2012-11-02 23:07:00 +00:00
|
|
|
#include "Parser.h"
|
|
|
|
#include "iostream"
|
|
|
|
|
2012-12-30 13:59:30 +00:00
|
|
|
Parser::Parser(ContextManager * context)
|
2012-12-08 19:59:05 +00:00
|
|
|
{
|
|
|
|
this->context = context;
|
2012-12-28 14:40:54 +00:00
|
|
|
error_message = "***ERRORS DURING PARSING***\n";
|
|
|
|
position_in_stream = 0;
|
|
|
|
in_statement = false;
|
|
|
|
program = static_cast<ProgramNode *>(tree.root);
|
2012-11-02 23:07:00 +00:00
|
|
|
}
|
|
|
|
|
2012-12-08 19:59:05 +00:00
|
|
|
|
2012-11-02 23:07:00 +00:00
|
|
|
Parser::~Parser()
|
|
|
|
{
|
2012-12-28 14:40:54 +00:00
|
|
|
|
2012-11-02 23:07:00 +00:00
|
|
|
}
|
2012-11-08 20:16:00 +00:00
|
|
|
|
2012-12-07 15:58:27 +00:00
|
|
|
void Parser::erase_all()
|
|
|
|
{
|
|
|
|
error_message = "***ERRORS DURING PARSING***\n";
|
|
|
|
position_in_stream = 0;
|
|
|
|
in_statement = false;
|
2012-12-22 18:19:13 +00:00
|
|
|
this->token_stream = vector<Token>();
|
|
|
|
delete program;
|
|
|
|
program = new ProgramNode();
|
2012-12-07 15:58:27 +00:00
|
|
|
}
|
2012-12-30 13:59:30 +00:00
|
|
|
|
2012-11-17 15:54:16 +00:00
|
|
|
string Parser::show_tokens()
|
|
|
|
{
|
|
|
|
string tokens = "";
|
2012-12-08 19:59:05 +00:00
|
|
|
for (unsigned int i = 0; i < token_stream.size(); i++)
|
2012-11-17 15:54:16 +00:00
|
|
|
{
|
|
|
|
tokens += token_stream[i].value + " ";
|
|
|
|
}
|
|
|
|
return tokens;
|
|
|
|
}
|
|
|
|
|
2012-11-08 20:16:00 +00:00
|
|
|
void Parser::add_tokens(vector<Token> tokens)
|
|
|
|
{
|
2012-12-08 19:59:05 +00:00
|
|
|
for (unsigned int i = 0; i < tokens.size(); i++)
|
2012-11-08 20:16:00 +00:00
|
|
|
{
|
|
|
|
token_stream.push_back(tokens[i]);
|
|
|
|
}
|
|
|
|
}
|
2012-11-02 23:07:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
void Parser::error(string s)
|
|
|
|
{
|
2012-12-28 14:40:54 +00:00
|
|
|
error_message += s ;
|
2012-11-02 23:07:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Parser::read_next()
|
|
|
|
{
|
2012-12-28 14:40:54 +00:00
|
|
|
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;
|
|
|
|
}
|
2012-11-02 23:07:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Parser::interpret()
|
2012-11-17 15:54:16 +00:00
|
|
|
{
|
|
|
|
read_next();
|
2012-12-28 16:39:43 +00:00
|
|
|
while(tok_value!= "") program->add_statement(statement());
|
2012-11-02 23:07:00 +00:00
|
|
|
}
|
|
|
|
|
2012-12-28 16:39:43 +00:00
|
|
|
bool Parser::peek(string s) {return tok_value == s;}
|
2012-11-02 23:07:00 +00:00
|
|
|
|
|
|
|
bool Parser::accept(string s)
|
|
|
|
{
|
2012-12-28 14:40:54 +00:00
|
|
|
if(peek(s))
|
|
|
|
{
|
|
|
|
read_next();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else return false;
|
2012-11-02 23:07:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Parser::expect(string s)
|
|
|
|
{
|
2012-12-28 14:40:54 +00:00
|
|
|
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;
|
2012-11-02 23:07:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Parser::is_type()
|
2012-12-28 14:40:54 +00:00
|
|
|
{
|
|
|
|
if(tok_value == "def" || tok_value == "string" || tok_value == "num")
|
|
|
|
{
|
|
|
|
read_next();
|
|
|
|
return true;
|
|
|
|
}
|
2012-12-28 16:39:43 +00:00
|
|
|
else return false;
|
2012-11-02 23:07:00 +00:00
|
|
|
}
|
2012-12-09 16:42:13 +00:00
|
|
|
|
|
|
|
bool Parser::is_function_name()
|
|
|
|
{
|
2012-12-10 10:45:09 +00:00
|
|
|
if(context->registered_functions.count(tok_value) == 1)
|
2012-12-09 16:42:13 +00:00
|
|
|
{
|
|
|
|
read_next();
|
|
|
|
return true;
|
|
|
|
}
|
2012-12-28 16:39:43 +00:00
|
|
|
else return false;
|
2012-12-09 16:42:13 +00:00
|
|
|
}
|
2012-11-02 23:07:00 +00:00
|
|
|
|
2012-12-28 10:01:48 +00:00
|
|
|
ASTStatement * Parser::statement()
|
2012-12-28 16:39:43 +00:00
|
|
|
{
|
2012-12-28 14:40:54 +00:00
|
|
|
if(accept("{"))
|
2012-12-28 16:39:43 +00:00
|
|
|
{
|
|
|
|
BasicStatement * stat = new BasicStatement();
|
|
|
|
while(!accept("}")) stat->children.push_back(statement());
|
|
|
|
return stat;
|
2012-12-28 14:40:54 +00:00
|
|
|
}
|
|
|
|
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();
|
2012-12-28 16:39:43 +00:00
|
|
|
if(peek(")")) break;
|
2012-12-28 14:40:54 +00:00
|
|
|
expect(",");
|
|
|
|
}
|
|
|
|
expect(")");
|
2012-12-28 16:39:43 +00:00
|
|
|
if(!accept(";")) declaration->add_body(statement());
|
2012-12-28 14:40:54 +00:00
|
|
|
}
|
|
|
|
return declaration;
|
|
|
|
}
|
|
|
|
else if(accept("if"))
|
|
|
|
{
|
|
|
|
IfNode * ifStatement = new IfNode();
|
|
|
|
ifStatement->add_condition(expr());
|
|
|
|
ifStatement->add_body(statement());
|
2012-12-28 16:39:43 +00:00
|
|
|
if(accept("else")) ifStatement->add_else_block(statement());
|
2012-12-28 14:40:54 +00:00
|
|
|
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"))
|
|
|
|
{
|
2012-12-28 16:39:43 +00:00
|
|
|
WhileNode * while_node = new WhileNode(expr(), statement());
|
2012-12-28 14:40:54 +00:00
|
|
|
return while_node;
|
|
|
|
}
|
|
|
|
else if(accept("return"))
|
2012-12-28 16:39:43 +00:00
|
|
|
{
|
|
|
|
BasicStatement * stat = new BasicStatement();
|
|
|
|
if(!peek(";")) stat->add_expression(expr());
|
2012-12-28 14:40:54 +00:00
|
|
|
expect(";");
|
|
|
|
return stat;
|
|
|
|
}
|
|
|
|
else
|
2012-12-28 16:39:43 +00:00
|
|
|
{
|
|
|
|
BasicStatement * stat = new BasicStatement();
|
2012-12-28 14:40:54 +00:00
|
|
|
stat->add_expression(expr());
|
|
|
|
while(!expect(";") && tok_value != "") read_next();
|
|
|
|
return stat;
|
2012-12-28 16:39:43 +00:00
|
|
|
}
|
2012-11-02 23:07:00 +00:00
|
|
|
}
|
|
|
|
|
2012-12-28 10:01:48 +00:00
|
|
|
ASTExpression * Parser::prim_expr()
|
2012-12-28 14:40:54 +00:00
|
|
|
{
|
2012-12-09 10:29:08 +00:00
|
|
|
if(current_token.get_type() == t_integer)
|
2012-12-22 10:18:47 +00:00
|
|
|
{
|
2012-12-28 15:19:47 +00:00
|
|
|
ConstantExpression * ce = new ConstantExpression(std::atoi(tok_value.c_str()));
|
2012-12-17 09:41:48 +00:00
|
|
|
read_next();
|
|
|
|
return ce;
|
2012-12-16 08:24:16 +00:00
|
|
|
}
|
|
|
|
else if(current_token.get_type() == t_float)
|
|
|
|
{
|
2012-12-28 15:19:47 +00:00
|
|
|
ConstantExpression * ce = new ConstantExpression(std::atof(tok_value.c_str()));
|
2012-12-16 08:24:16 +00:00
|
|
|
read_next();
|
2012-12-17 09:41:48 +00:00
|
|
|
return ce;
|
2012-12-09 10:29:08 +00:00
|
|
|
}
|
|
|
|
else if(current_token.get_type() == t_literal)
|
2012-12-22 10:18:47 +00:00
|
|
|
{
|
2012-12-28 15:19:47 +00:00
|
|
|
ConstantExpression * ce = new ConstantExpression(tok_value);
|
2012-12-17 09:41:48 +00:00
|
|
|
read_next();
|
|
|
|
return ce;
|
2012-12-09 10:29:08 +00:00
|
|
|
}
|
2012-12-09 16:42:13 +00:00
|
|
|
else if(current_token.get_type() == t_keyword)
|
|
|
|
{
|
2012-12-17 09:41:48 +00:00
|
|
|
ConstantExpression * ce;
|
2012-12-09 16:42:13 +00:00
|
|
|
if(tok_value == "true")
|
|
|
|
{
|
2012-12-28 10:01:48 +00:00
|
|
|
ce = new ConstantExpression( SenchaObject(true));
|
2012-12-09 16:42:13 +00:00
|
|
|
read_next();
|
|
|
|
}
|
|
|
|
else if (tok_value == "false")
|
|
|
|
{
|
2012-12-28 10:01:48 +00:00
|
|
|
ce = new ConstantExpression(SenchaObject(false));
|
2012-12-09 16:42:13 +00:00
|
|
|
read_next();
|
|
|
|
}
|
2012-12-17 09:41:48 +00:00
|
|
|
return ce;
|
2012-12-09 16:42:13 +00:00
|
|
|
}
|
2012-12-09 10:29:08 +00:00
|
|
|
else if(current_token.get_type() == t_symbol)
|
|
|
|
{
|
|
|
|
string name = current_token.value;
|
2012-12-28 16:39:43 +00:00
|
|
|
VariableExpression * ve = new VariableExpression(name, context);
|
2012-12-09 10:29:08 +00:00
|
|
|
read_next();
|
2012-12-17 09:41:48 +00:00
|
|
|
return ve;
|
2012-12-09 10:29:08 +00:00
|
|
|
}
|
|
|
|
else if(accept("("))
|
|
|
|
{
|
2012-12-28 16:39:43 +00:00
|
|
|
ASTExpression * expression = expr();
|
2012-12-09 10:29:08 +00:00
|
|
|
expect(")");
|
2012-12-28 16:39:43 +00:00
|
|
|
return expression;
|
2012-12-09 10:29:08 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
string error_message = "ERROR: unexpected primary expression " + tok_value + "\n";
|
|
|
|
error(error_message);
|
|
|
|
read_next();
|
2012-12-28 10:01:48 +00:00
|
|
|
return new IncorrectExpression(error_message);
|
2012-12-28 14:40:54 +00:00
|
|
|
}
|
2012-11-02 23:07:00 +00:00
|
|
|
}
|
|
|
|
|
2012-12-28 10:01:48 +00:00
|
|
|
ASTExpression * Parser::postfix_expr()
|
2012-12-06 17:41:16 +00:00
|
|
|
{
|
2012-12-28 15:19:47 +00:00
|
|
|
string name = tok_value;
|
2012-12-09 16:42:13 +00:00
|
|
|
if(is_function_name())
|
|
|
|
{
|
2012-12-28 15:19:47 +00:00
|
|
|
PostfixExpression * function_call = new PostfixExpression(name, context);
|
2012-12-09 16:42:13 +00:00
|
|
|
if(accept("("))
|
2012-12-28 14:40:54 +00:00
|
|
|
{
|
|
|
|
if(!accept(")"))
|
|
|
|
{
|
|
|
|
function_call->add_argument(expr());
|
|
|
|
while(accept(","))
|
|
|
|
{
|
|
|
|
function_call->add_argument(expr());
|
|
|
|
|
|
|
|
}
|
|
|
|
expect(")");
|
|
|
|
}
|
|
|
|
return function_call;
|
|
|
|
}
|
2012-12-09 16:42:13 +00:00
|
|
|
}
|
2012-12-28 14:40:54 +00:00
|
|
|
return prim_expr();
|
2012-11-04 16:16:02 +00:00
|
|
|
}
|
|
|
|
|
2012-12-28 10:01:48 +00:00
|
|
|
ASTExpression * Parser::mul_expr()
|
2012-11-04 16:16:02 +00:00
|
|
|
{
|
2012-12-28 15:19:47 +00:00
|
|
|
ASTExpression * left = postfix_expr();
|
2012-12-28 14:40:54 +00:00
|
|
|
if(peek("*") || peek("/"))
|
|
|
|
{
|
2012-12-28 15:19:47 +00:00
|
|
|
string oper = tok_value;
|
|
|
|
read_next();
|
|
|
|
return new BasicExpression(left, mul_expr(), oper);
|
2012-12-28 14:40:54 +00:00
|
|
|
}
|
2012-12-28 15:19:47 +00:00
|
|
|
else return left;
|
2012-11-04 16:16:02 +00:00
|
|
|
}
|
2012-11-02 23:07:00 +00:00
|
|
|
|
2012-12-28 10:01:48 +00:00
|
|
|
ASTExpression * Parser::add_expr()
|
2012-12-06 17:41:16 +00:00
|
|
|
{
|
2012-12-28 15:19:47 +00:00
|
|
|
ASTExpression * left = mul_expr();
|
2012-12-28 14:40:54 +00:00
|
|
|
if(peek("+") || peek("-"))
|
|
|
|
{
|
2012-12-28 15:19:47 +00:00
|
|
|
string oper = tok_value;
|
|
|
|
read_next();
|
|
|
|
return new BasicExpression(left, add_expr(), oper);
|
2012-12-28 14:40:54 +00:00
|
|
|
}
|
2012-12-28 15:19:47 +00:00
|
|
|
else return left;
|
2012-11-02 23:07:00 +00:00
|
|
|
}
|
|
|
|
|
2012-12-28 10:01:48 +00:00
|
|
|
ASTExpression * Parser::rel_expr()
|
2012-12-06 17:41:16 +00:00
|
|
|
{
|
2012-12-28 15:19:47 +00:00
|
|
|
ASTExpression * left = add_expr();
|
|
|
|
if(peek("<") || peek(">") || peek("<=") || peek(">="))
|
2012-12-28 14:40:54 +00:00
|
|
|
{
|
2012-12-28 15:19:47 +00:00
|
|
|
string oper = tok_value;
|
|
|
|
read_next();
|
|
|
|
return new BasicExpression(left, rel_expr(), oper);
|
2012-12-28 14:40:54 +00:00
|
|
|
}
|
2012-12-28 15:19:47 +00:00
|
|
|
else return left;
|
2012-11-02 23:07:00 +00:00
|
|
|
}
|
|
|
|
|
2012-12-28 10:01:48 +00:00
|
|
|
ASTExpression * Parser::eq_expr()
|
2012-12-06 17:41:16 +00:00
|
|
|
{
|
2012-12-28 15:19:47 +00:00
|
|
|
ASTExpression * left = rel_expr();
|
2012-12-28 14:40:54 +00:00
|
|
|
if(peek("==") || peek("!="))
|
|
|
|
{
|
2012-12-28 16:39:43 +00:00
|
|
|
string oper = tok_value;
|
|
|
|
read_next();
|
2012-12-28 15:19:47 +00:00
|
|
|
return new BasicExpression(left, eq_expr(), oper);
|
2012-12-28 14:40:54 +00:00
|
|
|
}
|
2012-12-28 15:19:47 +00:00
|
|
|
else return left;
|
2012-12-22 16:56:32 +00:00
|
|
|
}
|
|
|
|
|
2012-12-28 10:01:48 +00:00
|
|
|
ASTExpression * Parser::log_expr()
|
2012-12-22 16:56:32 +00:00
|
|
|
{
|
2012-12-28 15:19:47 +00:00
|
|
|
ASTExpression * left = eq_expr();
|
2012-12-28 14:40:54 +00:00
|
|
|
if(peek("and") || peek("or"))
|
|
|
|
{
|
2012-12-28 15:19:47 +00:00
|
|
|
string oper;
|
|
|
|
if(accept("and")) oper = "&&";
|
2012-12-28 16:39:43 +00:00
|
|
|
else if(accept("or")) oper = "||";
|
2012-12-28 15:19:47 +00:00
|
|
|
ASTExpression * right = log_expr();
|
|
|
|
return new BasicExpression(left, right, oper);
|
2012-12-28 14:40:54 +00:00
|
|
|
}
|
2012-12-28 15:19:47 +00:00
|
|
|
else return left;
|
2012-11-02 23:07:00 +00:00
|
|
|
}
|
|
|
|
|
2012-12-28 10:01:48 +00:00
|
|
|
ASTExpression * Parser::expr()
|
2012-12-05 20:31:06 +00:00
|
|
|
{
|
2012-12-28 15:19:47 +00:00
|
|
|
string name = tok_value;
|
2012-12-28 14:40:54 +00:00
|
|
|
ASTExpression * left = log_expr();
|
|
|
|
if(accept("="))
|
|
|
|
{
|
|
|
|
ASTExpression * right = expr();
|
2012-12-28 15:19:47 +00:00
|
|
|
Assignment * assignment = new Assignment( context, name, left, right);
|
2012-12-28 14:40:54 +00:00
|
|
|
return assignment;
|
|
|
|
}
|
2012-12-28 15:19:47 +00:00
|
|
|
else return left;
|
2012-11-02 23:07:00 +00:00
|
|
|
}
|