#include "Parser.h" Parser::Parser(vector tokens): tokens(tokens) { } vector> Parser::getStatements() { vector> statements; while (tokens.at(currentIndex).getKind() != Token::Kind::END) { shared_ptr statement = nextStatement(); // Abort parsing if we got an error if (!statement->isValid()) { cerr << "Unexpected token '" << statement->getToken()->getLexme() << "' at " << statement->getToken()->getLine() << ":" << statement->getToken()->getColumn() << endl; return vector>(); } statements.push_back(statement); } return statements; } // // Statement // shared_ptr Parser::nextStatement() { { shared_ptr statement = matchExpressionStatement(); if (statement->isValid()) return statement; } return matchInvalidStatement(); } shared_ptr Parser::matchInvalidStatement() { return make_shared(Statement::Kind::INVALID, make_shared(tokens.at(currentIndex)), nullptr); } // // Expression // shared_ptr Parser::matchExpressionStatement() { shared_ptr expression = term(); if (expression->isValid()) { return make_shared(Statement::Kind::EXPRESSION, nullptr, expression); } else { return make_shared(Statement::Kind::INVALID, make_shared(tokens.at(currentIndex)), expression); } } shared_ptr Parser::term() { shared_ptr expression = factor(); while (tokens.at(currentIndex).isOfKind({Token::Kind::PLUS, Token::Kind::MINUS})) { expression = matchBinary(expression); } return expression; } shared_ptr Parser::factor() { shared_ptr expression = primary(); while (tokens.at(currentIndex).isOfKind({Token::Kind::STAR, Token::Kind::SLASH, Token::Kind::PERCENT})) { expression = matchBinary(expression); } return expression; } shared_ptr Parser::primary() { { shared_ptr expression = matchInteger(); if (expression->isValid()) return expression; } { shared_ptr expression = matchGrouping(); if (expression->isValid()) return expression; } return make_shared(Expression::Kind::INVALID, tokens.at(currentIndex), nullptr, nullptr); } shared_ptr Parser::matchInteger() { Token token = tokens.at(currentIndex); if (token.getKind() == Token::Kind::INTEGER) { currentIndex++; return make_shared(Expression::Kind::LITERAL, token, nullptr, nullptr); } return make_shared(Expression::Kind::INVALID, token, nullptr, nullptr); } shared_ptr Parser::matchGrouping() { Token token = tokens.at(currentIndex); if (token.getKind() == Token::Kind::LEFT_PAREN) { currentIndex++; shared_ptr expression = term(); // has grouped expression failed? if (!expression->isValid()) return expression; if (tokens.at(currentIndex).getKind() == Token::Kind::RIGHT_PAREN) { currentIndex++; return make_shared(Expression::Kind::GROUPING, token, expression, nullptr); } } return make_shared(Expression::Kind::INVALID, token, nullptr, nullptr); } shared_ptr Parser::matchBinary(shared_ptr left) { Token token = tokens.at(currentIndex); if (token.isOfKind({Token::Kind::PLUS, Token::Kind::MINUS, Token::Kind::STAR, Token::Kind::SLASH, Token::Kind::PERCENT})) { currentIndex++; shared_ptr right = factor(); // Has right expression failed? if (!right->isValid()) return right; return make_shared(Expression::Kind::BINARY, token, left, right); } return make_shared(Expression::Kind::INVALID, token, nullptr, nullptr); }