1 #ifndef GLRNODE 2 3 #define GLRNODE 4 5 #include <glr/glrGuard.h> 6 #include <glr/glrSymbolTable.h> 7 #include <glr/glrGrammar.h> 8 9 #ifdef DEBUG_FOREST 10 extern glrSymbolTable *globalSymbols; 11 #endif 12 13 #include <deque> 14 15 typedef enum {glrTerminalNode, glrNonterminalNode, glrEpsilonNode} glrNodeClass; 16 17 /** 18 * 19 * The <tt>glrEdge</tt> class is used internally by the parser to represent the edge 20 * of the graph structured stack which goes from some vertex to the vertex assiciated 21 * with some active state. 22 */ 23 class glrEdge { 24 private: 25 class glrStateVertex *fromStack; 26 class glrState *toState; 27 public: 28 /** 29 * 30 * Constructor is the only way to initialize the object. 31 */ glrEdge(class glrStateVertex * fromStackA,class glrState * toStateA)32 glrEdge(class glrStateVertex *fromStackA,class glrState* toStateA){ 33 fromStack = fromStackA; 34 toState = toStateA; 35 } 36 37 /** 38 * 39 * The <tt>from</tt> function returns the vertex which is the edge going from. 40 * In fact this vertex is remembered by the vertex asociated witch state stored in 41 * this object -- I thing the names of the <tt>from</tt> and <tt>to</tt> functions 42 * are a bit missleading. 43 */ from()44 class glrStateVertex* const& from() const { 45 return fromStack; 46 } 47 48 /** 49 * 50 * The <tt>to</tt> function returns the state witch is the vertex with the <tt>from</tt> 51 * vertex as the predcessor associated with. 52 */ to()53 class glrState* const& to() const { 54 return toState; 55 } 56 }; 57 58 /** 59 * 60 * Just a comparing functor to make possible to store the <tt>glrEdge</tt> -- type objects in 61 * the STL <tt>set</tt> based classes. 62 */ 63 class glrEdgeCompare { 64 public: operator()65 bool operator () (const glrEdge &x,const glrEdge &y) const { 66 return (x.from()<y.from())||((x.from()==y.from())&&(x.to()<y.to())); 67 } 68 }; 69 70 /** 71 * 72 * A set of an edges. 73 */ 74 class glrEdgeSet : public set<glrEdge,glrEdgeCompare> { 75 public: 76 /** 77 * 78 * This function returns <tt>true</tt> iff this object contains the <tt>subset</tt> 79 * set of edges as its subset. 80 */ containsSubset(glrEdgeSet const & subset)81 bool containsSubset(glrEdgeSet const& subset) const { 82 if(subset.size()>size()) return false; 83 for(glrEdgeSet::iterator iEdge = subset.begin(); iEdge!=subset.end(); ++iEdge){ 84 if(find(*iEdge)==end()) return false; 85 } 86 return true; 87 } 88 89 /** 90 * 91 * The set substraction. The function removes from this set of edges the edges 92 * contained in the <tt>subset</tt> set of edges. 93 */ substract(glrEdgeSet const & subset)94 void substract(glrEdgeSet const& subset){ 95 if(empty()) return; 96 for(glrEdgeSet::iterator iEdge = subset.begin(); iEdge!=subset.end(); ++iEdge) erase(*iEdge); 97 } 98 }; 99 100 /** 101 * 102 * Class <tt>glrNode</tt> is intended to be a the base class for any user defined class(es) that will represent 103 * nodes of packed shared forest. You should derive this class to create the class which instances 104 * will the parser use to represent the nonterminal nodes of the packed shared forest and specify 105 * it as the first argument to the <tt>glrParser</tt> template. Read the quickstart manual to make 106 * this clear. 107 * 108 * You need also to 109 * create a <tt>glrNode</tt> -- drived class to represent the terminal nodes. You should instant 110 * this class in your overrided <tt>glrParser::readToken</tt> function. 111 * 112 * Read documantation of <tt>glrGuard</tt> class which is the base class to the <tt>glrNode</tt> class! 113 * 114 * @see glrGuard 115 * @see glrParser 116 */ 117 class glrNode : public glrGuard { 118 private: 119 glrSymbolTable::glrSymbol symbol; 120 glrNodeClass type; 121 glrEdgeSet edges; 122 123 #ifdef DEBUG 124 static int maxNodeId; 125 int nodeId; 126 #endif 127 public: 128 129 #ifdef DEBUG getId()130 int const& getId() const { 131 return nodeId; 132 } 133 #endif 134 135 /** 136 * 137 * This function is used internally by the parser. It return the stored set of edges where this 138 * node is shared in the graph structured stack. 139 */ edgeSet()140 const glrEdgeSet &edgeSet(){ 141 return edges; 142 } 143 144 /** 145 * 146 * This function adds an edge to the set of stored edges. It is used internally by the parser. 147 */ addEdge(class glrStateVertex * fromStackA,class glrState * toStateA)148 void addEdge(class glrStateVertex* fromStackA, class glrState *toStateA){ 149 edges.insert(glrEdge(fromStackA,toStateA)); 150 } 151 152 /** 153 * 154 * This constructor should be called when the instance of the class which 155 * represents terminal in the forest is created. You should call it in the head 156 * of constructor of such class. <tt>symbolA</tt> is the symbol of the grammar 157 * which represents appropriate preterminal. 158 */ glrNode(const glrSymbolTable::glrSymbol & symbolA)159 glrNode(const glrSymbolTable::glrSymbol &symbolA) : glrGuard() { 160 #ifdef DEBUG_FOREST 161 nodeId = maxNodeId++; 162 cerr << "creating new terminal node with symbol ,," << globalSymbols->getStringFromSymbol(symbolA) << "'' [" << nodeId << "]" << endl; 163 #endif 164 symbol=symbolA; 165 type=glrTerminalNode; 166 } 167 168 /** 169 * 170 * This constructor should be called to create node in the forest in consequence of 171 * reduction by the epsilon rule. You should create same constructor 172 * in the class you specify as the first argument to the <tt>glrParser</tt> template 173 * and call this constructor in it's head. The reduction is according to the 174 * rule <tt>ruleA</tt>. 175 */ glrNode(const glrRule * const & ruleA)176 glrNode(const glrRule* const &ruleA) : glrGuard() { 177 #ifdef DEBUG_FOREST 178 nodeId = maxNodeId++; 179 cerr << "creating new epsilon node [" << nodeId << "] along rule ,,"; 180 ruleA->print(*globalSymbols,cerr); 181 cerr << "''" << endl; 182 #endif 183 symbol=ruleA->getLeft(); 184 type=glrEpsilonNode; 185 } 186 187 /** 188 * 189 * This constructor should be called to create node in the forest in consequence of 190 * reduction by the nonepsilon rule. You should create same constructor 191 * in the class you specify as the first argument to the <tt>glrParser</tt> template 192 * and call this constructor in it's head. Reduction is accroding to 193 * the rule <tt>ruleA</tt>. <tt>succA</tt> are the appropriate childern nodes 194 * coresponding to the symbols at the right side of the rule. 195 */ glrNode(const glrRule * const & ruleA,const deque<glrNode * > & succA)196 glrNode(const glrRule* const &ruleA,const deque<glrNode*> &succA) : glrGuard() { 197 #ifdef DEBUG_FOREST 198 nodeId = maxNodeId++; 199 cerr << "creating new nonterminal node [" << nodeId << "] along rule ,,"; 200 ruleA->print(*globalSymbols,cerr); 201 cerr << "''" << endl; 202 #endif 203 symbol=ruleA->getLeft(); 204 type=glrNonterminalNode; 205 } 206 207 /** 208 * 209 * You should override the destructor in your <tt>glrNode</tt> -- drived classes 210 * and call the <tt>release()</tt> function of remembered <tt>glrGuard</tt> derived 211 * objects. 212 */ ~glrNode()213 virtual ~glrNode(){ 214 #ifdef DEBUG_FOREST 215 cerr << "deleting node [" << nodeId << "]" << endl; 216 #endif 217 } 218 219 /** 220 * 221 * This function is called by the parser to add other subtree to existing 222 * nonterminal node of the forest. 223 * You should override it in the class you 224 * specify as the first argument to the <tt>glrParser</tt> tamplate. Reduction 225 * is according to the rule <tt>ruleA</tt>. <tt>succA</tt> are the appropriate childern nodes 226 * coresponding to the symbols at the right side of the rule. 227 */ addSubtree(const glrRule * const & ruleA,const deque<glrNode * > & succA)228 virtual void addSubtree(const glrRule* const &ruleA,const deque<glrNode*> &succA) {} 229 230 /** 231 * 232 * Function <tt>getSymbol</tt> returns the symbol particular to this node. 233 */ getSymbol()234 const glrSymbolTable::glrSymbol &getSymbol() const { return symbol; } 235 236 /** 237 * 238 * Function <tt>getType()</tt> returns the type of the node. It can be either 239 * <tt>glrTerminalNode</tt>, <tt>glrNonterminalNode</tt> or <tt>glrEpsilonNode</tt>. 240 */ getType()241 const glrNodeClass &getType() const { return type; } 242 }; 243 244 /** 245 * 246 * The <tt>glrNodeSet</tt> class is used internally by the parser to represent the 247 * set of the nodes. 248 */ 249 class glrNodeSet : public set<glrNode*> { 250 public: 251 /** 252 * 253 * This function inserts the nodes cotained in the <tt>nodes</tt> vector to this set. 254 */ insert(vector<glrNode * > const & nodes)255 void insert(vector<glrNode*> const& nodes){ 256 for(vector<glrNode*>::const_iterator iNode = nodes.begin(); iNode!=nodes.end(); ++iNode){ 257 set<glrNode*>::insert(*iNode); 258 } 259 } 260 }; 261 262 #endif 263