summaryrefslogtreecommitdiff
path: root/parser.cpp
diff options
context:
space:
mode:
authorHombreLaser <sebastian-440@live.com>2022-04-10 10:21:12 -0500
committerHombreLaser <sebastian-440@live.com>2022-04-10 10:21:12 -0500
commit531f8f2f1adc1c6777920f0a8c68caaee30b0fc4 (patch)
treec3d8ac22f3ecc118cd2b5056e7ac556371efaca7 /parser.cpp
parentae25e110ca9d65c4e2cfffef21abc16f26ac3739 (diff)
Corregidos errores de las expresiones.
Diffstat (limited to 'parser.cpp')
-rw-r--r--parser.cpp153
1 files changed, 116 insertions, 37 deletions
diff --git a/parser.cpp b/parser.cpp
index 11ff786..07ca601 100644
--- a/parser.cpp
+++ b/parser.cpp
@@ -1,94 +1,145 @@
#include <string>
#include "include/parser.hpp"
+#include "include/expressions.hpp"
#include "include/lexer.hpp"
#include "include/exceptions.hpp"
-using std::string;
+using std::string, std::stoi;
-void Parser::setText(string text){
- tokenizer.setText(text); // Se prepara el lexer.
+// De haber habido un error vaciaremos la pila de expresiones.
+void Parser::panic() {
+ for(auto ptr = tree_stack.begin(); ptr != tree_stack.end(); ++ptr)
+ delete *ptr;
+
+ throw ParserException("Sintaxis incorrecta.");
}
-bool Parser::checkToken(){
- if(tokenizer.getCurrentToken().type == nil)
- return false;
+Expression *Parser::popStack() {
+ Expression *val = tree_stack.back();
+ tree_stack.pop_back();
+
+ return val;
+}
- return true;
+Expression *Parser::newTree(token_type type) {
+ switch(type) {
+ case sum:
+ return new AddExpression(popStack(), popStack());
+ case substraction:
+ return new SubExpression(popStack(), popStack());
+ case multiplication:
+ return new MultiplicationExpression(popStack(), popStack());
+ case division:
+ return new DivisionExpression(popStack(), popStack());
+ default: // Potencia.
+ return new PowerExpression(popStack(), popStack());
+ }
}
-void Parser::parse(string expr){
+void Parser::setText(string text) {
+ tokenizer.setText(text); // Se prepara el lexer.
+ var.value = "{}";
+ var.type = nil;
+}
+
+bool Parser::checkToken() {
+ return tokenizer.getCurrentToken().type == nil;
+}
+
+Expression *Parser::parse(string expr) {
setText(expr);
parseExpr();
/* Si no se ha consumido toda la cadena, lanzamos
error. */
if(tokenizer.getCurrentToken().type != nil)
- throw ParserException("Sintaxis incorrecta.");
+ panic();
+
+ return popStack();
}
-void Parser::parseExpr(){
+void Parser::parseExpr() {
parseTerm();
parsePrimeExpr();
}
-void Parser::parsePrimeExpr(){
+void Parser::parsePrimeExpr() {
+ token_type current;
+
if(tokenizer.getCurrentToken().type == sum
- || tokenizer.getCurrentToken().type == substraction)
- {
+ || tokenizer.getCurrentToken().type == substraction) {
+ current = tokenizer.getCurrentToken().type;
+
+ try {
tokenizer.nextToken();
+ } catch(const LexerException &e) {
+ panic();
+ }
- if(!checkToken())
- throw ParserException("Sintaxis incorrecta.");
+ if(checkToken())
+ panic();
parseTerm();
+ tree_stack.push_back(newTree(current));
parsePrimeExpr();
}
}
-void Parser::parseTerm(){
+void Parser::parseTerm() {
parsePower();
parsePrimeTerm();
}
-void Parser::parsePrimeTerm(){
+void Parser::parsePrimeTerm() {
+ token_type current;
+
if(tokenizer.getCurrentToken().type == multiplication
- || tokenizer.getCurrentToken().type == division)
- {
+ || tokenizer.getCurrentToken().type == division) {
+ current = tokenizer.getCurrentToken().type;
+
tokenizer.nextToken();
- if(!checkToken())
- throw ParserException("Sintaxis incorrecta.");
+ if(checkToken())
+ panic();
parsePower();
+ tree_stack.push_back(newTree(current));
parsePrimeTerm();
}
}
-void Parser::parsePower(){
+void Parser::parsePower() {
parseFactor();
parsePrimePower();
}
-void Parser::parsePrimePower(){
- if(tokenizer.getCurrentToken().type == power)
- {
+void Parser::parsePrimePower() {
+ if(tokenizer.getCurrentToken().type == power) {
+
tokenizer.nextToken();
if(tokenizer.getCurrentToken().type != number)
- throw ParserException("Sintaxis incorrecta.");
+ panic();
+ tree_stack.push_back(new Literal(stoi(tokenizer.getCurrentToken().value)));
tokenizer.nextToken();
+ tree_stack.push_back(newTree(power));
parsePrimePower();
}
}
-void Parser::parseFactor(){
- switch(tokenizer.getCurrentToken().type)
- {
+void Parser::parseFactor() {
+ trig_functions name;
+
+ switch(tokenizer.getCurrentToken().type) {
case substraction:
+
tokenizer.nextToken();
+
parseExpr();
+ tree_stack.push_back(new NegationExpression(popStack()));
+
break;
case left_parens:
tokenizer.nextToken();
@@ -96,35 +147,63 @@ void Parser::parseFactor(){
// Consumimos paréntesis derecho.
if(tokenizer.getCurrentToken().type != right_parens)
- throw ParserException("Sintaxis incorrecta.");
+ panic();
tokenizer.nextToken();
break;
- case function:
+ case function:
+ if(tokenizer.getCurrentToken().value == "sin")
+ name = i_sin;
+ else if(tokenizer.getCurrentToken().value == "cos")
+ name = i_cos;
+ else if(tokenizer.getCurrentToken().value == "tan")
+ name = i_tan;
+ else if(tokenizer.getCurrentToken().value == "csc")
+ name = i_csc;
+ else if(tokenizer.getCurrentToken().value == "sec")
+ name = i_sec;
+ else
+ name = i_ctg;
+
tokenizer.nextToken();
if(tokenizer.getCurrentToken().type != left_parens)
- throw ParserException("Sintaxis incorrecta.");
+ panic();
- parseExpr();
+ tokenizer.nextToken();
+ parseExpr();
+
if(tokenizer.getCurrentToken().type != right_parens)
- throw ParserException("Sintaxis incorrecta.");
-
+ panic();
+
tokenizer.nextToken();
+
+ tree_stack.push_back(new Function(popStack(), name));
break;
case variable:
- tokenizer.nextToken();
+ /* Checamos si no se ha registrado ningún nombre de variable o si
+ la variable leída por el lexer es la misma que la que se había leído. */
+ if(tokenizer.getCurrentToken().value == var.value || var.type == nil)
+ var = tokenizer.getCurrentToken();
+ else
+ panic(); // Se introdujeron dos variables en la expresión.
+ tree_stack.push_back(new Variable(tokenizer.getCurrentToken().value[0]));
+
+ tokenizer.nextToken();
+
break;
case number:
+ tree_stack.push_back(new Literal(stoi(tokenizer.getCurrentToken().value)));
+
tokenizer.nextToken();
break;
default:
- throw ParserException("Sintaxis incorrecta.");
+ panic();
break;
}