Skip to content

Instantly share code, notes, and snippets.

@bbielsa
Created February 19, 2019 01:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bbielsa/f93e22ddd7ffac4a29425237962aed2d to your computer and use it in GitHub Desktop.
Save bbielsa/f93e22ddd7ffac4a29425237962aed2d to your computer and use it in GitHub Desktop.
#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