296 lines
5.1 KiB
C++
296 lines
5.1 KiB
C++
#include "Parser.h"
|
|
#include "iostream"
|
|
|
|
Parser::Parser(vector<Token> tokens)
|
|
{
|
|
error_message = "***ERRORS DURING PARSING***\n";
|
|
report_message = "***PARSER REPORT***\n";
|
|
token_stream = tokens;
|
|
position_in_stream = 0;
|
|
read_next();
|
|
}
|
|
|
|
Parser::~Parser()
|
|
{
|
|
//dtor
|
|
}
|
|
|
|
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()
|
|
{
|
|
while(tok_value!= "")
|
|
{
|
|
if(is_type())
|
|
{
|
|
report("Identifier: " + tok_value + "\n");
|
|
read_next();
|
|
|
|
if(accept("="))
|
|
{
|
|
expr();
|
|
report(" :=\n");
|
|
}
|
|
if(accept(";"))
|
|
{
|
|
report("Variable definition\n");
|
|
continue;
|
|
}
|
|
|
|
expect("(");
|
|
int argc = 0;
|
|
while(true)
|
|
{
|
|
argc++;
|
|
is_type();
|
|
report("function argument: " + tok_value + "\n");
|
|
read_next();
|
|
if(peek(")"))
|
|
{
|
|
break;
|
|
}
|
|
expect(",");
|
|
}
|
|
expect(")");
|
|
|
|
if(!accept(";"))
|
|
{
|
|
report("function body:\n");
|
|
statement();
|
|
}
|
|
}
|
|
|
|
else {
|
|
report("Regular statement:\n");
|
|
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;
|
|
}
|
|
|
|
void Parser::statement()
|
|
{
|
|
if(accept("{"))
|
|
{
|
|
while(!accept("}"))
|
|
{
|
|
statement();
|
|
}
|
|
}
|
|
else if(is_type())
|
|
{
|
|
report("Local variable: " + tok_value + "\n");
|
|
read_next();
|
|
if(accept("="))
|
|
{
|
|
expr();
|
|
report(" :=\n");
|
|
}
|
|
expect(";");
|
|
}
|
|
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(";")) read_next();
|
|
|
|
}
|
|
}
|
|
|
|
void Parser::prim_expr()
|
|
{
|
|
if(current_token.get_type() == t_integer)
|
|
{
|
|
report("Number: " + tok_value + "\n");
|
|
}
|
|
else if(current_token.get_type() == t_symbol)
|
|
{
|
|
report("Variable: " + tok_value + "\n");
|
|
}
|
|
else if(current_token.get_type() == t_literal)
|
|
{
|
|
report("Character literal: " + tok_value + "\n");
|
|
}
|
|
else if(accept("("))
|
|
{
|
|
expr();
|
|
expect(")");
|
|
}
|
|
else
|
|
{
|
|
error("ERROR: unexpected primary expression" + tok_value + "\n");
|
|
|
|
}
|
|
read_next();
|
|
}
|
|
|
|
void Parser::postfix_expr()
|
|
{
|
|
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");
|
|
}
|
|
}
|
|
|
|
void Parser::add_expr()
|
|
{
|
|
postfix_expr();
|
|
while(peek("+") || peek("-"))
|
|
{
|
|
if(accept("+"))
|
|
{
|
|
postfix_expr();
|
|
report(" +\n");
|
|
} else if(accept("-"))
|
|
{
|
|
postfix_expr();
|
|
report(" -\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
void Parser::rel_expr()
|
|
{
|
|
add_expr();
|
|
while(peek("<"))
|
|
{
|
|
accept("<");
|
|
add_expr();
|
|
report(" <\n");
|
|
}
|
|
}
|
|
|
|
void Parser::eq_expr()
|
|
{
|
|
rel_expr();
|
|
while(peek("==") || peek("!="))
|
|
{
|
|
if(accept("=="))
|
|
{
|
|
rel_expr();
|
|
report("==\n");
|
|
}
|
|
else if(accept("!="))
|
|
{
|
|
rel_expr();
|
|
report("!=\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
void Parser::expr()
|
|
{
|
|
eq_expr();
|
|
if(accept("="))
|
|
{
|
|
expr();
|
|
report(" := ");
|
|
}
|
|
}
|