#include "Parser.h" Parser::Parser(ContextManager * context) { this->context = context; error_message = "***ERRORS DURING PARSING***\n"; position_in_stream = 0; in_statement = false; program = static_cast(tree.root); } Parser::~Parser() { } void Parser::erase_all() { error_message = "***ERRORS DURING PARSING***\n"; position_in_stream = 0; in_statement = false; this->token_stream = vector(); delete program; program = new ProgramNode(); } string Parser::show_tokens() { string tokens = ""; for (unsigned int i = 0; i < token_stream.size(); i++) { tokens += token_stream[i].value + " "; } return tokens; } void Parser::add_tokens(vector tokens) { for (unsigned int i = 0; i < tokens.size(); i++) { token_stream.push_back(tokens[i]); } } void Parser::error(string s) { error_message += s ; } bool Parser::read_next() { if(position_in_stream < token_stream.size()) { current_token = token_stream[position_in_stream]; tok_value = current_token.get_value(); position_in_stream++; return true; } else { current_token = Token(t_invalid_token, ""); tok_value = current_token.get_value(); return false; } } void Parser::interpret() { read_next(); while(tok_value!= "") program->add_statement(statement()); } bool Parser::peek(string s) {return tok_value == s;} bool Parser::accept(string s) { if(peek(s)) { read_next(); return true; } else return false; } bool Parser::expect(string s) { if(!accept(s)) { string error_message = "Error: expected "; error_message += s; error_message += " but received: " + tok_value + "\n"; error(error_message); return false; } else return true; } bool Parser::is_type() { if(tok_value == "def" || tok_value == "string" || tok_value == "num") { read_next(); return true; } else return false; } bool Parser::is_function_name() { if(context->registered_functions.count(tok_value) == 1) { read_next(); return true; } else return false; } ASTStatement * Parser::statement() { if(accept("{")) { BasicStatement * stat = new BasicStatement(); while(!accept("}")) stat->children.push_back(statement()); return stat; } else if(is_type()) { DeclarationStatement * declaration = new DeclarationStatement(context); std::string identifier = tok_value; read_next(); declaration->add_name(identifier); if(accept("=")) { ASTExpression * ae = expr(); declaration->add_right_value(ae); accept(";"); } if(expect("(")) { int argc = 0; while(tok_value != ")") { argc++; is_type(); declaration->add_argument(tok_value); read_next(); if(peek(")")) break; expect(","); } expect(")"); if(!accept(";")) declaration->add_body(statement()); } return declaration; } else if(accept("if")) { IfNode * ifStatement = new IfNode(); ifStatement->add_condition(expr()); ifStatement->add_body(statement()); if(accept("else")) ifStatement->add_else_block(statement()); return ifStatement; } else if(accept("repeat")) { RepeatStatement * repeat = new RepeatStatement(); repeat->add_iteration_number(expr()->evaluate()); repeat->add_body(statement()); return repeat; } else if(accept("while")) { WhileNode * while_node = new WhileNode(expr(), statement()); return while_node; } else if(accept("return")) { BasicStatement * stat = new BasicStatement(); if(!peek(";")) stat->add_expression(expr()); expect(";"); return stat; } else { BasicStatement * stat = new BasicStatement(); stat->add_expression(expr()); while(!expect(";") && tok_value != "") read_next(); return stat; } } ASTExpression * Parser::prim_expr() { if(current_token.get_type() == t_integer) { ConstantExpression * ce = new ConstantExpression(std::atoi(tok_value.c_str())); read_next(); return ce; } else if(current_token.get_type() == t_float) { ConstantExpression * ce = new ConstantExpression(std::atof(tok_value.c_str())); read_next(); return ce; } else if(current_token.get_type() == t_literal) { ConstantExpression * ce = new ConstantExpression(tok_value); read_next(); return ce; } else if(current_token.get_type() == t_keyword) { ConstantExpression * ce; if(tok_value == "true") { ce = new ConstantExpression( SenchaObject(true)); read_next(); } else if (tok_value == "false") { ce = new ConstantExpression(SenchaObject(false)); read_next(); } return ce; } else if(current_token.get_type() == t_symbol) { string name = current_token.value; VariableExpression * ve = new VariableExpression(name, context); read_next(); return ve; } else if(accept("(")) { ASTExpression * expression = expr(); expect(")"); return expression; } else { string error_message = "ERROR: unexpected primary expression " + tok_value + "\n"; error(error_message); read_next(); return new IncorrectExpression(error_message); } } ASTExpression * Parser::postfix_expr() { string name = tok_value; if(is_function_name()) { PostfixExpression * function_call = new PostfixExpression(name, context); if(accept("(")) { if(!accept(")")) { function_call->add_argument(expr()); while(accept(",")) { function_call->add_argument(expr()); } expect(")"); } return function_call; } } return prim_expr(); } ASTExpression * Parser::mul_expr() { ASTExpression * left = postfix_expr(); if(peek("*") || peek("/")) { string oper = tok_value; read_next(); return new BasicExpression(left, mul_expr(), oper); } else return left; } ASTExpression * Parser::add_expr() { ASTExpression * left = mul_expr(); if(peek("+") || peek("-")) { string oper = tok_value; read_next(); return new BasicExpression(left, add_expr(), oper); } else return left; } ASTExpression * Parser::rel_expr() { ASTExpression * left = add_expr(); if(peek("<") || peek(">") || peek("<=") || peek(">=")) { string oper = tok_value; read_next(); return new BasicExpression(left, rel_expr(), oper); } else return left; } ASTExpression * Parser::eq_expr() { ASTExpression * left = rel_expr(); if(peek("==") || peek("!=")) { string oper = tok_value; read_next(); return new BasicExpression(left, eq_expr(), oper); } else return left; } ASTExpression * Parser::log_expr() { ASTExpression * left = eq_expr(); if(peek("and") || peek("or")) { string oper; if(accept("and")) oper = "&&"; else if(accept("or")) oper = "||"; ASTExpression * right = log_expr(); return new BasicExpression(left, right, oper); } else return left; } ASTExpression * Parser::expr() { string name = tok_value; ASTExpression * left = log_expr(); if(accept("=")) { ASTExpression * right = expr(); Assignment * assignment = new Assignment( context, name, left, right); return assignment; } else return left; }