#include "Parser.h" Parser::Parser(ContextManager * context) { this->context_manager = 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; } } ProgramNode * Parser::interpret() { read_next(); while(tok_value!= "") program->add_statement(statement()); return program; } bool Parser::peek(string s) {return tok_value == s;} bool Parser::peek_one_ahead(string s) { if(position_in_stream < token_stream.size() - 1) { if(s == token_stream[position_in_stream].value) return true; } return false; } 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; } 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_manager); 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("array")) { DeclarationStatement * declaration = new DeclarationStatement(context_manager); std::string identifier = tok_value; read_next(); declaration->add_name(identifier); expect("["); declaration->add_array_size(expr()); expect("]"); accept(";"); 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(expr(), statement()); return repeat; } else if(accept("import")) { auto name_expression = expr()->execute(); cout << name_expression.repr() << endl; if(name_expression.type == SenchaObject::string_literal) { std::string name_of_import = name_expression.text; ImportStatement * import = new ImportStatement(name_of_import, context_manager); accept(";"); return import; } else if (name_expression.name != "") { std::string name_of_import = name_expression.name; ImportStatement * import = new ImportStatement(name_of_import, context_manager); accept(";"); return import; } else { string error_message = "ERROR: invalid import\n"; error(error_message); BasicStatement * stat = new BasicStatement(); stat->add_expression(new IncorrectExpression(error_message)); accept(";"); return stat; } } 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_manager); 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(current_token.get_type() == t_symbol) { if(peek_one_ahead("(")) { read_next(); read_next(); PostfixExpression * function_call = new PostfixExpression(name, context_manager); if(!accept(")")) { function_call->add_argument(expr()); while(accept(",")) function_call->add_argument(expr()); expect(")"); } return function_call; } if(peek_one_ahead("[")) { read_next(); read_next(); PostfixExpression * access = new PostfixExpression(name, context_manager, expr()); accept("]"); return access; } } return prim_expr(); } ASTExpression * Parser::unary_expr() { if(peek("-") || peek("!")) { string oper = tok_value; read_next(); return new UnaryExpression(unary_expr(), oper); } else return postfix_expr(); } ASTExpression * Parser::mul_expr() { ASTExpression * left = unary_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(); std::string name_of_left_side = left->evaluate().name; if(name_of_left_side != "") name = name_of_left_side; Assignment * assignment = new Assignment( context_manager, name, left, right); return assignment; } else return left; }