From 531f8f2f1adc1c6777920f0a8c68caaee30b0fc4 Mon Sep 17 00:00:00 2001 From: HombreLaser Date: Sun, 10 Apr 2022 10:21:12 -0500 Subject: Corregidos errores de las expresiones. --- parser.cpp | 153 ++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 116 insertions(+), 37 deletions(-) (limited to 'parser.cpp') diff --git a/parser.cpp b/parser.cpp index 11ff786..07ca601 100644 --- a/parser.cpp +++ b/parser.cpp @@ -1,94 +1,145 @@ #include #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; } -- cgit v1.2.3