parser.cpp

Go to the documentation of this file.
00001 // Generated by Bisonc++ V2.4.2 on Sat Jul 26 23:16:51 2008 +0100
00002 
00003 // $insert class.ih
00004 #include "parser.ih"
00005 
00006 // The FIRST element of SR arrays shown below uses `d_type', defining the
00007 // state's type, and `d_lastIdx' containing the last element's index. If
00008 // d_lastIdx contains the REQ_TOKEN bitflag (see below) then the state needs
00009 // a token: if in this state d_token__ is _UNDETERMINED_, nextToken() will be
00010 // called
00011 
00012 // The LAST element of SR arrays uses `d_token' containing the last retrieved
00013 // token to speed up the (linear) seach.  Except for the first element of SR
00014 // arrays, the field `d_action' is used to determine what to do next. If
00015 // positive, it represents the next state (used with SHIFT); if zero, it
00016 // indicates `ACCEPT', if negative, -d_action represents the number of the
00017 // rule to reduce to.
00018 
00019 // `lookup()' tries to find d_token__ in the current SR array. If it fails, and
00020 // there is no default reduction UNEXPECTED_TOKEN__ is thrown, which is then
00021 // caught by the error-recovery function.
00022 
00023 // The error-recovery function will pop elements off the stack until a state
00024 // having bit flag ERR_ITEM is found. This state has a transition on _error_
00025 // which is applied. In this _error_ state, while the current token is not a
00026 // proper continuation, new tokens are obtained by nextToken(). If such a
00027 // token is found, error recovery is successful and the token is
00028 // handled according to the error state's SR table and parsing continues.
00029 // During error recovery semantic actions are ignored.
00030 
00031 // A state flagged with the DEF_RED flag will perform a default
00032 // reduction if no other continuations are available for the current token.
00033 
00034 // The ACCEPT STATE never shows a default reduction: when it is reached the
00035 // parser returns ACCEPT(). During the grammar
00036 // analysis phase a default reduction may have been defined, but it is
00037 // removed during the state-definition phase.
00038 
00039 // So:
00040 //      s_x[] = 
00041 //      {
00042 //                  [_field_1_]         [_field_2_]
00043 //
00044 // First element:   {state-type,        idx of last element},
00045 // Other elements:  {required token,    action to perform},
00046 //                                      ( < 0: reduce, 
00047 //                                          0: ACCEPT,
00048 //                                        > 0: next state)
00049 // Last element:    {set to d_token__,    action to perform}
00050 //      }
00051 
00052 // When the --thread-safe option is specified, all static data are defined as
00053 // const. If --thread-safe is not provided, the state-tables are not defined
00054 // as const, since the lookup() function below will modify them
00055 
00056 // $insert debugincludes
00057 #include <iostream>
00058 #include <sstream>
00059 #include <string>
00060 #include <map>
00061 #include <iomanip>
00062 
00063 namespace // anonymous
00064 {
00065     char const author[] = "Frank B. Brokken (f.b.brokken@rug.nl)";
00066 
00067     enum 
00068     {
00069         STACK_EXPANSION = 5     // size to expand the state-stack with when
00070                                 // full
00071     };
00072 
00073     enum ReservedTokens
00074     {
00075         PARSE_ACCEPT     = 0,   // `ACCEPT' TRANSITION
00076         _UNDETERMINED_   = -2,
00077         _EOF_            = -1,
00078         _error_          = 256
00079     };
00080     enum StateType       // modify statetype/data.cc when this enum changes
00081     {
00082         NORMAL,
00083         ERR_ITEM,
00084         REQ_TOKEN,
00085         ERR_REQ,    // ERR_ITEM | REQ_TOKEN
00086         DEF_RED,    // state having default reduction
00087         ERR_DEF,    // ERR_ITEM | DEF_RED
00088         REQ_DEF,    // REQ_TOKEN | DEF_RED
00089         ERR_REQ_DEF // ERR_ITEM | REQ_TOKEN | DEF_RED
00090     };    
00091     struct PI__     // Production Info
00092     {
00093         size_t d_nonTerm; // identification number of this production's
00094                             // non-terminal 
00095         size_t d_size;    // number of elements in this production 
00096     };
00097 
00098     struct SR__     // Shift Reduce info, see its description above
00099     {
00100         union
00101         {
00102             int _field_1_;      // initializer, allowing initializations 
00103                                 // of the SR s_[] arrays
00104             int d_type;
00105             int d_token;
00106         };
00107         union
00108         {
00109             int _field_2_;
00110 
00111             int d_lastIdx;          // if negative, the state uses SHIFT
00112             int d_action;           // may be negative (reduce), 
00113                                     // postive (shift), or 0 (accept)
00114             size_t d_errorState;    // used with Error states
00115         };
00116     };
00117 
00118     // $insert staticdata
00119     
00120 // Productions Info Records:
00121 PI__ const s_productionInfo[] = 
00122 {
00123      {0, 0}, // not used: reduction values are negative
00124      {260, 1}, // 1: asctextfile ->  blocks
00125      {261, 1}, // 2: blocks ->  block
00126      {261, 2}, // 3: blocks ->  blocks block
00127      {262, 1}, // 4: block ->  testblock
00128      {263, 5}, // 5: testblock ->  TESTCASE '{' commands '}' TESTCASE
00129      {264, 2}, // 6: commands ->  command ';'
00130      {264, 2}, // 7: commands ->  commands command
00131      {265, 1}, // 8: command ->  MOVEUNIT
00132      {265, 1}, // 9: command ->  loadmapcommand
00133      {266, 4}, // 10: loadmapcommand ->  LOADMAP '(' filename ')'
00134      {267, 0}, // 11: filename ->  <empty>
00135      {268, 1}, // 12: asctextfile_$ ->  asctextfile
00136 };
00137 
00138 // State info and SR__ transitions for each state.
00139 
00140 
00141 SR__ const s_0[] =
00142 {
00143     { { REQ_TOKEN}, { 6} },               
00144     { {       260}, { 1} }, // asctextfile
00145     { {       261}, { 2} }, // blocks     
00146     { {       262}, { 3} }, // block      
00147     { {       263}, { 4} }, // testblock  
00148     { {       259}, { 5} }, // TESTCASE   
00149     { {         0}, { 0} },               
00150 };
00151 
00152 SR__ const s_1[] =
00153 {
00154     { { REQ_TOKEN}, {            2} }, 
00155     { {     _EOF_}, { PARSE_ACCEPT} }, 
00156     { {         0}, {            0} }, 
00157 };
00158 
00159 SR__ const s_2[] =
00160 {
00161     { { REQ_DEF}, {  4} },             
00162     { {     262}, {  6} }, // block    
00163     { {     263}, {  4} }, // testblock
00164     { {     259}, {  5} }, // TESTCASE 
00165     { {       0}, { -1} },             
00166 };
00167 
00168 SR__ const s_3[] =
00169 {
00170     { { DEF_RED}, {  1} }, 
00171     { {       0}, { -2} }, 
00172 };
00173 
00174 SR__ const s_4[] =
00175 {
00176     { { DEF_RED}, {  1} }, 
00177     { {       0}, { -4} }, 
00178 };
00179 
00180 SR__ const s_5[] =
00181 {
00182     { { REQ_TOKEN}, { 2} },       
00183     { {       123}, { 7} }, // '{'
00184     { {         0}, { 0} },       
00185 };
00186 
00187 SR__ const s_6[] =
00188 {
00189     { { DEF_RED}, {  1} }, 
00190     { {       0}, { -3} }, 
00191 };
00192 
00193 SR__ const s_7[] =
00194 {
00195     { { REQ_TOKEN}, {  6} },                  
00196     { {       264}, {  8} }, // commands      
00197     { {       265}, {  9} }, // command       
00198     { {       257}, { 10} }, // MOVEUNIT      
00199     { {       266}, { 11} }, // loadmapcommand
00200     { {       258}, { 12} }, // LOADMAP       
00201     { {         0}, {  0} },                  
00202 };
00203 
00204 SR__ const s_8[] =
00205 {
00206     { { REQ_TOKEN}, {  6} },                  
00207     { {       125}, { 13} }, // '}'           
00208     { {       265}, { 14} }, // command       
00209     { {       257}, { 10} }, // MOVEUNIT      
00210     { {       266}, { 11} }, // loadmapcommand
00211     { {       258}, { 12} }, // LOADMAP       
00212     { {         0}, {  0} },                  
00213 };
00214 
00215 SR__ const s_9[] =
00216 {
00217     { { REQ_TOKEN}, {  2} },       
00218     { {        59}, { 15} }, // ';'
00219     { {         0}, {  0} },       
00220 };
00221 
00222 SR__ const s_10[] =
00223 {
00224     { { DEF_RED}, {  1} }, 
00225     { {       0}, { -8} }, 
00226 };
00227 
00228 SR__ const s_11[] =
00229 {
00230     { { DEF_RED}, {  1} }, 
00231     { {       0}, { -9} }, 
00232 };
00233 
00234 SR__ const s_12[] =
00235 {
00236     { { REQ_TOKEN}, {  2} },       
00237     { {        40}, { 16} }, // '('
00238     { {         0}, {  0} },       
00239 };
00240 
00241 SR__ const s_13[] =
00242 {
00243     { { REQ_TOKEN}, {  2} },            
00244     { {       259}, { 17} }, // TESTCASE
00245     { {         0}, {  0} },            
00246 };
00247 
00248 SR__ const s_14[] =
00249 {
00250     { { DEF_RED}, {  1} }, 
00251     { {       0}, { -7} }, 
00252 };
00253 
00254 SR__ const s_15[] =
00255 {
00256     { { DEF_RED}, {  1} }, 
00257     { {       0}, { -6} }, 
00258 };
00259 
00260 SR__ const s_16[] =
00261 {
00262     { { DEF_RED}, {   2} },            
00263     { {     267}, {  18} }, // filename
00264     { {       0}, { -11} },            
00265 };
00266 
00267 SR__ const s_17[] =
00268 {
00269     { { DEF_RED}, {  1} }, 
00270     { {       0}, { -5} }, 
00271 };
00272 
00273 SR__ const s_18[] =
00274 {
00275     { { REQ_TOKEN}, {  2} },       
00276     { {        41}, { 19} }, // ')'
00277     { {         0}, {  0} },       
00278 };
00279 
00280 SR__ const s_19[] =
00281 {
00282     { { DEF_RED}, {   1} }, 
00283     { {       0}, { -10} }, 
00284 };
00285 
00286 
00287 // State array:
00288 SR__ const *s_state[] =
00289 {
00290   s_0,  s_1,  s_2,  s_3,  s_4,  s_5,  s_6,  s_7,  s_8,  s_9,
00291   s_10,  s_11,  s_12,  s_13,  s_14,  s_15,  s_16,  s_17,  s_18,  s_19,
00292 };
00293 
00294 typedef std::map<int, char const *> SMap;
00295 typedef SMap::value_type SMapVal;
00296 
00297 SMapVal s_symArr[] =
00298 {
00299     SMapVal(-2, "_UNDETERMINED_"),  // predefined symbols
00300     SMapVal(-1, "_EOF_"),
00301     SMapVal(256, "_error_"),
00302 
00303     SMapVal(257, "MOVEUNIT"),
00304     SMapVal(258, "LOADMAP"),
00305     SMapVal(259, "TESTCASE"),
00306     SMapVal(260, "asctextfile"),
00307     SMapVal(261, "blocks"),
00308     SMapVal(262, "block"),
00309     SMapVal(263, "testblock"),
00310     SMapVal(264, "commands"),
00311     SMapVal(265, "command"),
00312     SMapVal(266, "loadmapcommand"),
00313     SMapVal(267, "filename"),
00314     SMapVal(268, "asctextfile_$"),
00315 };
00316 
00317 SMap s_symbol
00318 (
00319     s_symArr, s_symArr + sizeof(s_symArr) / sizeof(SMapVal)
00320 );
00321 
00322 } // anonymous namespace ends
00323 
00324 
00325 
00326 // If the parsing function call uses arguments, then provide an overloaded
00327 // function.  The code below doesn't rely on parameters, so no arguments are
00328 // required.  Furthermore, parse uses a function try block to allow us to do
00329 // ACCEPT and ABORT from anywhere, even from within members called by actions,
00330 // simply throwing the appropriate exceptions.
00331 
00332 ParserBase::ParserBase()
00333 :
00334     d_stackIdx__(-1),
00335     // $insert debuginit
00336     d_debug__(true),
00337     d_nErrors__(0),
00338     // $insert requiredtokens
00339     d_requiredTokens__(0),
00340     d_acceptedTokens__(d_requiredTokens__),
00341     d_token__(_UNDETERMINED_),
00342     d_nextToken__(_UNDETERMINED_)
00343 {}
00344 
00345 // $insert debugfunctions
00346 
00347 std::ostringstream ParserBase::s_out__;
00348 
00349 std::ostream &ParserBase::dflush(std::ostream &out)
00350 {
00351     std::ostringstream &s_out__ = dynamic_cast<std::ostringstream &>(out);
00352 
00353     std::cout << "    " << s_out__.str() << std::flush;
00354     s_out__.clear();
00355     s_out__.str("");
00356     return out;
00357 }
00358 
00359 std::string ParserBase::symbol(int value) const
00360 {
00361     using namespace std;
00362     ostringstream ostr;
00363     SMap::const_iterator it = s_symbol.find(value);
00364     if (it != s_symbol.end())
00365         ostr << "`" << it->second << "'";
00366     else if (isprint(value))
00367         ostr << "`" << static_cast<char>(value) << "' (" << value << ")";
00368     else
00369         ostr << "'\\x" << setfill('0') << hex << setw(2) << value << "'";
00370     return ostr.str();
00371 }
00372 
00373 std::string ParserBase::stype__(char const *pre, STYPE__ const &semVal, char const *post) const
00374 {
00375     return "";
00376 }
00377 
00378 void ParserBase::clearin()
00379 {
00380     d_token__ = d_nextToken__ = _UNDETERMINED_;
00381 }
00382 
00383 void ParserBase::push__(size_t state)
00384 {
00385     if (static_cast<size_t>(d_stackIdx__ + 1) == d_stateStack__.size())
00386     {
00387         size_t newSize = d_stackIdx__ + STACK_EXPANSION;
00388         d_stateStack__.resize(newSize);
00389         d_valueStack__.resize(newSize);
00390     }
00391     ++d_stackIdx__;
00392     d_stateStack__[d_stackIdx__] = d_state__ = state;
00393     *(d_vsp__ = &d_valueStack__[d_stackIdx__]) = d_val__;
00394     // $insert debug
00395     if (d_debug__)
00396         s_out__ <<   "push(state " << state << stype__(", semantic TOS = ", d_val__, ")") << ')' << "\n" << dflush;
00397 }
00398 
00399 void ParserBase::popToken__()
00400 {
00401     d_token__ = d_nextToken__;
00402 
00403     d_val__ = d_nextVal__;
00404     d_nextVal__ = STYPE__();
00405 
00406     d_nextToken__ = _UNDETERMINED_;
00407 }
00408      
00409 void ParserBase::pushToken__(int token)
00410 {
00411     d_nextToken__ = d_token__;
00412     d_nextVal__ = d_val__;
00413     d_token__ = token;
00414 }
00415      
00416 void ParserBase::pop__(size_t count)
00417 {
00418     // $insert debug
00419     if (d_debug__)
00420         s_out__ <<  "pop(" << count << ") from stack having size " << (d_stackIdx__ + 1) << "\n" << dflush;
00421     if (d_stackIdx__ < static_cast<int>(count))
00422     {
00423         // $insert debug
00424         if (d_debug__)
00425             s_out__ <<  "Terminating parse(): unrecoverable input error at token " << symbol(d_token__) << "\n" << dflush;
00426         ABORT();
00427     }
00428 
00429     d_stackIdx__ -= count;
00430     d_state__ = d_stateStack__[d_stackIdx__];
00431     d_vsp__ = &d_valueStack__[d_stackIdx__];
00432     // $insert debug
00433     if (d_debug__)
00434         s_out__ <<  "pop(): next state: " << d_state__ << ", token: " << symbol(d_token__) ;
00435     // $insert debug
00436     if (d_debug__)
00437         s_out__ <<  stype__("semantic: ", d_val__) << "\n" << dflush;
00438 }
00439 
00440 inline size_t ParserBase::top__() const
00441 {
00442     return d_stateStack__[d_stackIdx__];
00443 }
00444 
00445 void Parser::executeAction(int production)
00446 {
00447     if (d_token__ != _UNDETERMINED_)
00448         pushToken__(d_token__);     // save an already available token
00449 
00450                                     // save default non-nested block $$
00451     if (int size = s_productionInfo[production].d_size)
00452         d_val__ = d_vsp__[1 - size];
00453 
00454     // $insert debug
00455     if (d_debug__)
00456         s_out__ <<  "executeAction(): of rule " << production ;
00457     // $insert debug
00458     if (d_debug__)
00459         s_out__ <<   stype__(", semantic [TOS]: ", d_val__) << " ..." << "\n" << dflush;
00460     switch (production)
00461     {
00462         // $insert actioncases
00463         
00464     }
00465     // $insert debug
00466     if (d_debug__)
00467         s_out__ <<  "... action of rule " << production << " completed" ;
00468     // $insert debug
00469     if (d_debug__)
00470         s_out__ <<   stype__(", semantic: ", d_val__) << "\n" << dflush;
00471 }
00472 
00473 inline void ParserBase::reduce__(PI__ const &pi)
00474 {
00475     d_token__ = pi.d_nonTerm;
00476     pop__(pi.d_size);
00477 
00478     // $insert debug
00479     if (d_debug__)
00480         s_out__ <<  "reduce(): by rule " << (&pi - s_productionInfo) ;
00481     // $insert debug
00482     if (d_debug__)
00483         s_out__ <<  " to N-terminal " << symbol(d_token__) << stype__(", semantic = ", d_val__) << "\n" << dflush;
00484 }
00485 
00486 // If d_token__ is _UNDETERMINED_ then if d_nextToken__ is _UNDETERMINED_ another
00487 // token is obtained from lex(). Then d_nextToken__ is assigned to d_token__.
00488 void Parser::nextToken()
00489 {
00490     if (d_token__ != _UNDETERMINED_)        // no need for a token: got one
00491         return;                             // already
00492 
00493     if (d_nextToken__ != _UNDETERMINED_)
00494     {
00495         popToken__();                       // consume pending token
00496         // $insert debug
00497         if (d_debug__)
00498             s_out__ <<  "nextToken(): popped " << symbol(d_token__) << stype__(", semantic = ", d_val__) << "\n" << dflush;
00499     }
00500     else
00501     {
00502         ++d_acceptedTokens__;               // accept another token (see
00503                                             // errorRecover())
00504         d_token__ = lex();
00505         if (d_token__ <= 0)
00506             d_token__ = _EOF_;
00507     }
00508     print();
00509     // $insert debug
00510     if (d_debug__)
00511         s_out__ <<  "nextToken(): using " << symbol(d_token__) << stype__(", semantic = ", d_val__) << "\n" << dflush;
00512 }
00513 
00514 // if the final transition is negative, then we should reduce by the rule
00515 // given by its positive value. Note that the `recovery' parameter is only
00516 // used with the --debug option
00517 int Parser::lookup(bool recovery)
00518 {
00519     // $insert threading
00520     SR__ const *sr = s_state[d_state__];  // get the appropriate state-table
00521     int lastIdx = sr->d_lastIdx;        // sentinel-index in the SR_ array
00522 
00523     SR__ const *lastElementPtr = sr + lastIdx;
00524     SR__ const *elementPtr = sr + 1;      // start the search at s_xx[1]
00525 
00526     while (elementPtr != lastElementPtr && elementPtr->d_token != d_token__)
00527         ++elementPtr;
00528 
00529     if (elementPtr == lastElementPtr)   // reached the last element
00530     {
00531         if (elementPtr->d_action < 0)   // default reduction
00532         {
00533         // $insert debug
00534         if (d_debug__)
00535             s_out__ <<  "lookup(" << d_state__ << ", " << symbol(d_token__) ;
00536         // $insert debug
00537         if (d_debug__)
00538             s_out__ <<  "): default reduction by rule " << -elementPtr->d_action << "\n" << dflush;
00539             return elementPtr->d_action;                
00540         }
00541         // $insert debug
00542         if (d_debug__)
00543             s_out__ <<  "lookup(" << d_state__ << ", " << symbol(d_token__) << "): Not " ;
00544         // $insert debug
00545         if (d_debug__)
00546             s_out__ <<  "found. " << (recovery ? "Continue" : "Start") << " error recovery."  << "\n" << dflush;
00547 
00548         // No default reduction, so token not found, so error.
00549         throw UNEXPECTED_TOKEN__;
00550     }
00551 
00552     // not at the last element: inspect the nature of the action
00553     // (< 0: reduce, 0: ACCEPT, > 0: shift)
00554 
00555     int action = elementPtr->d_action;
00556 
00557 // $insert debuglookup
00558     if (d_debug__)
00559     {
00560         s_out__ <<  "lookup(" << d_state__ << ", " << symbol(d_token__);
00561 
00562         if (action < 0)             // a reduction is found
00563             s_out__ << "): reduce by rule " << -action;
00564         else if (action == 0)
00565             s_out__ <<  "): ACCEPT";
00566         else 
00567             s_out__ <<  "): shift " << action << " (" << symbol(d_token__) << 
00568                         " processed)";
00569 
00570         s_out__ << "\n" << dflush;
00571     }
00572 
00573     return action;
00574 }
00575 
00576     // When an error has occurred, pop elements off the stack until the top
00577     // state has an error-item. If none is found, the default recovery
00578     // mode (which is to abort) is activated. 
00579     //
00580     // If EOF is encountered without being appropriate for the current state,
00581     // then the error recovery will fall back to the default recovery mode.
00582     // (i.e., parsing terminates)
00583 void Parser::errorRecovery()
00584 try
00585 {
00586     if (d_acceptedTokens__ >= d_requiredTokens__)// only generate an error-
00587     {                                           // message if enough tokens 
00588         ++d_nErrors__;                          // were accepted. Otherwise
00589         error("Syntax error");                  // simply skip input
00590 
00591     }
00592 
00593     // $insert debug
00594     if (d_debug__)
00595         s_out__ <<  "errorRecovery(): " << d_nErrors__ << " error(s) so far. State = " << top__() << "\n" << dflush;
00596 
00597     // get the error state
00598     while (not (s_state[top__()][0].d_type & ERR_ITEM))
00599     {
00600         // $insert debug
00601         if (d_debug__)
00602             s_out__ <<  "errorRecovery(): pop state " << top__() << "\n" << dflush;
00603         pop__();
00604     }
00605     // $insert debug
00606     if (d_debug__)
00607         s_out__ <<  "errorRecovery(): state " << top__() << " is an ERROR state" << "\n" << dflush;
00608 
00609     // In the error state, lookup a token allowing us to proceed.
00610     // Continuation may be possible following multiple reductions,
00611     // but eventuall a shift will be used, requiring the retrieval of
00612     // a terminal token. If a retrieved token doesn't match, the catch below 
00613     // will ensure the next token is requested in the while(true) block
00614     // implemented below:
00615 
00616     int lastToken = d_token__;                  // give the unexpected token a
00617                                                 // chance to be processed
00618                                                 // again.
00619 
00620     pushToken__(_error_);                       // specify _error_ as next token
00621     push__(lookup(true));                       // push the error state
00622 
00623     d_token__ = lastToken;                      // reactivate the unexpected
00624                                                 // token (we're now in an
00625                                                 // ERROR state).
00626 
00627     bool gotToken = true;                       // the next token is a terminal
00628 
00629     while (true)
00630     {
00631         try
00632         {
00633             if (s_state[d_state__]->d_type & REQ_TOKEN)
00634             {
00635                 gotToken = d_token__ == _UNDETERMINED_;
00636                 nextToken();                    // obtain next token
00637             }
00638             
00639             int action = lookup(true);
00640 
00641             if (action > 0)                 // push a new state
00642             {
00643                 push__(action);
00644                 popToken__();
00645                 // $insert debug
00646                 if (d_debug__)
00647                     s_out__ <<  "errorRecovery() SHIFT state " << action ;
00648                 // $insert debug
00649                 if (d_debug__)
00650                     s_out__ <<  ", continue with " << symbol(d_token__) << "\n" << dflush;
00651 
00652                 if (gotToken)
00653                 {
00654                     // $insert debug
00655                     if (d_debug__)
00656                         s_out__ <<  "errorRecovery() COMPLETED: next state " ;
00657                     // $insert debug
00658                     if (d_debug__)
00659                         s_out__ <<  action << ", no token yet" << "\n" << dflush;
00660 
00661                     d_acceptedTokens__ = 0;
00662                     return;
00663                 }
00664             }
00665             else if (action < 0)
00666             {
00667                 // no actions executed on recovery but save an already 
00668                 // available token:
00669                 if (d_token__ != _UNDETERMINED_)
00670                     pushToken__(d_token__);
00671  
00672                                             // next token is the rule's LHS
00673                 reduce__(s_productionInfo[-action]); 
00674                 // $insert debug
00675                 if (d_debug__)
00676                     s_out__ <<  "errorRecovery() REDUCE by rule " << -action ;
00677                 // $insert debug
00678                 if (d_debug__)
00679                     s_out__ <<  ", token = " << symbol(d_token__) << "\n" << dflush;
00680             }
00681             else
00682                 ABORT();                    // abort when accepting during
00683                                             // error recovery
00684         }
00685         catch (...)
00686         {
00687             if (d_token__ == _EOF_)
00688                 ABORT();                    // saw inappropriate _EOF_
00689                       
00690             popToken__();                   // failing token now skipped
00691         }
00692     }
00693 }
00694 catch (ErrorRecovery__)       // This is: DEFAULT_RECOVERY_MODE
00695 {
00696     ABORT();
00697 }
00698 
00699     // The parsing algorithm:
00700     // Initially, state 0 is pushed on the stack, and d_token__ as well as
00701     // d_nextToken__ are initialized to _UNDETERMINED_. 
00702     //
00703     // Then, in an eternal loop:
00704     //
00705     //  1. If a state does not have REQ_TOKEN no token is assigned to
00706     //     d_token__. If the state has REQ_TOKEN, nextToken() is called to
00707     //      determine d_nextToken__ and d_token__ is set to
00708     //     d_nextToken__. nextToken() will not call lex() unless d_nextToken__ is 
00709     //     _UNDETERMINED_. 
00710     //
00711     //  2. lookup() is called: 
00712     //     d_token__ is stored in the final element's d_token field of the
00713     //     state's SR_ array. 
00714     //
00715     //  3. The current token is looked up in the state's SR_ array
00716     //
00717     //  4. Depending on the result of the lookup() function the next state is
00718     //     shifted on the parser's stack, a reduction by some rule is applied,
00719     //     or the parsing function returns ACCEPT(). When a reduction is
00720     //     called for, any action that may have been defined for that
00721     //     reduction is executed.
00722     //
00723     //  5. An error occurs if d_token__ is not found, and the state has no
00724     //     default reduction. Error handling was described at the top of this
00725     //     file.
00726 
00727 int Parser::parse()
00728 try 
00729 {
00730     // $insert debug
00731     if (d_debug__)
00732         s_out__ <<  "parse(): Parsing starts" << "\n" << dflush;
00733     push__(0);                              // initial state
00734     clearin();                              // clear the tokens.
00735 
00736     while (true)
00737     {
00738         // $insert debug
00739         if (d_debug__)
00740             s_out__ <<  "==" << "\n" << dflush;
00741         try
00742         {
00743             if (s_state[d_state__]->d_type & REQ_TOKEN)
00744                 nextToken();                // obtain next token
00745 
00746 
00747             int action = lookup(false);     // lookup d_token__ in d_state__
00748 
00749             if (action > 0)                 // SHIFT: push a new state
00750             {
00751                 push__(action);
00752                 popToken__();               // token processed
00753             }
00754             else if (action < 0)            // REDUCE: execute and pop.
00755             {
00756                 executeAction(-action);
00757                                             // next token is the rule's LHS
00758                 reduce__(s_productionInfo[-action]); 
00759             }
00760             else 
00761                 ACCEPT();
00762         }
00763         catch (ErrorRecovery__)
00764         {
00765             errorRecovery();
00766         }
00767     }
00768 }
00769 catch (Return__ retValue)
00770 {
00771     // $insert debug
00772     if (d_debug__)
00773         s_out__ <<  "parse(): returns " << retValue << "\n" << dflush;
00774     return retValue;
00775 }
00776 

Generated on Mon May 21 01:26:36 2012 for Advanced Strategic Command by  doxygen 1.5.1