From ee0252298ab03c1647b7dcac302ac9fd4e7e8379 Mon Sep 17 00:00:00 2001 From: HombreLaser Date: Sat, 26 Mar 2022 13:18:12 -0600 Subject: Añadido código del lexer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/exceptions.hpp | 23 +++++++++++ include/lexer.hpp | 28 ++++++++----- lexer.cpp | 104 ++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 141 insertions(+), 14 deletions(-) create mode 100644 include/exceptions.hpp diff --git a/include/exceptions.hpp b/include/exceptions.hpp new file mode 100644 index 0000000..0469784 --- /dev/null +++ b/include/exceptions.hpp @@ -0,0 +1,23 @@ +#include +#ifndef EXCEPTIONS_H +#define EXCEPTIONS_H + +class Exception{ +private: + std::string error_msg; +public: + Exception(const std::string &error_msg); + std::string showMsg(); +}; + +class LexerException: public Exception{ +public: + LexerException(const std::string &error_msg): Exception(error_msg){} +}; + +class ParserException: public Exception{ +public: + ParserException(const std::string &error_msg): Exception(error_msg){} +}; + +#endif /* EXCEPTIONS_H */ diff --git a/include/lexer.hpp b/include/lexer.hpp index 8d0d826..e674999 100644 --- a/include/lexer.hpp +++ b/include/lexer.hpp @@ -7,7 +7,14 @@ #ifndef LEXER_H #define LEXER_H -const std::string EMPTY_STRING = ""; +enum function_name{ + sin, + cos, + tan, + csc, + sec, + ctg +}; enum token_type{ sum, @@ -17,29 +24,32 @@ enum token_type{ power, variable, number, - sin, - cos, - tan, function, left_parens, - right_parens + right_parens, + nil }; struct Token{ token_type type; std::string value; + Token(token_type type, std::string value) : type(type), value(value){} }; class Lexer{ private: + char var_name; std::string text; - size_t txt_ptr; + size_t current_char; Token current_token; - void setCurrentToken(Token val); + bool matchFunction(std::string function_name); + std::string createNumber(); public: - Lexer(std::string text); - void nextToken(); + Lexer(std::string text = {}); + void setText(std::string text); Token getCurrentToken(); + Token match(); + Token nextToken(); }; #endif /* LEXER_H */ diff --git a/lexer.cpp b/lexer.cpp index c58ebb5..9cfb2f7 100644 --- a/lexer.cpp +++ b/lexer.cpp @@ -3,18 +3,112 @@ * Luis Sebastián Martínez Vega - LCC */ #include +#include #include "include/lexer.hpp" +#include "include/exceptions.hpp" -Lexer::Lexer(std::string text){ - this->text = text; +using std::string, std::isalpha, std::isdigit; + +Lexer::Lexer(string text): current_token(nil, {}){ + setText(text); } -void Lexer::setCurrentToken(Token val){ - current_token = val; +void Lexer::setText(string text){ + this->text = text; + // Inicializamos el lexer. + current_token = nextToken(); + var_name = '\0'; } Token Lexer::getCurrentToken(){ return current_token; } -void Lexer::nextToken(){} +bool Lexer::matchFunction(string function_name){ + string name = text.substr(current_char, 2); + 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(){ + // Probamos las funciones. + if(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]) + 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: + throw LexerException("Carácter inválido."); + } +} + +Token Lexer::nextToken(){ + current_token = match(); + + return current_token; +} -- cgit v1.2.3