aboutsummaryrefslogtreecommitdiff
path: root/lib/Parser
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Parser')
-rw-r--r--lib/Parser/Parser.cc148
1 files changed, 109 insertions, 39 deletions
diff --git a/lib/Parser/Parser.cc b/lib/Parser/Parser.cc
index 76b124a..ee94b36 100644
--- a/lib/Parser/Parser.cc
+++ b/lib/Parser/Parser.cc
@@ -5,10 +5,12 @@ using namespace cps;
Parser::Parser(Lexer &L) : Lex(L) {
getNextToken();
- BinopPrecedence['+'] = 20;
- BinopPrecedence['-'] = 20;
- BinopPrecedence['*'] = 40;
- BinopPrecedence['/'] = 40;
+ BinopPrecedence[tok_eq] = 10;
+ BinopPrecedence[tok_ne] = 10;
+ BinopPrecedence[tok_le] = 10;
+ BinopPrecedence[tok_ge] = 10;
+ BinopPrecedence['<'] = 10;
+ BinopPrecedence['>'] = 10;
}
int Parser::GetTokPrecedence() {
@@ -91,48 +93,116 @@ std::vector<std::unique_ptr<StmtAST>> Parser::Parse() {
std::vector<std::unique_ptr<StmtAST>> Statements;
while (CurTok != tok_eof) {
- if (CurTok == tok_declare) {
- // DECLARE <id> : INTEGER
- getNextToken();
- if (CurTok != tok_identifier) break; // Error
- std::string Name = Lex.IdentifierStr;
- getNextToken();
-
- if (CurTok != tok_colon) break; // Error
- getNextToken();
+ if (auto Stmt = ParseStatement()) {
+ Statements.push_back(std::move(Stmt));
+ } else {
+ if (CurTok != tok_eof) getNextToken();
+ }
+ }
+ return Statements;
+}
+
+
+std::unique_ptr<StmtAST> Parser::ParseIfStmt() {
+ getNextToken();
+
+ auto Cond = ParseExpression();
+ if (!Cond) return nullptr;
+
+ if (CurTok != tok_then) {
+ fprintf(stderr, "Error: expected THEN\n");
+ return nullptr;
+ }
+ getNextToken();
+
+
+ std::vector<std::unique_ptr<StmtAST>> ThenStmts;
+ while (CurTok != tok_else && CurTok != tok_endif && CurTok != tok_eof) {
+ auto Stmt = ParseStatement();
+ if (Stmt) ThenStmts.push_back(std::move(Stmt));
+ }
- if (CurTok != tok_integer_kw) break; // Error
- getNextToken();
+ std::vector<std::unique_ptr<StmtAST>> ElseStmts;
+ if (CurTok == tok_else) {
+ getNextToken();
+ while (CurTok != tok_endif && CurTok != tok_eof) {
+ auto Stmt = ParseStatement();
+ if (Stmt) ElseStmts.push_back(std::move(Stmt));
+ }
+ }
- Statements.push_back(std::make_unique<DeclareStmtAST>(Name));
- }
- else if (CurTok == tok_identifier) {
- // <id> <- <expr>
- std::string Name = Lex.IdentifierStr;
- getNextToken();
+ if (CurTok != tok_endif) {
+ fprintf(stderr, "Error: expected ENDIF\n");
+ return nullptr;
+ }
+ getNextToken();
- if (CurTok != tok_assign) break; // Error
- getNextToken();
+ return std::make_unique<IfStmtAST>(std::move(Cond), std::move(ThenStmts), std::move(ElseStmts));
+}
- auto Expr = ParseExpression();
- Statements.push_back(std::make_unique<AssignStmtAST>(Name, std::move(Expr)));
+std::unique_ptr<StmtAST> Parser::ParseStatement() {
+ // DECLARE
+ if (CurTok == tok_declare) {
+ getNextToken();
+ if (CurTok != tok_identifier) {
+ fprintf(stderr, "Error: expected identifier after DECLARE\n");
+ return nullptr;
+ }
+ std::string Name = Lex.IdentifierStr;
+ getNextToken();
+
+ if (CurTok != tok_colon) {
+ fprintf(stderr, "Error: expected ':' after identifier\n");
+ return nullptr;
}
- else if (CurTok == tok_input) {
- // INPUT <id>
- getNextToken();
- if (CurTok != tok_identifier) break;
- Statements.push_back(std::make_unique<InputStmtAST>(Lex.IdentifierStr));
- getNextToken();
+ getNextToken();
+
+ if (CurTok != tok_integer_kw) {
+ fprintf(stderr, "Error: expected INTEGER type\n");
+ return nullptr;
}
- else if (CurTok == tok_output) {
- // OUTPUT <expr>
- getNextToken();
- auto Expr = ParseExpression();
- Statements.push_back(std::make_unique<OutputStmtAST>(std::move(Expr)));
+ getNextToken();
+ return std::make_unique<DeclareStmtAST>(Name);
+ }
+
+ // ASSIGNMENT (x <- expr)
+ else if (CurTok == tok_identifier) {
+ std::string Name = Lex.IdentifierStr;
+ getNextToken(); // eat Name
+
+ if (CurTok != tok_assign) {
+ fprintf(stderr, "Error: expected '<-' for assignment\n");
+ return nullptr;
}
- else {
- getNextToken();
+ getNextToken();
+
+ auto Expr = ParseExpression();
+ return std::make_unique<AssignStmtAST>(Name, std::move(Expr));
+ }
+
+ // INPUT
+ else if (CurTok == tok_input) {
+ getNextToken();
+ if (CurTok != tok_identifier) {
+ fprintf(stderr, "Error: expected identifier after INPUT\n");
+ return nullptr;
}
+ std::string Name = Lex.IdentifierStr;
+ getNextToken();
+ return std::make_unique<InputStmtAST>(Name);
}
- return Statements;
+
+ // OUTPUT
+ else if (CurTok == tok_output) {
+ getNextToken();
+ auto Expr = ParseExpression();
+ return std::make_unique<OutputStmtAST>(std::move(Expr));
+ }
+
+ // IF
+ else if (CurTok == tok_if) {
+ return ParseIfStmt();
+ }
+
+ return nullptr;
}