From f1fedc36ec54578be4983d2fc6abee999dbc51c2 Mon Sep 17 00:00:00 2001 From: ov-4 Date: Thu, 29 Jan 2026 10:41:27 +0000 Subject: Added binary operations +-*/ --- lib/Parser/Parser.cc | 95 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 78 insertions(+), 17 deletions(-) (limited to 'lib/Parser') diff --git a/lib/Parser/Parser.cc b/lib/Parser/Parser.cc index 90dc3a0..76b124a 100644 --- a/lib/Parser/Parser.cc +++ b/lib/Parser/Parser.cc @@ -2,6 +2,69 @@ using namespace cps; +Parser::Parser(Lexer &L) : Lex(L) { + getNextToken(); + + BinopPrecedence['+'] = 20; + BinopPrecedence['-'] = 20; + BinopPrecedence['*'] = 40; + BinopPrecedence['/'] = 40; +} + +int Parser::GetTokPrecedence() { + if (!isascii(CurTok)) return -1; + int TokPrec = BinopPrecedence[CurTok]; + if (TokPrec <= 0) return -1; + return TokPrec; +} + +std::unique_ptr Parser::ParseParenExpr() { + getNextToken(); + auto V = ParseExpression(); + if (!V) return nullptr; + if (CurTok != ')') { + fprintf(stderr, "Error: expected ')'\n"); + return nullptr; + } + getNextToken(); + return V; +} + +std::unique_ptr Parser::ParsePrimary() { + switch (CurTok) { + case tok_identifier: return ParseIdentifierExpr(); + case tok_number: return ParseNumberExpr(); + case '(': return ParseParenExpr(); + default: + fprintf(stderr, "Error: unknown token when expecting an expression\n"); + return nullptr; + } +} + +std::unique_ptr Parser::ParseBinOpRHS(int ExprPrec, std::unique_ptr LHS) { + while (true) { + int TokPrec = GetTokPrecedence(); + + if (TokPrec < ExprPrec) + return LHS; + + int BinOp = CurTok; + getNextToken(); + + auto RHS = ParsePrimary(); + if (!RHS) return nullptr; + + int NextPrec = GetTokPrecedence(); + if (TokPrec < NextPrec) { + RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS)); + if (!RHS) return nullptr; + } + + LHS = std::make_unique(BinOp, std::move(LHS), std::move(RHS)); + } +} + + int Parser::getNextToken() { return CurTok = Lex.gettok(); } @@ -19,11 +82,9 @@ std::unique_ptr Parser::ParseIdentifierExpr() { } std::unique_ptr Parser::ParseExpression() { - if (CurTok == tok_number) - return ParseNumberExpr(); - if (CurTok == tok_identifier) - return ParseIdentifierExpr(); - return nullptr; + auto LHS = ParsePrimary(); + if (!LHS) return nullptr; + return ParseBinOpRHS(0, std::move(LHS)); } std::vector> Parser::Parse() { @@ -32,45 +93,45 @@ std::vector> Parser::Parse() { while (CurTok != tok_eof) { if (CurTok == tok_declare) { // DECLARE : INTEGER - getNextToken(); // eat DECLARE + getNextToken(); if (CurTok != tok_identifier) break; // Error std::string Name = Lex.IdentifierStr; - getNextToken(); // eat Name + getNextToken(); - if (CurTok != tok_colon) break; // Error: expected ':' - getNextToken(); // eat ':' + if (CurTok != tok_colon) break; // Error + getNextToken(); - if (CurTok != tok_integer_kw) break; // Error: expected INTEGER - getNextToken(); // eat INTEGER + if (CurTok != tok_integer_kw) break; // Error + getNextToken(); Statements.push_back(std::make_unique(Name)); } else if (CurTok == tok_identifier) { // <- std::string Name = Lex.IdentifierStr; - getNextToken(); // eat Name + getNextToken(); - if (CurTok != tok_assign) break; // Error: expected '<-' - getNextToken(); // eat '<-' + if (CurTok != tok_assign) break; // Error + getNextToken(); auto Expr = ParseExpression(); Statements.push_back(std::make_unique(Name, std::move(Expr))); } else if (CurTok == tok_input) { // INPUT - getNextToken(); // eat INPUT + getNextToken(); if (CurTok != tok_identifier) break; Statements.push_back(std::make_unique(Lex.IdentifierStr)); getNextToken(); } else if (CurTok == tok_output) { // OUTPUT - getNextToken(); // eat OUTPUT + getNextToken(); auto Expr = ParseExpression(); Statements.push_back(std::make_unique(std::move(Expr))); } else { - getNextToken(); // Skip unknown + getNextToken(); } } return Statements; -- cgit v1.3.1-4-g156e