#ifndef STATE #define STATE #include #include #include #include using namespace std; //typedef enum { none, active, both } queFlagType; /** * * Class glrState is the base class for classes which represent state of the automat. On the other side, it represents one row of the glr * table. glrState class is never used directly. Instead of it, the parser uses glrState -- derived classes * which adds some other essential properties. * */ class glrState { private: int number; public: // queFlagType queFlag; // bool reducesFlag; /** * * The crossEdges field is used to store edges whitch runs from any vertex associated with any * active state to the vertex associated with this state. * */ vector > crossEdges; /** * * Field reduces is the vector of pointers to the grammar rules which can be used to make the reductions * from this state and concurrently which are not the epsilon rules and which have nonterminal on the end of the right side. * */ vector reduces; /** * * Field epsReduces is vector of pointers to grammar rules which can be used to make reductions * from this state and which are the epsilon rules (their right side is empty). * */ vector epsReduces; /** * * Field reduces is vector of pointers to the grammar rules which can be used to make the reductions * from this state and which are not the epsilon rules and which have the preterminal on the end of the right side. * */ vector termReduces; /** * * If this state is active --- this means, that on the top of the graph stack is its state vertex --- the field * stack points to this state vertex. * */ class glrStateVertex *stack; /** * * The field futureStack is used temporarly in the * glrParser::makeReductions and the glrParser::parse() functions. * */ class glrStateVertex *futureStack; /** * * The field adtionalStack is used temporarly during * glrParser::makeAditionalReductions. * */ // class glrStateVertex *aditionalStack; /** * * If the state is active, this field says in which phase are reductions in regard of the state vertex stored in * the stack field. It can be one of this values: glrRedDone, glrRedMaking, glrRedWaiting, * glrRedNotNeed. * */ // glrReducesState reducesState; /** * * Functon getNumber() returns the number of this state. * */ const int &getNumber() const { return number; } // bool crossInProgress; /** * * Constructor. numberA is the number of new state. * */ glrState(const int &numberA) { number=numberA; // reducesState=glrRedNotNeed; stack=(glrStateVertex*)NULL; futureStack=(glrStateVertex*)NULL; // aditionalStack=NULL; // crossInProgress=false; //queFlag = none; //reducesFlag = false; } }; /** * * Class glrMapState is the alternative implementation of the state of automat (the row of glr table). You can make the * parser to use it by specifying it as the second argument to the glrParser template. * This is the first implementation I used, but I found that it is about few slower then * glrVectorState which I use now. On the other side, memory requiments may be lower if this class is used * witch grammar with lots of symbols. * */ class glrMapState : public glrState { private: map gotos; map shifts; public: /** * * Constructor. numberA is the number of the state and symbols is the parser's * table of symbols. * */ glrMapState(const int &numberA,const glrSymbolTable &symbols) : glrState(numberA) {}; /** * * Function gotos_find returns the state where the parser can make * transition over symbol symbol. If there is not such transition * it returns NULL. The guaranted complexity * is logarithmic according to number of transitions stored. * */ glrMapState* gotos_find(const glrSymbolTable::glrSymbol &symbol) const { const map::const_iterator &i=gotos.find(symbol); return (i!=gotos.end())?(i->second):((glrMapState*)NULL); } /** * * Function shifts_find returns the state where the parser * can make shift over the symbol symbol. If there is not such shift * from this state it returns NULL. * The guaranted complexity is logarithmic according to the number of shifts stored. * */ glrMapState* shifts_find(const glrSymbolTable::glrSymbol &symbol) const { const map::const_iterator &i=shifts.find(symbol); return (i!=shifts.end())?(i->second):((glrMapState*)NULL); } /** * * Function gotos_insert inserts the transition to state over symbol symbol * to the row of the goto table. * */ void gotos_insert(const glrSymbolTable::glrSymbol &symbol,glrMapState* const& state){ gotos.insert(pair(symbol,state)); } /** * * Function shifts_insert inserts the shift to the state over symbol * symbol to the row of the glr table. * */ void shifts_insert(const glrSymbolTable::glrSymbol &symbol,glrMapState* const& state){ shifts.insert(pair(symbol,state)); } /** * * Function print prints the state (row of glr table) in the form * in which the parser can read it from the file. symbols is parser's * table of symbols and the output is where to print. * */ void print(const glrSymbolTable &symbols,ostream &output) const { output << "|State| " << getNumber() << endl; for(map::const_iterator i=gotos.begin();i!=gotos.end();++i) output << "\t\t" << symbols.getStringFromSymbol(i->first) << " " << i->second->getNumber() << endl; for(map::const_iterator i=shifts.begin();i!=shifts.end();++i) output << "\t\t" << symbols.getStringFromSymbol(i->first) << " " << i->second->getNumber() << endl; for(vector::const_iterator i=reduces.begin();i!=reduces.end();++i) output << "\t\t__reduce " << (*i)->getNumber() << endl; for(vector::const_iterator i=epsReduces.begin();i!=epsReduces.end();++i) output << "\t\t__reduce " << (*i)->getNumber() << endl; for(vector::const_iterator i=termReduces.begin();i!=termReduces.end();++i) output << "\t\t__reduce " << (*i)->getNumber() << endl; } }; /** * * Class glrVectorState is the parser's default class to storing the state (one row of the glr table). * */ class glrVectorState : public glrState { private: vector transitions; public: /** * * Constructor. numberA is the number of the state and symbols is the parser's * table of symbols. * */ glrVectorState(const int &numberA,const glrSymbolTable &symbols) : glrState(numberA) { transitions.resize(symbols.size()); for(int i=0;igotos_find returns the state where the parser can make * transition over the symbol symbol. If there is not such transition * it returns NULL. The guaranted complexity * is constant. * */ glrVectorState* const &gotos_find(const glrSymbolTable::glrSymbol &symbol) const { return transitions[(int)symbol]; } /** * * Function shifts_find returns the state where the parser * can make shift over the symbol symbol. If there is not such shift * from this state it returns NULL. * The guaranted complexity is constant. * */ glrVectorState* const &shifts_find(const glrSymbolTable::glrSymbol &symbol) const { return transitions[(int)symbol]; } /** * * Function gotos_insert inserts the transition to state over symbol * to the row of the goto table. * */ void gotos_insert(const glrSymbolTable::glrSymbol &symbol,glrVectorState* const& state){ transitions[(int)symbol]=state; } /** * * Function shifts_insert inserts the shift to state over symbol * symbol to the row of the glr table. * */ void shifts_insert(const glrSymbolTable::glrSymbol &symbol,glrVectorState* const& state){ transitions[(int)symbol]=state; } /** * * Function print prints the state (row of the glr table) in the form * in which the parser can read it from the file. symbols is parser's * table of symbols and output is where to print. * */ void print(const glrSymbolTable &symbols,ostream &output) const { output << "|State| " << getNumber() << endl; for(int i=0;igetNumber() << endl; for(vector::const_iterator i=reduces.begin();i!=reduces.end();++i) output << "\t\t__reduce " << (*i)->getNumber() << endl; for(vector::const_iterator i=epsReduces.begin();i!=epsReduces.end();++i) output << "\t\t__reduce " << (*i)->getNumber() << endl; for(vector::const_iterator i=termReduces.begin();i!=termReduces.end();++i) output << "\t\t__reduce " << (*i)->getNumber() << endl; } }; #endif