/* PIA - Lenguajes Modernos de Programación * FACULTAD DE CIENCIAS FÍSICO MATEMÁTICAS * Luis Sebastián Martínez Vega - LCC */ #include #include #include "include/lexer.hpp" #include "include/exceptions.hpp" using std::string, std::isalpha, std::isdigit; Lexer::Lexer(string text): current_token(nil, {}){ setText(text); } void Lexer::setText(string text){ this->text = text; // Inicializamos el lexer. current_char = 0; current_token = nextToken(); var_name = '\0'; } Token Lexer::getCurrentToken(){ return current_token; } bool Lexer::matchFunction(const string &function_name){ string name = text.substr(current_char, 3); bool matched = name == function_name; // Si hubo una coincidencia movemos el puntero. if(matched) current_char += 3; return matched; } string Lexer::createNumber(){ string number; while(isdigit(text[current_char]) && current_char < text.length()) { number += text[current_char]; ++current_char; } return number; } Token Lexer::match(){ // Si ya consumimos todo el texto, // regresamos nil. if(current_char >= text.length()) return Token(nil, {}); // Probamos las funciones. if(isalpha(text[current_char]) && current_char + 2 <= text.length()) { if(matchFunction("sin")) return Token(function, "sin"); else if(matchFunction("cos")) return Token(function, "cos"); else if(matchFunction("tan")) return Token(function, "tan"); else if(matchFunction("csc")) return Token(function, "csc"); else if(matchFunction("sec")) return Token(function, "ctg"); } if(isdigit(text[current_char])) return Token(number, createNumber()); if(isalpha(text[current_char])) { /* Si es la primera vez que se lee un token variable o si la variable leída es igual a la anteriormente leída. */ if(var_name == '\0' || var_name == text[current_char]) { var_name = text[current_char]; ++current_char; return Token(variable, string(1, var_name)); } // Error, se introdujo una expresión con dos o más variables. throw LexerException("Encontrada más de una variable."); } /* El token actual no es ni una variable, número o función. Ahora a probar operadores. */ switch(text[current_char]) { case '+': ++current_char; return Token(sum, {}); case '-': ++current_char; return Token(substraction, {}); case '*': ++current_char; return Token(multiplication, {}); case '/': ++current_char; return Token(division, {}); case '^': ++current_char; return Token(power, {}); case '(': ++current_char; return Token(left_parens, {}); case ')': ++current_char; return Token(right_parens, {}); default: return Token(nil, {}); } } Token Lexer::nextToken(){ if(text[current_char] == ' ') ++current_char; current_token = match(); return current_token; }