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