#include "Parser.h" #include "iostream" Parser::Parser(Context * context) { this->context = context; error_message = "***ERRORS DURING PARSING***\n"; report_message = "***PARSER REPORT***\n"; position_in_stream = 0; in_statement = false; program = static_cast(tree.root); } Parser::~Parser() { //dtor } void Parser::erase_all() { tree.delete_all_children(); tree.root = new ProgramNode(); error_message = "***ERRORS DURING PARSING***\n"; report_message = "***PARSER REPORT***\n"; position_in_stream = 0; in_statement = false; program = static_cast(tree.root); } 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::report(string s) { report_message += s ; } 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(program)); } } 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() { //check in registered functions //cout << tok_value << " is it registered?" << endl; if(context->registered_functions.count(tok_value) == 1) { //cout << "Yes" << endl; read_next(); return true; } else { //cout << "No" << endl; return false; } } ASTStatement * Parser::statement(ASTNode * parent) { BasicStatement * stat = new BasicStatement(parent); if(accept("{")) { while(!accept("}")) { stat->children.push_back( statement(parent)); } } else if(is_type()) { DeclarationStatement * declaration = new DeclarationStatement(parent, context); std::string identifier = tok_value; report("Identifier: " + identifier + "\n"); read_next(); declaration->add_name(identifier); if(accept("=")) { ASTExpression * ae = expr(stat); declaration->add_right_value(ae); report(" := \n"); accept(";"); } if(accept(";")) { report("Variable declaration\n"); } if(expect("(")) { int argc = 0; while(tok_value != ")") { argc++; is_type(); report("function argument: " + tok_value + "\n"); declaration->add_argument(tok_value); read_next(); if(peek(")")) { break; } expect(","); } expect(")"); if(!accept(";")) { report("function body:\n"); declaration->add_body(statement(stat)); report("function definition\n"); } } delete stat; return declaration; } else if(accept("if")) { IfNode * ifStatement = new IfNode(parent); ifStatement->add_condition(expr(ifStatement)); ifStatement->add_body(statement(parent)); if(accept("else")) { ifStatement->add_else_block(statement(parent)); } delete stat; return ifStatement; } else if(accept("repeat")) { RepeatStatement * repeat = new RepeatStatement(parent); repeat->add_iteration_number(expr(repeat)->evaluate()); repeat->add_body(statement(repeat)); //similar stuff delete stat; return repeat; } else if(accept("while")) { WhileNode * while_node = new WhileNode(parent); while_node->add_condition(expr(while_node)); while_node->add_body(statement(while_node)); delete stat; return while_node; } else if(accept("return")) { if(!peek(";")) { stat->add_expression(expr(stat)); } expect(";"); report("RETURN\n"); return stat; } else { stat->add_expression(expr(stat)); while(!expect(";") && tok_value != "") read_next(); return stat; } return stat; } ASTExpression * Parser::prim_expr(ASTNode * expression) { if(current_token.get_type() == t_integer) { report("Number: " + tok_value + "\n"); ConstantExpression * ce; ce = new ConstantExpression(expression, std::atoi(tok_value.c_str())); read_next(); return ce; } else if(current_token.get_type() == t_float) { report("Number: " + tok_value + "\n"); ConstantExpression * ce; ce = new ConstantExpression(expression, std::atof(tok_value.c_str())); read_next(); return ce; } else if(current_token.get_type() == t_literal) { report("Character literal: " + tok_value + "\n"); ConstantExpression * ce; ce = new ConstantExpression(expression, tok_value); read_next(); return ce; } else if(current_token.get_type() == t_keyword) { ConstantExpression * ce; if(tok_value == "true") { report("Boolean: " + tok_value + "\n"); ce = new ConstantExpression(expression, SenchaObject(true)); read_next(); } else if (tok_value == "false") { report("Boolean: " + tok_value + "\n"); ce = new ConstantExpression(expression, SenchaObject(false)); read_next(); } return ce; } else if(current_token.get_type() == t_symbol) { report("variable: " + tok_value + "\n"); string name = current_token.value; VariableExpression * ve; ve = new VariableExpression(expression, context, name); read_next(); return ve; } else if(accept("(")) { report("( "); BasicExpression * be; be = static_cast(expr(expression)); report(" ) "); expect(")"); return be; } else { string error_message = "ERROR: unexpected primary expression " + tok_value + "\n"; error(error_message); read_next(); return new IncorrectExpression(expression, error_message); } } ASTExpression * Parser::postfix_expr(ASTNode * expression) { //TODO implement postfix expression ASAP auto name = tok_value; if(is_function_name()) { PostfixExpression * function_call = new PostfixExpression(expression, context); function_call->set_name(name); if(accept("(")) { if(!accept(")")) { function_call->add_argument(expr(function_call)); report("function argument\n"); while(accept(",")) { function_call->add_argument(expr(function_call)); report("function argument\n"); } expect(")"); } report("FUNC_CALL\n"); return function_call; } } return prim_expr(expression); } ASTExpression * Parser::mul_expr(ASTNode * expression) { BasicExpression * be = new BasicExpression(expression); be->set_left_operand(postfix_expr(be)); if(peek("*") || peek("/")) { if(accept("*")) { be->set_operator("*"); report(" *\n"); } else if(accept("/")) { be->set_operator("/"); report(" /\n"); } be->set_right_operand(mul_expr(be)); } if(be->oper == "") { ASTExpression * ae; ae = static_cast(be->children[0]); ae->parent = expression; delete be; return ae; } return be; } ASTExpression * Parser::add_expr(ASTNode * expression) { BasicExpression * be = new BasicExpression(expression); be->set_left_operand(mul_expr(be)); if(peek("+") || peek("-")) { if(accept("+")) { report(" +\n"); be->set_operator("+"); } else if(accept("-")) { report(" -\n"); be->set_operator("-"); } be->set_right_operand(add_expr(be)); } if(be->oper == "") { ASTExpression * ae; ae = static_cast(be->children[0]); ae->parent = expression; delete be; return ae; } return be; } ASTExpression * Parser::rel_expr(ASTNode * expression) { BasicExpression * be = new BasicExpression(expression); be->set_left_operand(add_expr(be)); if(peek("<") || peek(">")) { if(accept("<")) { be->set_operator("<"); report(" <\n"); } else if (accept(">")) { be->set_operator(">"); report(" >\n"); } be->set_right_operand(rel_expr(be)); } if(be->oper == "") { ASTExpression * ae; ae = static_cast(be->children[0]); ae->parent = expression; delete be; return ae; } return be; } ASTExpression * Parser::eq_expr(ASTNode * expression) { BasicExpression * be = new BasicExpression(expression); be->set_left_operand(rel_expr(be)); if(peek("==") || peek("!=")) { if(accept("==")) { be->set_operator("=="); report("==\n"); } else if(accept("!=")) { be->set_operator("!="); report("!=\n"); } be->set_right_operand(eq_expr(be)); } if(be->oper == "") { ASTExpression * ae; ae = static_cast(be->children[0]); ae->parent = expression; delete be; return ae; } return be; } ASTExpression * Parser::expr(ASTNode * expression) { Assignment * assignment = new Assignment(expression, context); auto name = tok_value; ASTExpression * left = eq_expr(assignment); if(accept("=")) { ASTExpression * right = expr(assignment); assignment->add_lvalue(left); assignment->add_rvalue(right); assignment->set_name(name); report(" :=\n"); return assignment; } else { left->parent = expression; delete assignment; return left; } }