345 lines
5.8 KiB
C++
345 lines
5.8 KiB
C++
#include "Parser.h"
|
|
#include "iostream"
|
|
|
|
Parser::Parser()
|
|
{
|
|
error_message = "***ERRORS DURING PARSING***\n";
|
|
report_message = "***PARSER REPORT***\n";
|
|
position_in_stream = 0;
|
|
in_statement = false;
|
|
}
|
|
|
|
Parser::~Parser()
|
|
{
|
|
//dtor
|
|
}
|
|
|
|
string Parser::show_tokens()
|
|
{
|
|
string tokens = "";
|
|
for (int i = 0; i < token_stream.size(); i++)
|
|
{
|
|
tokens += token_stream[i].value + " ";
|
|
}
|
|
return tokens;
|
|
}
|
|
|
|
void Parser::add_tokens(vector<Token> tokens)
|
|
{
|
|
for (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!= "")
|
|
{
|
|
statement();
|
|
}
|
|
|
|
|
|
}
|
|
|
|
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(current_token.get_type() == t_symbol || current_token.get_type() == t_keyword)
|
|
{
|
|
if(tok_value == "def" || tok_value == "string" || tok_value == "num")
|
|
{
|
|
read_next();
|
|
return true;
|
|
}
|
|
else return false;
|
|
|
|
}
|
|
else return false;
|
|
}
|
|
|
|
ASTNode * Parser::statement(ASTNode * statement)
|
|
{
|
|
if(accept("{"))
|
|
{
|
|
while(!accept("}"))
|
|
{
|
|
statement();
|
|
}
|
|
}
|
|
|
|
|
|
else if(is_type())
|
|
{
|
|
|
|
report("Identifier: " + tok_value + "\n");
|
|
|
|
read_next();
|
|
|
|
if(accept("="))
|
|
{
|
|
report("Identifier: " + tok_value + "\n");
|
|
read_next();
|
|
expr();
|
|
report(" := \n");
|
|
}
|
|
|
|
|
|
if(accept(";"))
|
|
{
|
|
report("Variable definition\n");
|
|
return;
|
|
}
|
|
|
|
if(expect("("))
|
|
{
|
|
int argc = 0;
|
|
while(tok_value != ")")
|
|
{
|
|
argc++;
|
|
is_type();
|
|
report("function argument: " + tok_value + "\n");
|
|
read_next();
|
|
if(peek(")"))
|
|
{
|
|
break;
|
|
}
|
|
expect(",");
|
|
}
|
|
expect(")");
|
|
|
|
if(!accept(";"))
|
|
{
|
|
report("function body:\n");
|
|
statement();
|
|
report("function definition\n");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
expect(";");
|
|
report("function declaration\n");
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
else if(accept("if"))
|
|
{
|
|
//stuff
|
|
//TODO implement that
|
|
}
|
|
else if(accept("while"))
|
|
{
|
|
//similar stuff
|
|
}
|
|
else if(accept("return"))
|
|
{
|
|
|
|
if(!peek(";"))
|
|
{
|
|
expr();
|
|
}
|
|
expect(";");
|
|
report("RETURN\n");
|
|
|
|
}
|
|
else
|
|
{
|
|
expr();
|
|
while(!expect(";") && tok_value != "") read_next();
|
|
|
|
}
|
|
}
|
|
|
|
ASTNode * Parser::prim_expr(ASTNode * expression)
|
|
{
|
|
if(current_token.get_type() == t_integer)
|
|
{
|
|
report("Number: " + tok_value + "\n");
|
|
read_next();
|
|
}
|
|
else if(current_token.get_type() == t_symbol)
|
|
{
|
|
report("Variable: " + tok_value + "\n");
|
|
read_next();
|
|
}
|
|
else if(current_token.get_type() == t_literal)
|
|
{
|
|
report("Character literal: " + tok_value + "\n");
|
|
read_next();
|
|
}
|
|
else if(accept("("))
|
|
{
|
|
report("( ");
|
|
expr();
|
|
report(" ) ");
|
|
expect(")");
|
|
|
|
}
|
|
else
|
|
{
|
|
error("ERROR: unexpected primary expression " + tok_value + "\n");
|
|
read_next();
|
|
}
|
|
|
|
}
|
|
|
|
ASTNode * Parser::postfix_expr(ASTNode * expression)
|
|
{
|
|
prim_expr();
|
|
if(accept("["))
|
|
{
|
|
expr();
|
|
expect("]");
|
|
report(" [] ");
|
|
|
|
}
|
|
else if(accept("("))
|
|
{
|
|
if(!accept(")"))
|
|
{
|
|
expr();
|
|
report("function argument\n");
|
|
while(accept(","))
|
|
{
|
|
expr();
|
|
report("function argument\n");
|
|
}
|
|
|
|
expect(")");
|
|
}
|
|
report("FUNC_CALL\n");
|
|
}
|
|
}
|
|
|
|
ASTNode * Parser::mul_expr(ASTNode * expression)
|
|
{
|
|
postfix_expr();
|
|
while(peek("*") || peek("/"))
|
|
{
|
|
if(accept("*"))
|
|
{
|
|
postfix_expr();
|
|
report(" *\n");
|
|
} else if(accept("/"))
|
|
{
|
|
postfix_expr();
|
|
report(" /\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
ASTNode * Parser::add_expr(ASTNode * expression)
|
|
{
|
|
mul_expr();
|
|
while(peek("+") || peek("-"))
|
|
{
|
|
if(accept("+"))
|
|
{
|
|
mul_expr();
|
|
report(" +\n");
|
|
} else if(accept("-"))
|
|
{
|
|
mul_expr();
|
|
report(" -\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
ASTNode * Parser::rel_expr(ASTNode * expression)
|
|
{
|
|
add_expr();
|
|
while(peek("<"))
|
|
{
|
|
accept("<");
|
|
add_expr();
|
|
report(" <\n");
|
|
}
|
|
}
|
|
|
|
ASTNode * Parser::eq_expr(ASTNode * expression)
|
|
{
|
|
rel_expr();
|
|
while(peek("==") || peek("!="))
|
|
{
|
|
if(accept("=="))
|
|
{
|
|
rel_expr();
|
|
report("==\n");
|
|
}
|
|
else if(accept("!="))
|
|
{
|
|
rel_expr();
|
|
report("!=\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
ASTNode * Parser::expr(ASTNode * expression)
|
|
{
|
|
eq_expr(expression);
|
|
if(accept("="))
|
|
{
|
|
expr();
|
|
report(" :=\n");
|
|
}
|
|
}
|