sencha-lang/sencha/Parser.cpp

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(" := ");
}
}