aboutsummaryrefslogtreecommitdiff
path: root/lib/Parser/Parser.cc
blob: 76b124acee4ee75fd6ebb17e342a4df55c8d54e6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138

#include "cps/Parser.h"

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<ExprAST> 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<ExprAST> 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<ExprAST> Parser::ParseBinOpRHS(int ExprPrec, std::unique_ptr<ExprAST> 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<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS));
    }
}


int Parser::getNextToken() {
    return CurTok = Lex.gettok();
}

std::unique_ptr<ExprAST> Parser::ParseNumberExpr() {
    auto Result = std::make_unique<NumberExprAST>(Lex.NumVal);
    getNextToken();
    return Result;
}

std::unique_ptr<ExprAST> Parser::ParseIdentifierExpr() {
    std::string IdName = Lex.IdentifierStr;
    getNextToken();
    return std::make_unique<VariableExprAST>(IdName);
}

std::unique_ptr<ExprAST> Parser::ParseExpression() {
    auto LHS = ParsePrimary();
    if (!LHS) return nullptr;
    return ParseBinOpRHS(0, std::move(LHS));
}

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 (CurTok != tok_integer_kw) break; // Error
            getNextToken();

            Statements.push_back(std::make_unique<DeclareStmtAST>(Name));
        } 
        else if (CurTok == tok_identifier) {
            // <id> <- <expr>
            std::string Name = Lex.IdentifierStr;
            getNextToken();

            if (CurTok != tok_assign) break; // Error
            getNextToken();

            auto Expr = ParseExpression();
            Statements.push_back(std::make_unique<AssignStmtAST>(Name, std::move(Expr)));
        }
        else if (CurTok == tok_input) {
            // INPUT <id>
            getNextToken();
            if (CurTok != tok_identifier) break;
            Statements.push_back(std::make_unique<InputStmtAST>(Lex.IdentifierStr));
            getNextToken();
        }
        else if (CurTok == tok_output) {
            // OUTPUT <expr>
            getNextToken();
            auto Expr = ParseExpression();
            Statements.push_back(std::make_unique<OutputStmtAST>(std::move(Expr)));
        }
        else {
            getNextToken();
        }
    }
    return Statements;
}