sencha-lang/Sencha-lang/Parser.cpp

527 lines
11 KiB
C++

#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<ProgramNode *>(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<ProgramNode *>(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<Token> 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<BasicExpression *>(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)
{
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->get_operator() == "")
{
ASTExpression * ae;
ae = static_cast<ASTExpression *>(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->get_operator() == "")
{
ASTExpression * ae;
ae = static_cast<ASTExpression *>(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->get_operator() == "")
{
ASTExpression * ae;
ae = static_cast<ASTExpression *>(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->get_operator() == "")
{
ASTExpression * ae;
ae = static_cast<ASTExpression *>(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;
}
}