#ifndef GLRSTACK #define GLRSTACK class glrStackNoPredsException {}; #include #include #include #ifdef DEBUG #include extern glrSymbolTable* globalSymbols; extern bool mergeInProgress; #endif #include #include #include #include #include #include using namespace std; /** * * This class is used internally by the parser during parsing. * Class glrSymbolVertex is used to store all edges of the graph structured stack, which goes to * one state vertex over one symbol. * */ class glrSymbolVertex { private: map > nodesFromState; map > statesFromNode; // glrNode *epsilonNode; public: /** * * Constructor. Just necessary initialization. * */ glrSymbolVertex(){ // epsilonNode=(glrNode*)NULL; } /** * * Destrcutor. It calls release() function to all remembered state vertices. * */ ~glrSymbolVertex(){ for(map >::iterator iState = nodesFromState.begin(); iState!=nodesFromState.end(); ++iState){ for(vector::iterator iEdge = iState->second.begin(); iEdge!=iState->second.end(); ++iEdge){ ((glrGuard*)(iState->first))->release(); (*iEdge)->release(); } } } /** * * Function addPred stores the edge from the vertex pred over the node node. * */ void addPred(glrStateVertex * const &pred,glrNode * const &node){ nodesFromState[pred].push_back(node); statesFromNode[node].push_back(pred); node->shackle(); ((glrGuard*)pred)->shackle(); } /** * * Function nodeFromState_begin() returns the iterator to the begining of associative * container which stores edges from vertices. To each edge is associated apropriate node of packed shared forest. * */ map >::const_iterator nodesFromState_begin() const { return nodesFromState.begin(); } /** * * Function nodeFromState_end() returns the iterator to the end of the associative * container which stores edges from vertices. To each edge is associated apropriate node of packed shared forest. * */ map >::const_iterator nodesFromState_end() const { return nodesFromState.end(); } /** * * Function nodeFromState_find() returns the iterator to the element of associative * container which stores edges associated with apropriate node. The returned iterator * points to the element which represents an edge from the fromStack. If there doesn't exist * such edge, it returns the same value as nodeFromState_end() function. * */ map >::const_iterator nodesFromState_find(glrStateVertex *fromStack) const { return nodesFromState.find(fromStack); } /** * * Function statesFromNode_begin() returns iterator to the begining of the asociative * container which stores vector of state vertices from which the edges comes over one node of * packed shared forest (which is the key). * */ map >::const_iterator statesFromNode_begin() const { return statesFromNode.begin(); } /** * * Function statesFromNode_end() returns iterator to the end of the asociative * container which stores vector of state vertices from which the edges comes over one node of * packed shared forest (which is the key). * */ map >::const_iterator statesFromNode_end() const { return statesFromNode.end(); } /** * * Function statesFromNode_find() returns iterator to the element of the asociative * container which stores vector of state vertices from which comes edges over node fromNode. * */ map >::const_iterator statesFromNode_find(glrNode *fromNode) const { return statesFromNode.find(fromNode); } // /** // * // * Function getEpsilonRule returns pointer to the node asociated with stored edge which was created // * by epsilon rule. Note that there may be only one such node to any state vertex. // * // */ // glrNode* const &getEpsilonNode(){ // return epsilonNode; // } }; /** * * Class glrStateVertex is used internaly by the parser to represent one state vertex of the graph stack. * */ class glrStateVertex : public glrGuard { public: #ifdef DEBUG static int numStateVertices; static int maxStateVertexId; int vertexId; int const& getId() const { return vertexId; } #endif private: class glrState *state; // stav, ke kteremu patri dany stateVertex int iToken; // poradove cislo symbolu na vstupu, ktere bylo aktualni ve chvili vzniku tohoto vrcholu map pred; // predkove v zasobniku daneho vrholu klicovani podle symbolu patricimu hrane bool bottomFlag; // map > > reductionsMade; // map,glrNode*> > reductionsMade; public: /* bool performReductions(const void* rule,const deque &subtree){ pair >::iterator,bool> ret = reductionsMade[rule].insert(subtree); #ifdef DEBUG if(!ret.second){ cerr << "bool glrStateVertex::performReductions(const void* rule,const deque &subtree): \ refusing attempt to make same reduction twice" << endl; } #endif return ret.second; }*/ /* glrNode* findParentForEdge(void *rule,const deque &subtree){ map,glrNode*>::iterator ret = reductionsMade[rule].find(subtree); if(ret==reductionsMade[rule].end()){ return NULL; }else{ return ret->second; } }*/ virtual ~glrStateVertex(){ #ifdef DEBUG --numStateVertices; cerr << "deleting state vertex with id " << vertexId << endl; #endif } /** * * Contructor. iTokenA is actual number of token on input. stateA is the asociated state of automat. predA * and nodeA specifies new edge to create in the graph stack from the state vertex predA over the node nodeA. * */ glrStateVertex(int const &iTokenA,class glrState* const &stateA,class glrStateVertex* const &predA,class glrNode* const &node){ iToken=iTokenA; state=stateA; addPred(predA,node); bottomFlag = false; #ifdef DEBUG numStateVertices++; vertexId = (maxStateVertexId++); cerr << "creating state vertex with id " << vertexId << endl; #endif } bool bottom() const { return bottomFlag; } /** * * Constructor. iTokenA is actual number of token on input. stateA is the asociated state of the automat. * */ glrStateVertex(int const &iTokenA,class glrState* const &stateA){ iToken=iTokenA; state=stateA; bottomFlag = false; #ifdef DEBUG ++numStateVertices; vertexId = (maxStateVertexId++); cerr << "creating state vertex with id " << vertexId << endl; #endif } /** * * Constructor. iTokenA is actual number of token on input. stateA is the asociated state of the automat. * bottomFlagA should be set to true iff this vertex is the bottom of the graph structured stack. * */ glrStateVertex(int const &iTokenA,class glrState* const &stateA, bool bottomFlagA){ iToken=iTokenA; state=stateA; bottomFlag = bottomFlagA; #ifdef DEBUG ++numStateVertices; vertexId = (maxStateVertexId++); cerr << "creating state vertex with id " << vertexId << endl; #endif } /** * * The function getToken() returns the number of token on input which was actual when the vertex was created. * */ int const &getToken(){ return iToken; } /** * * Function addPred adds edge to the graph stack from vertex fromVertex * over node overNode. * */ void addPred(glrStateVertex* const &fromVertex,glrNode* const &overNode){ #ifdef DEBUG if(!mergeInProgress){ cerr << "creating edge from vertex " << fromVertex->getState()->getNumber() << " (" << fromVertex->getToken() << ") " << "to vertex " << getState()->getNumber() << " (" << getToken() << ") over symbol ,," << globalSymbols->getStringFromSymbol(overNode->getSymbol()) << "''" << endl; } #endif glrSymbolVertex &predsFromSymbol=pred[overNode->getSymbol()]; predsFromSymbol.addPred(fromVertex,overNode); } /** * * Function getPreds returns reference to the object of type glrSymbolVertex, * where all edges over symbol symbol to this vertex are stored. If there * is not such edge, new glrSymbolVertex object is created and stored. * */ glrSymbolVertex &getPreds(glrSymbolTable::glrSymbol const &symbol){ return pred[symbol]; } /** * * Function findPreds returns reference to the object of type glrSymbolVertex, * where all edges over symbol symbol to this vertex are stored. If there * is not such edge the exception glrStackNoPredsException is throwed. * */ glrSymbolVertex const& findPreds(glrSymbolTable::glrSymbol const &symbol) const { map::const_iterator iSym=pred.find(symbol); if(iSym==pred.end())throw glrStackNoPredsException(); return iSym->second; } /** * * The function getState() returns the state asociated with this vertex. * */ class glrState* const &getState(){ return state; } /** * * Function merge adds all stored edges to state vertex specified by where. * */ void merge(glrStateVertex* const &where){ #ifdef DEBUG if((state!=where->getState())||(iToken!=where->getToken())){ cerr << "error: can\'t merge stack with different state or iToken" << endl; return; } mergeInProgress = true; #endif for(map::iterator iSym=pred.begin();iSym!=pred.end();++iSym){ for(map >::const_iterator iStack = iSym->second.nodesFromState_begin(); iStack!=iSym->second.nodesFromState_end(); ++iStack){ for(vector::const_iterator iNode = iStack->second.begin(); iNode!=iStack->second.end(); ++iNode){ where->addPred(iStack->first, *iNode); if(iStack->first->getToken()==where->getToken()){ iStack->first->getState()->crossEdges.push_back(pair(*iNode, getState())); } } } } #ifdef DEBUG mergeInProgress = false; #endif } void addCrossEdges(){ for(map::iterator iSym=pred.begin();iSym!=pred.end();++iSym){ for(map >::const_iterator iStack = iSym->second.nodesFromState_begin();iStack!=iSym->second.nodesFromState_end(); ++iStack){ if(iStack->first->getToken()==getToken()){ for(vector::const_iterator iNode = iStack->second.begin(); iNode!=iStack->second.end(); ++iNode){ iStack->first->getState()->crossEdges.push_back(pair(*iNode, getState())); } } } } } }; #endif