diff --git a/src/Parser.cpp b/src/Parser.cpp index 0e848cc..39a6927 100644 --- a/src/Parser.cpp +++ b/src/Parser.cpp @@ -6,7 +6,7 @@ Parser::Parser(vector> tokens): tokens(tokens) { vector> Parser::getStatements() { vector> statements; - while (tokens.at(currentIndex)->getKind() != TokenKind::END) { + while (!tryMatchingTokenKinds({TokenKind::END}, true, false)) { shared_ptr statement = nextStatement(); // Abort parsing if we got an error if (!statement->isValid()) { @@ -45,7 +45,8 @@ shared_ptr Parser::nextStatement() { } shared_ptr Parser::matchStatementFunctionDeclaration() { - if (!matchesTokenKinds({TokenKind::IDENTIFIER, TokenKind::COLON, TokenKind::FUNCTION})) + //if (!matchesTokenKinds({TokenKind::IDENTIFIER, TokenKind::COLON, TokenKind::FUNCTION})) + if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER, TokenKind::COLON, TokenKind::FUNCTION}, true, false)) return nullptr; shared_ptr identifierToken = tokens.at(currentIndex); @@ -53,9 +54,10 @@ shared_ptr Parser::matchStatementFunctionDeclaration() { currentIndex++; // skip colon currentIndex++; // skip fun - while (tokens.at(currentIndex)->getKind() != TokenKind::NEW_LINE) { + // FIXME: implement function arguments + while (!tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, false)) currentIndex++; - } + currentIndex++; // new line shared_ptr statementBlock = matchStatementBlock(); if (statementBlock == nullptr) @@ -67,7 +69,7 @@ shared_ptr Parser::matchStatementFunctionDeclaration() { } shared_ptr Parser::matchStatementVarDeclaration() { - if (!matchesTokenKinds({TokenKind::IDENTIFIER, TokenKind::COLON, TokenKind::TYPE})) + if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER, TokenKind::COLON, TokenKind::TYPE}, true, false)) return nullptr; shared_ptr identifierToken = tokens.at(currentIndex); @@ -77,9 +79,8 @@ shared_ptr Parser::matchStatementVarDeclaration() { currentIndex++; // skip fun // Expect left arrow - if (tokens.at(currentIndex)->getKind() != TokenKind::LEFT_ARROW) + if (!tryMatchingTokenKinds({TokenKind::LEFT_ARROW}, true, true)) return matchStatementInvalid(); - currentIndex++; shared_ptr expression = nextExpression(); if (expression == nullptr || !expression->isValid()) @@ -98,10 +99,8 @@ shared_ptr Parser::matchStatementVarDeclaration() { return matchStatementInvalid(); // Expect new line - if (tokens.at(currentIndex)->getKind() != TokenKind::NEW_LINE) + if (!tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true)) return matchStatementInvalid(); - - currentIndex++; return make_shared(identifierToken->getLexme(), valueType, expression); } @@ -109,7 +108,7 @@ shared_ptr Parser::matchStatementVarDeclaration() { shared_ptr Parser::matchStatementBlock() { vector> statements; - while (!tokens.at(currentIndex)->isOfKind({TokenKind::SEMICOLON, TokenKind::COLON})) { + while (!tryMatchingTokenKinds({TokenKind::SEMICOLON, TokenKind::COLON}, false, false)) { shared_ptr statement = nextStatement(); if (statement == nullptr) return matchStatementInvalid(); @@ -119,34 +118,28 @@ shared_ptr Parser::matchStatementBlock() { statements.push_back(statement); } // consune ';' only - if (tokens.at(currentIndex)->getKind() == TokenKind::SEMICOLON) { - currentIndex++; - - if (!tokens.at(currentIndex)->isOfKind({TokenKind::NEW_LINE, TokenKind::END})) + if (tryMatchingTokenKinds({TokenKind::SEMICOLON}, true, true)) { + if (!tryMatchingTokenKinds({TokenKind::NEW_LINE, TokenKind::END}, false, false)) return matchStatementInvalid(); - if (tokens.at(currentIndex)->getKind() == TokenKind::NEW_LINE) - currentIndex++; + tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true); } return make_shared(statements); } shared_ptr Parser::matchStatementReturn() { - if (tokens.at(currentIndex)->getKind() != TokenKind::RETURN) + if (!tryMatchingTokenKinds({TokenKind::RETURN}, true, true)) return nullptr; - - currentIndex++; shared_ptr expression = nextExpression(); if (expression != nullptr && !expression->isValid()) return matchStatementInvalid(); - if (!tokens.at(currentIndex)->isOfKind({TokenKind::NEW_LINE, TokenKind::SEMICOLON})) + if (!tryMatchingTokenKinds({TokenKind::NEW_LINE, TokenKind::SEMICOLON}, false, false)) return matchStatementInvalid(); - if (tokens.at(currentIndex)->getKind() == TokenKind::NEW_LINE) - currentIndex++; // new line + tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true); return make_shared(expression); } @@ -160,8 +153,7 @@ shared_ptr Parser::matchStatementExpression() { return make_shared(tokens.at(currentIndex)); // Consume new line - if (tokens.at(currentIndex)->getKind() == TokenKind::NEW_LINE) - currentIndex++; + tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true); return make_shared(expression); } @@ -196,7 +188,7 @@ shared_ptr Parser::matchEquality() { if (expression == nullptr || !expression->isValid()) return expression; - while (tokens.at(currentIndex)->isOfKind(Token::tokensEquality)) + while (tryMatchingTokenKinds({Token::tokensEquality}, false, false)) expression = matchExpressionBinary(expression); return expression; @@ -207,7 +199,7 @@ shared_ptr Parser::matchComparison() { if (expression == nullptr || !expression->isValid()) return expression; - while (tokens.at(currentIndex)->isOfKind(Token::tokensComparison)) + while (tryMatchingTokenKinds({Token::tokensComparison}, false, false)) expression = matchExpressionBinary(expression); return expression; @@ -218,7 +210,7 @@ shared_ptr Parser::matchTerm() { if (expression == nullptr || !expression->isValid()) return expression; - while (tokens.at(currentIndex)->isOfKind(Token::tokensTerm)) + while (tryMatchingTokenKinds({Token::tokensTerm}, false, false)) expression = matchExpressionBinary(expression); return expression; @@ -251,26 +243,23 @@ shared_ptr Parser::matchPrimary() { shared_ptr Parser::matchExpressionLiteral() { shared_ptr token = tokens.at(currentIndex); - if (token->isOfKind({TokenKind::BOOL, TokenKind::INTEGER, TokenKind::REAL})) { - currentIndex++; + + if (tryMatchingTokenKinds({TokenKind::BOOL, TokenKind::INTEGER, TokenKind::REAL}, false, true)) return make_shared(token); - } return nullptr; } shared_ptr Parser::matchExpressionGrouping() { shared_ptr token = tokens.at(currentIndex); - if (token->getKind() == TokenKind::LEFT_PAREN) { - currentIndex++; + if (tryMatchingTokenKinds({TokenKind::LEFT_PAREN}, true, true)) { shared_ptr expression = matchTerm(); // has grouped expression failed? if (expression == nullptr) { return matchExpressionInvalid(); } else if(!expression->isValid()) { return expression; - } else if (tokens.at(currentIndex)->getKind() == TokenKind::RIGHT_PAREN) { - currentIndex++; + } else if (tryMatchingTokenKinds({TokenKind::RIGHT_PAREN}, true, true)) { return make_shared(expression); } else { return matchExpressionInvalid(); @@ -284,17 +273,13 @@ shared_ptr Parser::matchExpressionBinary(shared_ptr left shared_ptr token = tokens.at(currentIndex); shared_ptr right; // What level of binary expression are we having? - if (token->isOfKind(Token::tokensEquality)) { - currentIndex++; + if (tryMatchingTokenKinds(Token::tokensEquality, false, true)) { right = matchComparison(); - } else if (token->isOfKind(Token::tokensComparison)) { - currentIndex++; + } else if (tryMatchingTokenKinds(Token::tokensComparison, false, true)) { right = matchTerm(); - } else if (token->isOfKind(Token::tokensTerm)) { - currentIndex++; + } else if (tryMatchingTokenKinds(Token::tokensTerm, false, true)) { right = matchFactor(); - } else if (token->isOfKind(Token::tokensFactor)) { - currentIndex++; + } else if (tryMatchingTokenKinds(Token::tokensFactor, false, true)) { right = matchPrimary(); } @@ -312,9 +297,10 @@ shared_ptr Parser::matchExpressionBinary(shared_ptr left shared_ptr Parser::matchExpressionIfElse() { // Try maching '?' shared_ptr token = tokens.at(currentIndex); - if (token->getKind() != TokenKind::QUESTION) + + //if (!tryAdvancingForOneOfTokenKinds({TokenKind::QUESTION})) + if (!tryMatchingTokenKinds({TokenKind::QUESTION}, true, true)) return nullptr; - currentIndex++; // Then get condition shared_ptr condition = nextExpression(); @@ -324,9 +310,9 @@ shared_ptr Parser::matchExpressionIfElse() { return condition; // Match ':', '\n', or ':\n' - if (matchesTokenKinds({TokenKind::COLON, TokenKind::NEW_LINE})) + if (tryMatchingTokenKinds({TokenKind::COLON, TokenKind::NEW_LINE}, true, false)) currentIndex += 2; - else if (tokens.at(currentIndex)->isOfKind({TokenKind::COLON, TokenKind::NEW_LINE})) + else if (tryMatchingTokenKinds({TokenKind::COLON, TokenKind::NEW_LINE}, false, false)) currentIndex++; else return matchExpressionInvalid(); @@ -341,10 +327,8 @@ shared_ptr Parser::matchExpressionIfElse() { // Match else block shared_ptr elseBlock; - if (tokens.at(currentIndex)->getKind() == TokenKind::COLON) { - currentIndex++; - if (tokens.at(currentIndex)->getKind() == TokenKind::NEW_LINE) - currentIndex++; + if (tryMatchingTokenKinds({TokenKind::COLON}, true, true)) { + tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true); elseBlock = matchStatementBlock(); if (elseBlock == nullptr) @@ -362,10 +346,9 @@ shared_ptr Parser::matchExpressionIfElse() { shared_ptr Parser::matchExpressionVar() { shared_ptr token = tokens.at(currentIndex); - if (token->isOfKind({TokenKind::IDENTIFIER})) { - currentIndex++; + + if (tryMatchingTokenKinds({TokenKind::IDENTIFIER}, true, true)) return make_shared(token->getLexme()); - } return nullptr; } @@ -374,14 +357,30 @@ shared_ptr Parser::matchExpressionInvalid() { return make_shared(tokens.at(currentIndex)); } -bool Parser::matchesTokenKinds(vector kinds) { - if (currentIndex + kinds.size() >= tokens.size()) +bool Parser::tryMatchingTokenKinds(vector kinds, bool shouldMatchAll, bool shouldAdvance) { + int requiredCount = shouldMatchAll ? kinds.size() : 1; + if (currentIndex + requiredCount > tokens.size()) return false; + + if (shouldMatchAll) { + for (int i=0; igetKind()) + return false; + } - for (int i=0; igetKind()) - return false; + if (shouldAdvance) + currentIndex += kinds.size(); + + return true; + } else { + for (int i=0; igetKind()) { + if (shouldAdvance) + currentIndex++; + return true; + } + } + + return false; } - - return true; } diff --git a/src/Parser.h b/src/Parser.h index c73b776..c2e5548 100644 --- a/src/Parser.h +++ b/src/Parser.h @@ -36,7 +36,7 @@ private: shared_ptr matchExpressionVar(); shared_ptr matchExpressionInvalid(); - bool matchesTokenKinds(vector kinds); + bool tryMatchingTokenKinds(vector kinds, bool shouldMatchAll, bool shouldAdvance); public: Parser(vector> tokens);