-
Notifications
You must be signed in to change notification settings - Fork 0
/
Parser.h
152 lines (131 loc) · 4.3 KB
/
Parser.h
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#ifndef _PARSER_H_
#define _PARSER_H_
#include "Lexer.h"
#include "AST.h"
#include <utility>
#include <string>
#include <stack>
using namespace std;
class Parser {
public:
Parser(std::string filename): l(filename) {}
shared_ptr<Program> parse();
vector<pair<string, string>> getEdges() const;
vector<pair<string, string>> getOrder() const;
private:
Lexer l;
ErrorHandling err;
vector<pair<string, string>> edges;
// Used in top-sort to build symbol table in top-sort order.
// See ClassFilter.
vector<pair<string, string>> OrderEdge;
// Store the value of the current class we parse.
stack<string>CurClass;
shared_ptr<Program> ParseProgram();
shared_ptr<MainClass> ParseMainClass();
shared_ptr<ClassDecl> ParseClassDecl();
shared_ptr<VarDecl> ParseVarDecl();
shared_ptr<MethodDecl> ParseMethodDecl();
shared_ptr<Argument> ParseArgument();
shared_ptr<Type> ParseType();
// We need this to parse int types.
// Arrays and int types has the same start symbols
// int x;
// int [] x;
shared_ptr<Type> ParseTypeHelper();
shared_ptr<BoolType> ParseBoolType();
shared_ptr<IdentifierType> ParseIdType();
shared_ptr<Statement> ParseStatement();
shared_ptr<Block> ParseBlock();
shared_ptr<If> ParseIf();
shared_ptr<While> ParseWhile();
shared_ptr<Print> ParsePrint();
shared_ptr<Statement> ParseStatementHelper();
// To parse expression we should elimenate left recuresion.
// Expression ::= Expression ( "&&" | "<" | "+" | "-" | "*" ) Expression
// | Expression "[" Expression "]"
// | Expression "." "length"
// | Expression "." Identifier "(" ( Expression ( "," Expression )* )? ")"
// | <INTEGER_LITERAL>
// | "true"
// | "false"
// | Identifier
// | "this"
// | "new" "int" "[" Expression "]"
// | "new" Identifier "(" ")"
// | "!" Expression
// | "(" Expression ")"
// This is equivelent to:
// Expression ::= Expression Alpha | Beta
// We convert this grammar to:
// Expression ::= Beta GoodExpression
// GoodExpression ::= Alpha GoodExpression | epselon
// Alpha ::= ( "&&" | "<" | "+" | "-" | "*" ) Expression
// | "[" Expression "]"
// | "." "length"
// | "." Identifier "(" ( Expression ( "," Expression )* )? ")"
// Beta ::= <INTEGER_LITERAL>
// | "true"
// | "false"
// | Identifier
// | "this"
// | "new" "int" "[" Expression "]"
// | "new" Identifier "(" ")"
// | "!" Expression
// | "(" Expression ")"
shared_ptr<Expression> ParseExpression();
shared_ptr<Expression> ParseAlpha(shared_ptr<Expression> LHS);
// Parse binary operations using Operator-Precedence Parsing
shared_ptr<BinOpExpression> ParseBinOpExpression(int ExpPerc,
shared_ptr<Expression> LHS);
int GetPercedence(TOK op);
shared_ptr<ArrayLookup> ParseArrayLookup(shared_ptr<Expression> LHS);
shared_ptr<Expression> ParseDotHelper(shared_ptr<Expression> LHS);
shared_ptr<ArrayLength> ParseArrayLength(shared_ptr<Expression> LHS);
shared_ptr<Call> ParseCallExpression(shared_ptr<Expression> LHS);
shared_ptr<Expression> ParseBeta();
shared_ptr<IntegerLiteral> ParseIntLit();
shared_ptr<True> ParseTrue();
shared_ptr<False> ParseFalse();
shared_ptr<IdentifierExp> ParseIdExp();
shared_ptr<NewArray> ParseNewArray();
shared_ptr<NewObject> ParseNewObject();
shared_ptr<Not> ParseNot();
shared_ptr<Expression> ParseParenExpr();
shared_ptr<Expression> ParseNewHelper();
shared_ptr<This> ParseThis();
shared_ptr<Expression> ParseGoodExpression(shared_ptr<Expression> LHS);
shared_ptr<Identifier> ParseIdentifier();
// Here we define some helper functions
// to help us decide which grammer production
// we should follow.
// Variable Declarations
bool IsVarStart(TOK tk) {
return tk == INT || tk == BOOL || tk == ID;
}
// Method
bool IsMethodStart(TOK tk) {
return tk == PUBLIC;
}
// Class
bool IsClassStart(TOK tk) {
return tk == CLASS;
}
// Statement
bool IsStatementStart(TOK tk) {
return tk == L_BRACKET
|| tk == IF
|| tk == WHILE
|| tk == PRINT
|| tk == ID;
}
// Binary operations
bool IsBinOp(TOK tk) {
return tk > __OP_START && tk < __OP_END && tk != NOT;
}
// epsilon
bool IsStillGood(TOK tk) {
return tk == DOT || tk == L_SBRACKET|| IsBinOp(tk);
}
};
#endif