#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; } } ASTStatement * Parser::statement(ASTNode * parent) { BasicStatement * stat = new BasicStatement(parent); if(accept("{")) { while(!accept("}")) { stat = static_cast(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")) { //stuff //TODO implement that return stat; } else if(accept("while")) { //similar stuff return stat; } 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) { ConstantExpression * ce; BasicExpression * be; //TODO add reference type to prims, syblol is now just a literal... and floats if(current_token.get_type() == t_integer) { report("Number: " + tok_value + "\n"); ce = new ConstantExpression(expression, std::atoi(tok_value.c_str())); read_next(); } else if(current_token.get_type() == t_literal) { report("Character literal: " + tok_value + "\n"); ce = new ConstantExpression(expression, tok_value); read_next(); } else if(current_token.get_type() == t_symbol) { report("variable: " + tok_value + "\n"); SenchaObject variable; //TODO is it right? string name = current_token.value; variable = context->get(name); variable.name = name; ce = new ConstantExpression(expression, variable, name); read_next(); } else if(accept("(")) { report("( "); 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); } return ce; } ASTExpression * Parser::postfix_expr(ASTNode * expression) { //TODO implement postfix expression ASAP BasicExpression * be = new BasicExpression(expression); prim_expr(be); if(accept("[")) { expr(be); expect("]"); report(" [] "); } else if(accept("(")) { if(!accept(")")) { expr(be); report("function argument\n"); while(accept(",")) { expr(be); report("function argument\n"); } expect(")"); } report("FUNC_CALL\n"); } //TODO implement postfix_expression return be; } ASTExpression * Parser::mul_expr(ASTNode * expression) { BasicExpression * be = new BasicExpression(expression); be->set_left_operand(prim_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); ASTExpression * left = eq_expr(assignment); if(accept("=")) { ASTExpression * right = expr(assignment); assignment->add_lvalue(left); assignment->add_rvalue(right); report(" :=\n"); return assignment; } else { left->parent = expression; delete assignment; return left; } }