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