-
Notifications
You must be signed in to change notification settings - Fork 0
/
CParser.cpp
170 lines (156 loc) · 3.48 KB
/
CParser.cpp
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/*
* Kainoa Seto
* The recursive descent parser and interpreter as certain tokens are reached. This makes
* direct calls to the Scanner instance that is passed into the constructor and then gets
* all tokens from the src file and decides what to do when it receives certain tokens based
* on the grammer defined in CGrammer.h
* 11-29-16
*/
#include "CParser.h"
CParser::CParser(CScanner* scanner)
{
// Initialize our stack, really its just a well navigated array
stackinit();
top = 0;
this->scanner = scanner;
}
void CParser::Parse()
{
program();
}
void CParser::match(int expectedToken)
{
if(token == expectedToken)
{
if(token != EOFSY)
token = scanner->GetToken();
}
else
{
// Any syntax error we will exit
cout << "Token " << TokenNames[expectedToken] << "(" << expectedToken << ")"
<< " expected, but instead encountered "
<< scanner->GetTokenChar() << endl;
exit(1);
}
}
void CParser::program()
{
token = scanner->GetToken();
stmt_list();
match(EOFSY);
}
void CParser::stmt_list()
{
if(token == ID || token == READSY || token == WRITESY)
{
stmt();
stmt_list();
}
}
void CParser::stmt()
{
if(token == ID)
{
string currentId = scanner->GetTokenChar();
match(ID);
match(ASSIGNOP);
expr();
symbolTable[currentId] = pop();
cout << "Assign: " << currentId << " = " << symbolTable[currentId] << endl;
}
if(token == READSY)
{
double readValue = 0.0;
match(READSY);
cout << "Read: Enter value for " << scanner->GetTokenChar() << "> ";
cin >> readValue;
symbolTable[scanner->GetTokenChar()] = readValue;
match(ID);
}
if(token == WRITESY)
{
match(WRITESY);
expr();
cout << "Write: " << pop() << endl;
}
}
void CParser::expr()
{
term();
term_tail();
}
void CParser::term_tail()
{
if (token == ADDOP)
{
match(ADDOP);
term();
double firstValue = pop();
double secondValue = pop();
push(firstValue+secondValue);
term_tail();
}
else if(token == SUBOP)
{
match(SUBOP);
term();
double firstValue = pop();
double secondValue = pop();
push(secondValue-firstValue);
term_tail();
}
}
void CParser::term()
{
factor();
factor_tail();
}
void CParser::factor_tail()
{
if(token == MULOP)
{
match(MULOP);
factor();
double firstValue = pop();
double secondValue = pop();
push(firstValue*secondValue);
factor_tail();
}
else if(token == DIVOP)
{
match(DIVOP);
factor();
double firstValue = pop();
double secondValue = pop();
push(secondValue/firstValue);
factor_tail();
}
}
void CParser::factor()
{
// Handle ( expresion )
if(token == LPAREN)
{
match(LPAREN);
expr();
match(RPAREN);
}
// Handle an ID/Variable name
else if(token == ID)
{
if(symbolTable.count(scanner->GetTokenChar()) == 0)
{
cout << "ERROR couldn't find token value in symbol table!" << endl;
exit(1);
}
push(symbolTable[scanner->GetTokenChar()]);
match(ID);
}
// Handle any constants/numbers
else if(token == NUMCONST)
{
push(atof(scanner->GetTokenChar()));
match(NUMCONST);
}
}