summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHombreLaser <sebastian-440@live.com>2022-03-26 13:18:12 -0600
committerHombreLaser <sebastian-440@live.com>2022-03-26 13:18:12 -0600
commitee0252298ab03c1647b7dcac302ac9fd4e7e8379 (patch)
tree12046727c686850d6cb95f77cd12790a1342137f
parentc11d390f07a663a939dd37a764ac755c37e4def3 (diff)
Añadido código del lexer
-rw-r--r--include/exceptions.hpp23
-rw-r--r--include/lexer.hpp28
-rw-r--r--lexer.cpp104
3 files changed, 141 insertions, 14 deletions
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 <string>
+#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 <string>
+#include <cctype>
#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;
+}