-
-
Save bbielsa/f93e22ddd7ffac4a29425237962aed2d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "parser.h" | |
#include <string> | |
#include <sstream> | |
Parser::Parser(std::istream *in) { | |
this->in = in; | |
this->hasSavedToken = false; | |
} | |
void Parser::error(Token errorToken, std::string reason) { | |
std::cout << linenum << ": Syntax error, " << reason << std::endl; | |
std::exit(1); | |
} | |
Token Parser::getToken() { | |
if(hasSavedToken) { | |
hasSavedToken = false; | |
return savedToken; | |
} | |
return ::getToken(this->in); | |
} | |
void Parser::validateNextToken(std::string lexeme) { | |
auto next = getToken(); | |
if(next.getLexeme() != lexeme) | |
this->error(next, "unexpected token"); | |
} | |
Token Parser::peekToken() { | |
if(!hasSavedToken) { | |
savedToken = ::getToken(this->in); | |
hasSavedToken = true; | |
} | |
return savedToken; | |
} | |
StatementList *Parser::ParseStatementList() { | |
StatementList *statementList = NULL; | |
StatementList *subStatementList = NULL; | |
auto firstStatement = this->ParseStatement(); | |
auto nextToken = this->peekToken(); | |
if(nextToken.getTok() != DONE) { | |
subStatementList = this->ParseStatementList(); | |
} | |
if(firstStatement == NULL) { | |
} | |
statementList = new StatementList(firstStatement, subStatementList); | |
return statementList; | |
} | |
Statement *Parser::ParseStatement() { | |
Statement *statement = NULL; | |
auto operation = this->getToken(); | |
switch(operation.getTok()) { | |
case PRINT: | |
{ | |
auto printExpression = this->ParseExpression(); | |
statement = new PrintStatement(printExpression); | |
break; | |
} | |
case SET: | |
{ | |
auto id = (Identifier *)this->ParsePrimary(); | |
auto setExpression = this->ParseExpression(); | |
statement = new SetStatement(id, setExpression); | |
break; | |
} | |
default: | |
this->error(operation, "invalid statement"); | |
return 0; | |
} | |
// consume sc | |
this->getToken(); | |
return statement; | |
} | |
Expression *Parser::ParseExpression() { | |
Expression *expression = NULL; | |
auto firstTerm = this->ParseTerm(); | |
auto plus = this->peekToken(); | |
if(plus.getTok() == PLUS) { | |
this->getToken(); | |
auto subExpression = this->ParseExpression(); | |
expression = new PlusExpression(firstTerm, subExpression); | |
} | |
else { | |
return firstTerm; | |
} | |
return expression; | |
} | |
Expression *Parser::ParseTerm() { | |
Term *term = NULL; | |
auto firstPrimary = this->ParsePrimary(); | |
auto star = this->peekToken(); | |
if(star.getTok() == STAR) { | |
this->getToken(); | |
auto subTerm = this->ParseTerm(); | |
term = new MultiplyTerm(firstPrimary, subTerm); | |
} | |
else { | |
return firstPrimary; | |
} | |
return term; | |
} | |
String *Parser::ParseString() { | |
String *string = NULL; | |
Expression *firstIndex = NULL; | |
Expression *secondIndex = NULL; | |
auto stringToken = this->getToken(); | |
auto next = this->peekToken(); | |
if(next.getTok() == LEFTSQ) { | |
// skip [ | |
this->getToken(); | |
firstIndex = this->ParseExpression(); | |
next = this->peekToken(); | |
if(next.getTok() == SC) { | |
// skip ; | |
this->getToken(); | |
secondIndex = this->ParseExpression(); | |
} | |
// consume ] | |
this->getToken(); | |
} | |
string = new String(stringToken, firstIndex, secondIndex); | |
return string; | |
} | |
Expression *Parser::ParsePrimary() { | |
Expression *resultTree = NULL; | |
auto t = this->peekToken(); | |
switch(t.getTok()) { | |
case INT: | |
{ | |
auto token = this->getToken(); | |
resultTree = new Integer(token); | |
break; | |
} | |
case ID: | |
resultTree = new Identifier(this->getToken()); | |
break; | |
case STR: | |
resultTree = this->ParseString(); | |
break; | |
case LPAREN: | |
// skip ( | |
this->getToken(); | |
resultTree = this->ParseExpression(); | |
//this->ParseExpression(); | |
// consume ) | |
this->getToken(); | |
break; | |
default: | |
return 0; | |
} | |
return resultTree; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment