1 #ifndef GLRGRAMMAR 2 3 #define GLRGRAMMAR 4 5 #include <iostream> 6 #include <set> 7 #include <map> 8 #include <deque> 9 #include <cstdio> // for EOF 10 11 using namespace std; 12 13 #include <glr/glrException.h> 14 #include <glr/glrSymbolTable.h> 15 #include <glr/glrGuard.h> 16 #include <glr/glrNode.h> 17 18 /** @name glrRuleType 19 * 20 * Enumeration type for identifying the type of the grammar rule. The <tt>glrEpsilonRule</tt> 21 * identifyies the epsilon rule. The <tt>glrNonterminalRule</tt> is used for rules that have 22 * a nonterminal at the end of the right side. The <tt>glrPreterminalRule</tt> is used for 23 * rules that have (pre)terminal at the right side of the rule. 24 * 25 * @see glrRule 26 */ 27 typedef enum { 28 /** 29 * 30 * If the type of some rule is <tt>glrEpsilonRule</tt>, the rule has the right side empty. 31 */ 32 glrEpsilonRule, 33 34 /** 35 * 36 * If the type of some rule is the <tt>glrNonterminalRule</tt>, the rule has nonterminal 37 * at the end of the right side. 38 */ 39 glrNonterminalRule, 40 41 /** 42 * 43 * If the type os some grammar rule is <tt>glrPreterminalRule</tt>, the rule has preterminal 44 * at the end of the right side. 45 */ 46 glrPreterminalRule 47 } glrRuleType; 48 49 50 /** 51 * 52 * Type for storing the right side of the grammar rule. 53 * 54 * @see glrRule 55 */ 56 typedef vector<glrSymbolTable::glrSymbol> glrRuleRight; 57 58 /* 59 class glrReductionHint { 60 private: 61 set<class glrNode*> packedNodes; 62 class glrNode* ownParent; 63 public: 64 void setOwnParent(class glrNode* const& ownParentA){ 65 66 if(ownParent){ 67 throw glrLostOwnParentException("void glrReductionHint::setOwnParent(class glrNode* const& ownParentA): \ 68 call of this function while ownParent not NULL"); 69 } 70 // if(ownParent)((glrGuard*)(ownParent))->release(); 71 ownParent = ownParentA; 72 if(ownParent) packedNodes.insert(ownParent); 73 74 } 75 class glrNode* const& getOwnParent(){ 76 return ownParent; 77 } 78 bool packedNodes_add(class glrNode* const& node){ 79 pair<set<class glrNode*>::iterator,bool> p = packedNodes.insert(node); 80 return p.second; 81 } 82 glrReductionHint(){ 83 ownParent = NULL; 84 } 85 ~glrReductionHint(){ 86 if(ownParent)((glrGuard*)(ownParent))->release(); 87 } 88 set<class glrNode*> &getPackedNodes(){ 89 return packedNodes; 90 } 91 }; 92 93 class glrParseTimeRuleState { 94 private: 95 int iToken; 96 map<deque<class glrNode*>,glrReductionHint> reductions; 97 class glrNode* epsilonNode; 98 public: 99 void reset(){ 100 iToken = 0; 101 reductions.clear(); 102 if(epsilonNode)((glrGuard*)epsilonNode)->release(); 103 epsilonNode = NULL; 104 } 105 glrReductionHint& getReductionHint(const deque<class glrNode*> &subtree,int const& iTokenA) { 106 // if(iToken!=iTokenA){ 107 // iToken = iTokenA; 108 // reductions.clear(); 109 // } 110 return reductions[subtree]; 111 } 112 113 class glrNode *getEpsilonHint(const int& iTokenA){ 114 // if(iToken!=iTokenA){ 115 // iToken = iTokenA; 116 // ((glrGuard*)epsilonNode)->release(); 117 // epsilonNode = NULL; 118 // } 119 return epsilonNode; 120 } 121 122 void setEpsilonHint(class glrNode* const &epsilonNodeA){ 123 epsilonNode = epsilonNodeA; 124 } 125 126 glrParseTimeRuleState(){ 127 epsilonNode = NULL; 128 } 129 };*/ 130 131 /** 132 * 133 * Class which used to represent the grammar rule. Note that you may want to derive this class 134 * to store any other values associated with the rule. Of course then you have to 135 * derive also the <tt>glrGrammar</tt> class and override its <tt>read</tt> function to store 136 * rules of your own type in the grammar. 137 * 138 * @see glrGrammar 139 */ 140 class glrRule { 141 private: 142 glrRuleType type; 143 int number; 144 glrSymbolTable::glrSymbol left; 145 glrRuleRight right; 146 // glrParseTimeRuleState *ruleState; 147 int nodeToken; 148 void *epsilonNode; 149 public: 150 getEpsilonNode(const int & nodeTokenA)151 void* getEpsilonNode(const int &nodeTokenA) const { 152 if (nodeToken==nodeTokenA) return epsilonNode; 153 else return NULL; 154 } 155 setEpsilonNode(int const & nodeTokenA,void * const & epsilonNodeA)156 void setEpsilonNode(int const& nodeTokenA, void* const& epsilonNodeA){ 157 nodeToken = nodeTokenA; 158 epsilonNode = epsilonNodeA; 159 } 160 161 /* 162 glrReductionHint& getReductionHint(const deque<class glrNode*> &subtree,int const& iTokenA) const { 163 return ruleState->getReductionHint(subtree,iTokenA); 164 } 165 166 void resetRuleState() const { 167 ruleState->reset(); 168 } 169 170 void setEpsilonHint(class glrNode* const &epsilonNodeA) const { 171 ruleState->setEpsilonHint(epsilonNodeA); 172 } 173 174 class glrNode *getEpsilonHint(const int& iTokenA) const { 175 return ruleState->getEpsilonHint(iTokenA); 176 } 177 */ 178 179 /** 180 * 181 * The function <tt>getNumber()</tt> returns the number of the grammar rule. 182 * Note that the rule number 0 has special sense in the grammar. 183 * It is the only rule which can be at the top of all derivation trees found by the parser. 184 * 185 * @see glrGrammar 186 */ getNumber()187 const int &getNumber() const { 188 return number; 189 } 190 191 /** 192 * 193 * The function <tt>getType()</tt> returns the type of the grammar rule. It can be either <tt>glrEpsilonRule</tt> for epsilon 194 * rules, <tt>glrNonterminalRule</tt> for rules which has at the end of right side nonterminal 195 * and the <tt>glrPreterminalRule</tt> for rules which end with preterminal. 196 * 197 * @see glrRuleType 198 */ getType()199 const glrRuleType &getType() const { 200 return type; 201 } 202 203 /** 204 * 205 * The function pushes the symbol <tt>symbol</tt> to the right side of the rule. 206 * Argument <tt>symbols</tt> is parser's symbol table. 207 * 208 * @see glrSymbolTable::glrSymbol 209 * @see glrSymbolTable 210 * @see glrParser 211 */ pushRight(const glrSymbolTable & symbols,const glrSymbolTable::glrSymbol & symbol)212 void pushRight(const glrSymbolTable &symbols,const glrSymbolTable::glrSymbol &symbol){ 213 right.push_back(symbol); 214 type=(symbols.getSymbolType(symbol)==glrSymbolTable::glrPreterminal)?glrPreterminalRule:glrNonterminalRule; 215 } 216 217 /** 218 * 219 * The function adds the symbol specified by the <tt>charSymbol</tt> argument to 220 * the <tt>symbols</tt> symbol table (if there is not already such) and pushes 221 * appropriate value of type <tt>glrSymbolTable::glrSymbol</tt> to the right side of the rule. 222 * 223 * @see glrSymbolTable::glrSymbol 224 * @see glrSymbolTable 225 * @see glrParser 226 */ pushRight(glrSymbolTable & symbols,const char * const & charSymbol)227 void pushRight(glrSymbolTable &symbols,const char* const &charSymbol){ 228 const glrSymbolTable::glrSymbol &symbol=symbols.addTextSymbol(charSymbol); 229 right.push_back(symbol); 230 type=(symbols.getSymbolType(symbol)==glrSymbolTable::glrPreterminal)?glrPreterminalRule:glrNonterminalRule; 231 } 232 233 /** 234 * 235 * The function adds the symbol specified by the <tt>stringSymbol</tt> argument to 236 * the <tt>symbols</tt> symbol table (if there is not already such) and pushes 237 * appropriate value of type <tt>glrSymbolTable::glrSymbol</tt> to the right side of the rule. 238 * 239 * @see glrSymbolTable::glrSymbol 240 * @see glrSymbolTable 241 * @see glrParser 242 */ pushRight(glrSymbolTable & symbols,const string & stringSymbol)243 void pushRight(glrSymbolTable &symbols,const string &stringSymbol){ 244 const glrSymbolTable::glrSymbol &symbol=symbols.addTextSymbol(stringSymbol); 245 right.push_back(symbol); 246 type=(symbols.getSymbolType(symbol)==glrSymbolTable::glrPreterminal)?glrPreterminalRule:glrNonterminalRule; 247 } 248 249 /** 250 * 251 * The function prints the rule in the the format <tt>LEFT -> RIGHT_1 RIGHT_2 ... RIGHT_N</tt>. 252 * The delimiter is space. The <tt>symbols</tt> argument is the parser's symbol table and 253 * the <tt>output</tt> specifies where to print. 254 * 255 * @see glrSymbolTable 256 */ print(const glrSymbolTable & symbols,ostream & output)257 virtual void print(const glrSymbolTable &symbols,ostream &output) const { 258 if(!(output << symbols.getStringFromSymbol(left) << " ->")){ 259 throw glrIOErrorException("void glrRule::print(const glrSymbolTable &symbols,ostream &output) const: can't write to output"); 260 } 261 for(glrRuleRight::const_iterator i=right.begin();i!=right.end();++i){ 262 if(!(output << " " << symbols.getStringFromSymbol(*i))){ 263 throw glrIOErrorException("void glrRule::print(const glrSymbolTable &symbols,ostream &output) const: can't write to output"); 264 } 265 } 266 } 267 268 /** 269 * 270 * The function returns the constant reference to the symbol at the end of the right side of 271 * the rule. 272 * 273 * @see glrSymbolTable::glrSymbol 274 * @see glrSymbolTable 275 */ right_back()276 const glrSymbolTable::glrSymbol &right_back() const { 277 #ifdef DEBUGEXCEPTIONS 278 if(right.empty()){ 279 throw glrEmptyContainerException("const glrSymbolTable::glrSymbol& glrRule::right_back() const: right side of the rule is empty"); 280 } 281 #endif 282 return right.back(); 283 } 284 285 /** 286 * 287 * The function returns the size of the right side of the rule. 288 * 289 */ right_size()290 int right_size() const { 291 return right.size(); 292 } 293 294 /** 295 * 296 * The function returns constant reference to the symbol at the position <tt>pos</tt> 297 * at the right size of the rule. 298 * 299 * @see glrSymbolTable::glrSymbol 300 * @see glrSymbolTable 301 */ right_at(const int & pos)302 const glrSymbolTable::glrSymbol &right_at(const int &pos) const { 303 #ifdef DEBUGEXCEPTIONS 304 if((pos<0)||(pos>=right.size())){ 305 throw glrIndexOutOfBoundsException("const glrSymbolTable::glrSymbol& glrRule::right_at(const int &pos) const: index out of bounds"); 306 } 307 #endif 308 return right[pos]; 309 } 310 311 /** 312 * 313 * The function returns the iterator to the begin of the right side of the rule. 314 * You can use it in the cooperation with the <tt>right_end()</tt> function 315 * to iterate over all symbols of the right side of the rule. 316 * 317 * @see glrRuleRight 318 * @see glrRule::right_end 319 */ right_begin()320 glrRuleRight::const_iterator right_begin() const { 321 return right.begin(); 322 } 323 324 /** 325 * 326 * Function returns iterator to the end of the right side of the rule. 327 * 328 * @see glrRuleRight 329 * @see glrRule::right_begin 330 */ right_end()331 glrRuleRight::const_iterator right_end() const { 332 return right.end(); 333 } 334 335 /** 336 * 337 * The function returns the iterator to the begin of the reversed right 338 * side of the rule. 339 * 340 */ right_rbegin()341 glrRuleRight::const_reverse_iterator right_rbegin() const { 342 return right.rbegin(); 343 } 344 345 /** 346 * 347 * The function returns the iterator to the end of the reversed right side 348 * of the rule. 349 * 350 * @see glrRuleRight 351 * @see glrRule::right_rbegin 352 */ right_rend()353 glrRuleRight::const_reverse_iterator right_rend() const { 354 return right.rend(); 355 } 356 357 /** 358 * 359 * Function returns constant reference to the symbol at the left side of the rule. 360 * 361 * @see glrSymbolTable::glrSymbol 362 * @see glrSymbolTable 363 */ getLeft()364 const glrSymbolTable::glrSymbol &getLeft() const { 365 return left; 366 } 367 368 /** 369 * 370 * Constructor. <tt>numberA</tt> is the number of the rule and <tt>leftA</tt> is the symbol at the left side of the rule. 371 * 372 */ glrRule(const int & numberA,const glrSymbolTable::glrSymbol & leftA)373 glrRule(const int &numberA,const glrSymbolTable::glrSymbol &leftA){ 374 left=leftA; 375 number=numberA; 376 type=glrEpsilonRule; 377 //ruleState = new glrParseTimeRuleState(); 378 } 379 ~glrRule()380 virtual ~glrRule(){ 381 //delete ruleState; 382 } 383 384 }; 385 386 /** 387 * 388 * Class <tt>glrCompRule</tt> is used internally by the parser during the glr table computation. 389 * 390 */ 391 class glrCompRule { 392 private: 393 /** 394 * 395 * <tt>symbolTypes</tt> are types of symbols at the right side of rule <tt>rule</tt>. 396 * 397 */ 398 vector<glrSymbolTable::glrSymbolType> symbolTypes; 399 public: 400 /** 401 * 402 * <tt>rule</tt> is constant pointer to associated rule. 403 * 404 */ 405 const glrRule *rule; 406 symbolType_at(const int & pos)407 const glrSymbolTable::glrSymbolType& symbolType_at(const int &pos) const { 408 #ifdef DEBUGEXCEPTIONS 409 if((pos<0)||(pos>=symbolTypes.size())){ 410 throw glrIndexOutOfBoundsException("const glrSymbolTable::glrSymbolType& glrCompRule::symbolType_at(const int &pos) const: index out of bounds"); 411 } 412 #endif 413 return symbolTypes[pos]; 414 } 415 symbolTypes_back()416 const glrSymbolTable::glrSymbolType& symbolTypes_back() const { 417 #ifdef DEBUGEXCEPTIONS 418 if(symbolTypes.empty()){ 419 throw glrEmptyContainerException("const glrSymbolTable::glrSymbolType& glrCompRule::symbolTypes_back() const: symbol types container is empty"); 420 } 421 #endif 422 return symbolTypes.back(); 423 } 424 425 /** 426 * 427 * Constructor. <tt>symbols</tt> is the parser's symbol table and <tt>ruleA</tt> is the rule 428 * asociated with newly created object. 429 * 430 */ glrCompRule(const glrSymbolTable & symbols,const glrRule * ruleA)431 glrCompRule(const glrSymbolTable &symbols,const glrRule *ruleA){ 432 rule=ruleA; 433 for(glrRuleRight::const_iterator sym=rule->right_begin();sym!=rule->right_end();++sym){ 434 symbolTypes.push_back(symbols.getSymbolType(*sym)); 435 } 436 } 437 438 }; 439 440 /** 441 * 442 * Class <tt>glrGrammarMap</tt> is used internally by the parser during the glr table 443 * computation. It stores vector of pointers to objects of type <tt>glrCompRule</tt> at the position 444 * returned by the <tt>(int)</tt> cast operation applyed to the symbol at the left sides 445 * of stored rules. 446 * 447 * @see glrCompRule 448 */ 449 class glrGrammarMap : public vector<vector<glrCompRule*> >{ 450 public: 451 /** 452 * 453 * Function dealocates all objects of stored pointers and clears the map. 454 * 455 */ releaseCompRules()456 void releaseCompRules(){ 457 for(glrGrammarMap::iterator i=begin();i!=end();++i) 458 for(vector<glrCompRule*>::iterator j=i->begin();j!=i->end();++j) 459 delete (*j); 460 clear(); 461 } 462 }; 463 464 /** 465 * 466 * Class <tt>glrGrammar</tt> is used by the parser to store grammar. You may want to derive it 467 * to override virtual function read and print to handle different format of grammar files. 468 * Other purpuse may be also to store rules in object of type of your own class derived from 469 * glrGrammarRule class. 470 * 471 * @see glrRule 472 */ 473 class glrGrammar { 474 public: 475 476 /** 477 * 478 * <tt>glrRulesContainer</tt> is the container which is used by the <tt>glrGrammar</tt> class 479 * to store pointers to the grammar rules. 480 * 481 */ 482 typedef vector<glrRule*> glrRulesContainer; 483 private: 484 glrRulesContainer rules; 485 unsigned int maxRuleLength; 486 vector<glrRule*> epsilonRules; 487 public: 488 489 /** 490 * 491 * Function <tt>prepareGrammar</tt> prepares the grammar for parsing. It is automaticaly 492 * called at the end of the <tt>read</tt> function. If you are initializing the grammar 493 * by your own way, you should call this function after last grammar modification before 494 * parsing. 495 */ prepareGrammar()496 void prepareGrammar() { 497 maxRuleLength = 0; 498 epsilonRules.clear(); 499 for(glrRulesContainer::iterator i = rules.begin(); i!=rules.end(); ++i){ 500 if(maxRuleLength<(*i)->right_size()){ 501 maxRuleLength = (*i)->right_size(); 502 } 503 if((*i)->getType()==glrEpsilonRule){ 504 epsilonRules.push_back(*i); 505 } 506 } 507 } 508 509 /** 510 * 511 * The <tt>resetEpsilonRules</tt> function is called by the parser to reset informations 512 * stored in epsilon rules temporarly during parsing. 513 */ resetEpsilonRules()514 void resetEpsilonRules(){ 515 for(vector<glrRule*>::iterator i = epsilonRules.begin(); i!=epsilonRules.end(); ++i){ 516 (*i)->setEpsilonNode(-1, NULL); 517 } 518 } 519 getMaxRuleLength()520 virtual unsigned int const& getMaxRuleLength() const { 521 return maxRuleLength; 522 } 523 524 /* 525 void resetParseTimeRuleStates(){ 526 for(glrRulesContainer::iterator i = rules.begin(); i!=rules.end(); ++i){ 527 (*i)->resetRuleState(); 528 } 529 } 530 */ 531 532 /** 533 * 534 * Function <tt>addRule</tt> adds the rule <tt>newRule</tt> to the grammar. 535 * 536 */ addRule(glrRule * const & newRule)537 void addRule(glrRule* const &newRule){ 538 if(maxRuleLength<newRule->right_size()){ 539 maxRuleLength = newRule->right_size(); 540 } 541 if(newRule->getNumber()>=rules.size()){ 542 rules.resize(newRule->getNumber()+1); 543 } 544 rules[newRule->getNumber()]=newRule; 545 } 546 547 /** 548 * 549 * Function <tt>getRule</tt> returns the pointer to rule which number is <tt>ruleNo</tt>. 550 * 551 */ getRule(const int & ruleNo)552 const glrRule* getRule(const int &ruleNo) const { 553 #ifdef DEBUGEXCEPTIONS 554 if((ruleNo<0)||(ruleNo>=rules.size())){ 555 throw glrIndexOutOfBoundsException("const glrRule* glrGrammar::getRule(const int &ruleNo) const: index ruleNo out of bounds"); 556 } 557 #endif 558 return rules[ruleNo]; 559 } 560 561 /** 562 * 563 * Function <tt>print</tt> simply prints all rules to <tt>output</tt> by calling 564 * function <tt>print</tt> for each rule. <tt>symbols</tt> is the parser's symbol table. 565 * 566 */ print(const glrSymbolTable & symbols,ostream & output)567 virtual void print(const glrSymbolTable &symbols,ostream &output) const { 568 for(glrRulesContainer::const_iterator i=rules.begin();i!=rules.end();++i){ 569 (*i)->print(symbols,output); 570 if(!(output << endl)){ 571 throw glrIOErrorException("void glrGrammar:: print(const glrSymbolTable &symbols,ostream &output) const: can't write to output stream"); 572 } 573 } 574 } 575 576 /** 577 * 578 * Function <tt>size</tt> returns the number of rules in the grammar. 579 * 580 */ size()581 int size() const { 582 return rules.size(); 583 } 584 585 /** 586 * 587 * Function <tt>initGrammarMap</tt> initializes the object <tt>grammarMap</tt> from the grammar. 588 * <tt>symbols</tt> is the parser's symbol table. 589 * 590 */ initGrammarMap(const glrSymbolTable & symbols,glrGrammarMap & grammarMap)591 glrCompRule *initGrammarMap(const glrSymbolTable &symbols,glrGrammarMap &grammarMap) const { 592 grammarMap.resize(symbols.size()); 593 glrCompRule *ret = NULL; 594 for(glrRulesContainer::const_iterator iRule=rules.begin();iRule!=rules.end();++iRule){ 595 if(*iRule){ 596 glrCompRule *newCompRule=new glrCompRule(symbols,*iRule); 597 if((*iRule)->getNumber()==0)ret=newCompRule; 598 grammarMap[(*iRule)->getLeft()].push_back(newCompRule); 599 } 600 } 601 return ret; 602 } 603 glrGrammar()604 glrGrammar(){ 605 maxRuleLength = 0; 606 } 607 608 /** 609 * 610 * Destructor dealocates all stored rules. 611 * 612 */ ~glrGrammar()613 virtual ~glrGrammar(){ 614 for(glrRulesContainer::iterator i=rules.begin();i!=rules.end();++i){ 615 if(*i)delete (*i); 616 } 617 } 618 619 /** 620 * 621 * Function reads grammar from file. Each rule in the file have to be on 622 * its own line. Format of the line is same as output of <tt>glrRule::print</tt> function. 623 * <tt>istream</tt> is input. <tt>symbols</tt> is the parsers table of symbols. 624 * 625 * @see glrRule::print 626 */ read(glrSymbolTable & symbols,istream & input)627 virtual void read(glrSymbolTable &symbols, istream &input){ 628 int lineNo = 1; 629 int state = 1; 630 int ruleCount = 0; 631 string leftSymbol; 632 string token; 633 glrRule *newRule = NULL; 634 while(state){ 635 int c = input.get(); 636 switch(state){ 637 case 1: 638 if(((c>='a')&&(c<='z'))||((c>='A')&&(c<='Z'))){ 639 leftSymbol = c; 640 state = 2; 641 }else if((c==' ')||(c=='\t')||(c=='\n')){ 642 if(c=='\n')lineNo++; 643 }else if(c==EOF){ 644 state = 0; 645 }else if(c=='#'){ 646 state = 3; 647 }else if(c=='\''){ 648 state = 20; 649 }else{ 650 state = -1; 651 } 652 break; 653 case 20: 654 if((c>=32)&&(c!='\'')){ 655 leftSymbol = c; 656 state = 21; 657 }else{ 658 state = -1; 659 } 660 break; 661 case 21: 662 if((c>=32)&&(c!='\'')){ 663 leftSymbol += c; 664 }else if(c=='\''){ 665 state = 22; 666 }else{ 667 state = -1; 668 } 669 break; 670 case 22: 671 if((c==' ')||(c=='\t')){ 672 state = 23; 673 }else{ 674 state = -1; 675 } 676 break; 677 case 23: 678 if((c==' ')||(c=='\t')){ 679 }else if(c=='-'){ 680 state = 5; 681 }else{ 682 state = -1; 683 } 684 break; 685 case 2: 686 if(((c>='a')&&(c<='z'))||((c>='A')&&(c<='Z'))||(c=='-')||(c=='_')||((c>='0')&&(c<='9'))){ 687 leftSymbol += c; 688 }else if((c==':')||(c=='(')){ 689 state = 3; 690 }else if((c==' ')||(c=='\t')){ 691 state = 4; 692 }else{ 693 state = -1; 694 } 695 break; 696 case 3: 697 if((c=='\n')||(c==EOF)){ 698 state = 1; 699 lineNo++; 700 } 701 break; 702 case 4: 703 if(c=='('){ 704 state = 3; 705 }else if((c==' ')||(c=='\t')){ 706 }else if(c=='-'){ 707 state = 5; 708 }else{ 709 state = -1; 710 } 711 break; 712 case 5: 713 if(c=='>'){ 714 addRule(newRule = new glrRule(ruleCount++,symbols.addTextSymbol(leftSymbol))); 715 state = 6; 716 }else{ 717 state = -1; 718 } 719 break; 720 case 6: 721 if((c==' ')||(c=='\t')){ 722 state = 7; 723 }else if((c=='\n')||(c==EOF)){ 724 lineNo++; 725 newRule = NULL; 726 state = 1; 727 }else{ 728 state = -1; 729 } 730 break; 731 case 7: 732 if((c==' ')||(c=='\t')){ 733 }else if((c=='\n')||(c==EOF)){ 734 ++lineNo; 735 newRule = NULL; 736 state = 1; 737 }else if(c=='+'){ 738 state = 8; 739 }else if(((c>='a')&&(c<='z'))||((c>='A')&&(c<='Z'))){ 740 token = c; 741 state = 9; 742 }else if(c=='\''){ 743 state = 24; 744 }else{ 745 state = -1; 746 } 747 break; 748 case 24: 749 if((c>=32)&&(c!='\'')){ 750 state = 25; 751 token = c; 752 }else{ 753 state = -1; 754 } 755 break; 756 case 25: 757 if((c>=32)&&(c!='\'')){ 758 token += c; 759 }else if(c=='\''){ 760 newRule->pushRight(symbols,token); 761 state = 26; 762 }else{ 763 state = -1; 764 } 765 break; 766 case 26: 767 if((c==' ')||(c=='\t')){ 768 state = 11; 769 }else if((c=='\n')||(c=EOF)){ 770 state = 1; 771 newRule = NULL; 772 lineNo++; 773 }else{ 774 state = -1; 775 } 776 break; 777 case 8: 778 if((c>='0')||(c<='9')){ 779 state = 10; 780 }else{ 781 state = -1; 782 } 783 break; 784 case 9: 785 if(((c>='a')&&(c<='z'))||((c>='A')&&(c<='Z'))||((c>='0')&&(c<='9'))||(c=='-')||(c=='_')){ 786 token += c; 787 }else if((c==' ')||(c=='\t')){ 788 newRule->pushRight(symbols,token); 789 state = 11; 790 }else if((c=='\n')||(c==EOF)){ 791 newRule->pushRight(symbols,token); 792 newRule = NULL; 793 lineNo++; 794 state = 1; 795 }else{ 796 state = -1; 797 } 798 break; 799 case 10: 800 if((c>='0')&&(c<='9')){ 801 }else if(c=='.'){ 802 state = 12; 803 }else if((c=='\n')||(c==EOF)){ 804 state = 1; 805 newRule = NULL; 806 lineNo++; 807 }else if((c==' ')||(c=='\t')){ 808 state = 16; 809 }else{ 810 state = -1; 811 } 812 break; 813 case 11: 814 if((c==' ')||(c=='\t')){ 815 }else if(((c>='a')&&(c<='z'))||((c>='A')&&(c<='Z'))){ 816 token = c; 817 state = 9; 818 }else if((c=='\n')||(c==EOF)){ 819 newRule = NULL; 820 lineNo++; 821 state = 1; 822 }else if(c=='+'){ 823 state = 13; 824 }else if(c=='\''){ 825 state = 24; 826 }else{ 827 state = -1; 828 } 829 break; 830 case 12: 831 if((c>='0')&&(c<='9')){ 832 state = 14; 833 }else{ 834 state = -1; 835 } 836 break; 837 case 13: 838 if((c>='0')&&(c<='9')){ 839 state = 15; 840 }else{ 841 state = -1; 842 } 843 break; 844 case 14: 845 if((c>='0')&&(c<='9')){ 846 }else if((c==' ')||(c=='\t')){ 847 state = 16; 848 }else if((c=='\n')||(c==EOF)){ 849 state = 1; 850 newRule = NULL; 851 lineNo++; 852 }else{ 853 state = -1; 854 } 855 break; 856 case 15: 857 if((c>='0')&&(c<='9')){ 858 }else if(c=='.'){ 859 state = 17; 860 }else if((c=='\n')||(c==EOF)){ 861 state = 1; 862 newRule = NULL; 863 lineNo++; 864 }else if((c=' ')||(c='\t')){ 865 state = 19; 866 }else{ 867 state = -1; 868 } 869 break; 870 case 16: 871 if((c==' ')||(c=='\t')){ 872 }else if((c=='\n')||(c==EOF)){ 873 newRule = NULL; 874 lineNo++; 875 state = 1; 876 }else{ 877 state = -1; 878 } 879 break; 880 case 17: 881 if((c>='0')&&(c<='9')){ 882 state = 18; 883 }else{ 884 state = -1; 885 } 886 break; 887 case 18: 888 if((c>='0')&&(c<='9')){ 889 }else if((c==' ')||(c=='\t')){ 890 state = 19; 891 }else if((c=='\n')||(c==EOF)){ 892 state = 1; 893 newRule = NULL; 894 lineNo++; 895 }else{ 896 state = -1; 897 } 898 break; 899 case 19: 900 if((c==' ')||(c=='\t')){ 901 }else if((c=='\n')||(c==EOF)){ 902 state = 1; 903 lineNo++; 904 newRule = NULL; 905 }else{ 906 state = -1; 907 } 908 break; 909 case -1: 910 throw glrSyntaxErrorException("void glrGrammar::read(glrSymbolTable &symbols, istream &input): syntax error in grammar at line ",lineNo); 911 default: 912 throw glrIOErrorException("void glrGrammar::read(glrSymbolTable &symbols, istream &input): grammar reader came to undefined state"); 913 } 914 } 915 prepareGrammar(); 916 } 917 }; 918 919 #endif 920