index
1 /**************************************************
2 * file: Parser.cpp
3 * date: 2006-04-12
4 * author: ideawu
5 * describe: parser
6 **************************************************/
7
8 //#define TRACE_DEBUG
9
10 #ifdef TRACE_DEBUG
11 #define TRACE(FUNCTION) printf("%-16s token = %s\n", FUNCTION, currentToken.name);
12 #else
13 #define TRACE(FUNCTION)
14 #endif
15
16
17 #include "Parser.h"
18 #include <stdio.h>
19 #include <stdlib.h>
20
21 Parser::Parser(char* sourcefile){
22 lexer = new Lexer(sourcefile);
23 }
24
25 Parser::Parser(){
26 }
27
28 Parser::~Parser(){
29 delete lexer;
30 }
31
32 void Parser::setLexer(Lexer *srclexer){
33 lexer = srclexer;
34 }
35
36
37 Token Parser::nextToken(){
38 currentToken = lexer->nextToken();
39 return currentToken;
40 }
41
42 void Parser::reset(){
43 lexer->reset();
44 }
45
46 void Parser::printError(const char *error){ // private method
47 printf("%s when token = '%s'\n", error, currentToken.name);
48 }
49
50 void Parser::printError(){ // public method
51 if(lexer->isReady())
52 printf("\n*** ERROR BEFORE: ***\n%s", lexer->getSrc()+lexer->getIndex());
53 else
54 printf("Lexer is not ready!\n");
55 }
56
57 /*==================================================================*/
58
59 SyntaxTree* Parser::parse(){
60 SyntaxTree* tree = NULL;
61 if(lexer->isReady()){
62 currentToken = lexer->nextToken();
63 tree = Statement();
64 }else{
65 printf("no ready\n");
66 }
67 return tree;
68 }
69
70
71 SyntaxTree* Parser::Statement(){
72 TRACE("in Statement();");
73
74 SyntaxTree *tree = NULL;
75
76 switch(currentToken.type){
77 case LEXER_DONE:
78 tree = new SyntaxTree(LEXER_DONE);
79 break;
80 case ID:
81 this->nextToken();
82 tree = Assign();
83 if(tree != NULL){
84 tree->addLeft(ID);
85 }
86 break;
87 case WHILE:
88 this->nextToken();
89 tree = While();
90 break;
91 case BEGIN:
92 this->nextToken();
93 tree = Block();
94 if(currentToken.type != END){
95 tree = NULL;
96 this->printError("ERROR! begin without end");
97 }
98 //this->nextToken();
99 this->currentToken.type = SEMI;
100 break;
101 case IF:
102 this->nextToken();
103 tree = Condition();
104 break;
105 default:
106 tree = NULL;
107 break;
108 }
109
110 TRACE("out Statement();");
111 return tree;
112 }
113
114
115 SyntaxTree* Parser::Assign(){
116 TRACE("in Assign();");
117
118 SyntaxTree *tree = NULL;
119
120 if(currentToken.type == ASSIGN){
121 this->nextToken();
122 SyntaxTree *temptree = Expression();
123
124 if(temptree != NULL){
125 tree = new SyntaxTree(ASSIGN);
126 tree->addRight(temptree);
127 }
128 }else{
129 this->printError("ERROR! Assignment statement expects '=';");
130 return NULL;
131 }
132
133 TRACE("out Assign();");
134 return tree;
135 }
136
137
138 SyntaxTree* Parser::Expression(){
139 TRACE("in Expression();");
140
141 SyntaxTree *temp = NULL;
142 SyntaxTree *tree = T();
143
144 if(tree == NULL){
145 return NULL;
146 }
147
148 while(currentToken.type == PLUS || currentToken.type == MINUS){
149 temp = new SyntaxTree(currentToken.type);
150 temp->addLeft(tree);
151 tree = temp;
152 this->nextToken();
153
154 temp = T();
155 if(temp != NULL){
156 tree->addRight(temp);
157 }else{
158 this->printError("ERROR! Behind '+';");
159 return NULL;
160 }
161 }
162
163 return tree;
164 }
165
166
167 SyntaxTree* Parser::T(){
168 SyntaxTree *temp = NULL;
169 SyntaxTree *tree = F();
170
171 if(tree == NULL){
172 return NULL;
173 }
174
175 while(currentToken.type == MUL || currentToken.type == DIV){
176 temp = new SyntaxTree(currentToken.type);
177 temp->addLeft(tree);
178 tree = temp;
179 this->nextToken();
180
181 temp = F();
182 if(temp != NULL){
183 tree->addRight(temp);
184 }else{
185 this->printError("ERROR in T();");
186 return NULL;
187 }
188 }
189
190 return tree;
191 }
192
193
194 SyntaxTree* Parser::F(){
195 SyntaxTree *tree = NULL;
196
197 if(currentToken.type == ID){
198 tree = new SyntaxTree(ID);
199 }else if(currentToken.type == NUM){
200 tree = new SyntaxTree(NUM, atoi(currentToken.name));
201 }else{
202 this->printError("ERROR! in F();");
203 }
204
205 this->nextToken();
206
207 return tree;
208 }
209
210 /*==================================================================*/
211
212 SyntaxTree* Parser::Boolean(){
213 TRACE("in Boolean();");
214
215 SyntaxTree *temp = NULL;
216 SyntaxTree *tree = T2();
217
218 if(tree == NULL){
219 return NULL;
220 }
221
222 while(currentToken.type == OR){
223 temp = new SyntaxTree(OR);
224 temp->addLeft(tree);
225 tree = temp;
226 this->nextToken();
227
228 temp = T2();
229 if(temp != NULL){
230 tree->addRight(temp);
231 }else{
232 this->printError("ERROR! behind OR;");
233 return NULL;
234 }
235 }
236
237 TRACE("out Boolean();");
238 return tree;
239 }
240
241
242 SyntaxTree* Parser::T2(){
243 SyntaxTree *temp = NULL;
244 SyntaxTree *tree = F2();
245
246 if(tree == NULL){
247 return NULL;
248 }
249
250 while(currentToken.type == AND){
251 temp = new SyntaxTree(AND);
252 temp->addLeft(tree);
253 tree = temp;
254 this->nextToken();
255
256 temp = F2();
257 if(temp != NULL){
258 tree->addRight(temp);
259 }else{
260 this->printError("ERROR! behind AND;");
261 return NULL;
262 }
263 }
264
265 return tree;
266 }
267
268
269 SyntaxTree* Parser::F2(){
270 SyntaxTree *temp = NULL;
271 SyntaxTree *tree = Expression();
272
273 if(tree == NULL){
274 return NULL;
275 }
276
277 switch(currentToken.type){
278 case LT:
279 temp = new SyntaxTree(LT);
280 break;
281 case GT:
282 temp = new SyntaxTree(GT);
283 break;
284 case EQ:
285 temp = new SyntaxTree(EQ);
286 break;
287 default :
288 break;
289 }
290
291 if(temp != NULL){
292 this->nextToken();
293 temp->addLeft(tree);
294 tree = temp;
295 temp = Expression();
296 if(temp != NULL){
297 tree->addRight(temp);
298 }else{
299 this->printError("ERROR! Relation Operator needs Expression behind;");
300 return NULL;
301 }
302 }
303
304 return tree;
305 }
306
307 /*==================================================================*/
308
309 SyntaxTree* Parser::While(){
310 TRACE("in While();");
311
312 SyntaxTree *tree = new SyntaxTree(WHILE);
313 SyntaxTree *temp = Boolean();
314
315 if(temp == NULL){
316 this->printError("ERROR! in While(); Condition NULL;");
317 return NULL;
318 }
319 tree->addLeft(temp);
320
321 if(currentToken.type != DO){
322 this->printError("ERROR! in While(); token.type!=DO;");
323 return NULL;
324 }
325 this->nextToken();
326 temp = Statement();
327
328 if(temp == NULL){
329 this->printError("ERROR! in While(); DO empty;");
330 return NULL;
331 }
332 tree->addRight(temp);
333
334 TRACE("out While();");
335 return tree;
336 }
337
338
339 /*==================================================================*/
340
341 SyntaxTree* Parser::Begin(){
342 return Block();
343 }
344
345 /*
346 L = S(;S)* | <empsilon>
347 */
348 SyntaxTree* Parser::Block(){
349 TRACE("in Block();");
350
351 SyntaxTree *tree = Statement();
352 SyntaxTree *temp = new SyntaxTree(BEGIN);
353
354 if(tree == NULL){
355 //this->printError("WARNNING! Don't accept empty block.");
356 return NULL;
357 /*
358 while(currentToken.type == SEMI){
359 this->nextToken();
360 }
361 return new SyntaxTree(BEGIN);
362 */
363 }
364 temp->addLeft(tree);
365 tree = temp;
366
367 // temp = L2();
368
369 while(currentToken.type == SEMI){
370 this->nextToken();
371 }
372 temp = Block();
373
374 if(temp != NULL){ // it couldn't be
375 if(temp->getLeft() != NULL)
376 tree->addRight(temp);
377 }
378
379 TRACE("out Block();");
380
381 if(tree == NULL)
382 return NULL;
383 if(tree->getRight() == NULL)
384 return tree->getLeft();
385 else
386 return tree;
387 }
388
389
390 /*==================================================================*/
391
392
393 SyntaxTree* Parser::Condition(){
394 TRACE("in Condition();");
395
396 SyntaxTree *tree = new SyntaxTree(IF);
397 SyntaxTree *temp = Boolean();
398 SyntaxTree *temp2 = NULL;
399
400 if(temp == NULL){
401 this->printError("ERROR! if without a boolean statement.");
402 return NULL;
403 }
404 tree->addLeft(temp);
405
406 if(currentToken.type != THEN){
407 this->printError("ERROR! if without then.");
408 return NULL;
409 }
410 this->nextToken();
411 temp = Statement();
412
413 if(temp == NULL){
414 this->printError("ERROR! then without a statement.");
415 return NULL;
416 }
417
418 temp2 = new SyntaxTree(THEN);
419 temp2->addLeft(temp);
420
421 //temp2 = temp;
422
423 this->nextToken();
424 if(currentToken.type == ELSE){
425 TRACE("ELSE");
426 this->nextToken();
427 //temp = new SyntaxTree(BEGIN);
428 //temp->addLeft(temp2);
429 //temp2 = temp;
430
431 temp = Statement();
432 if(temp == NULL){
433 this->printError("ERROR! else without a statement.");
434 return NULL;
435 }
436 temp2->addRight(temp);
437 }
438
439 tree->addRight(temp2);
440
441 TRACE("out Condition();");
442 return tree;
443 }
444
445
446
447