Some more refactoring following the elimination of the intermediate file. Don't
[external/ragel.git] / ragel / parsedata.h
1 /*
2  *  Copyright 2001-2006 Adrian Thurston <thurston@complang.org>
3  */
4
5 /*  This file is part of Ragel.
6  *
7  *  Ragel is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  * 
12  *  Ragel is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  * 
17  *  You should have received a copy of the GNU General Public License
18  *  along with Ragel; if not, write to the Free Software
19  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
20  */
21
22 #ifndef _PARSEDATA_H
23 #define _PARSEDATA_H
24
25 #include <iostream>
26 #include <limits.h>
27 #include <sstream>
28 #include "avlmap.h"
29 #include "bstmap.h"
30 #include "vector.h"
31 #include "dlist.h"
32 #include "fsmgraph.h"
33 #include "compare.h"
34 #include "vector.h"
35 #include "common.h"
36 #include "parsetree.h"
37
38 /* Forwards. */
39 using std::ostream;
40
41 struct VarDef;
42 struct Join;
43 struct Expression;
44 struct Term;
45 struct FactorWithAug;
46 struct FactorWithLabel;
47 struct FactorWithRep;
48 struct FactorWithNeg;
49 struct Factor;
50 struct Literal;
51 struct Range;
52 struct RegExpr;
53 struct ReItem;
54 struct ReOrBlock;
55 struct ReOrItem;
56 struct LongestMatch;
57 struct InputData;
58 typedef DList<LongestMatch> LmList;
59
60
61 /* Graph dictionary. */
62 struct GraphDictEl 
63 :
64         public AvlTreeEl<GraphDictEl>,
65         public DListEl<GraphDictEl>
66 {
67         GraphDictEl( const char *k ) 
68                 : key(k), value(0), isInstance(false) { }
69         GraphDictEl( const char *k, VarDef *value ) 
70                 : key(k), value(value), isInstance(false) { }
71
72         const char *getKey() { return key; }
73
74         const char *key;
75         VarDef *value;
76         bool isInstance;
77
78         /* Location info of graph definition. Points to variable name of assignment. */
79         InputLoc loc;
80 };
81
82 typedef AvlTree<GraphDictEl, const char*, CmpStr> GraphDict;
83 typedef DList<GraphDictEl> GraphList;
84
85 /* Priority name dictionary. */
86 typedef AvlMapEl<char*, int> PriorDictEl;
87 typedef AvlMap<char*, int, CmpStr> PriorDict;
88
89 /* Local error name dictionary. */
90 typedef AvlMapEl<const char*, int> LocalErrDictEl;
91 typedef AvlMap<const char*, int, CmpStr> LocalErrDict;
92
93 /* Tree of instantiated names. */
94 typedef BstMapEl<const char*, NameInst*> NameMapEl;
95 typedef BstMap<const char*, NameInst*, CmpStr> NameMap;
96 typedef Vector<NameInst*> NameVect;
97 typedef BstSet<NameInst*> NameSet;
98
99 /* Node in the tree of instantiated names. */
100 struct NameInst
101 {
102         NameInst( const InputLoc &loc, NameInst *parent, const char *name, int id, bool isLabel ) : 
103                 loc(loc), parent(parent), name(name), id(id), isLabel(isLabel),
104                 isLongestMatch(false), numRefs(0), numUses(0), start(0), final(0) {}
105
106         InputLoc loc;
107
108         /* Keep parent pointers in the name tree to retrieve 
109          * fully qulified names. */
110         NameInst *parent;
111
112         const char *name;
113         int id;
114         bool isLabel;
115         bool isLongestMatch;
116
117         int numRefs;
118         int numUses;
119
120         /* Names underneath us, excludes anonymous names. */
121         NameMap children;
122
123         /* All names underneath us in order of appearance. */
124         NameVect childVect;
125
126         /* Join scopes need an implicit "final" target. */
127         NameInst *start, *final;
128
129         /* During a fsm generation walk, lists the names that are referenced by
130          * epsilon operations in the current scope. After the link is made by the
131          * epsilon reference and the join operation is complete, the label can
132          * have its refcount decremented. Once there are no more references the
133          * entry point can be removed from the fsm returned. */
134         NameVect referencedNames;
135
136         /* Pointers for the name search queue. */
137         NameInst *prev, *next;
138
139         /* Check if this name inst or any name inst below is referenced. */
140         bool anyRefsRec();
141 };
142
143 typedef DList<NameInst> NameInstList;
144
145 /* Stack frame used in walking the name tree. */
146 struct NameFrame 
147 {
148         NameInst *prevNameInst;
149         int prevNameChild;
150         NameInst *prevLocalScope;
151 };
152
153 /* Class to collect information about the machine during the 
154  * parse of input. */
155 struct ParseData
156 {
157         /* Create a new parse data object. This is done at the beginning of every
158          * fsm specification. */
159         ParseData( const char *fileName, char *sectionName, const InputLoc &sectionLoc );
160         ~ParseData();
161
162         /*
163          * Setting up the graph dict.
164          */
165
166         /* Initialize a graph dict with the basic fsms. */
167         void initGraphDict();
168         void createBuiltin( const char *name, BuiltinMachine builtin );
169
170         /* Make a name id in the current name instantiation scope if it is not
171          * already there. */
172         NameInst *addNameInst( const InputLoc &loc, const char *data, bool isLabel );
173         void makeRootNames();
174         void makeNameTree( GraphDictEl *gdNode );
175         void makeExportsNameTree();
176         void fillNameIndex( NameInst *from );
177         void printNameTree();
178
179         /* Increments the usage count on entry names. Names that are no longer
180          * needed will have their entry points unset. */
181         void unsetObsoleteEntries( FsmAp *graph );
182
183         /* Resove name references in action code and epsilon transitions. */
184         NameSet resolvePart( NameInst *refFrom, const char *data, bool recLabelsOnly );
185         void resolveFrom( NameSet &result, NameInst *refFrom, 
186                         const NameRef &nameRef, int namePos );
187         NameInst *resolveStateRef( const NameRef &nameRef, InputLoc &loc, Action *action );
188         void resolveNameRefs( InlineList *inlineList, Action *action );
189         void resolveActionNameRefs();
190
191         /* Set the alphabet type. If type types are not valid returns false. */
192         bool setAlphType( const InputLoc &loc, char *s1, char *s2 );
193         bool setAlphType( const InputLoc &loc, char *s1 );
194
195         /* Override one of the variables ragel uses. */
196         bool setVariable( char *var, InlineList *inlineList );
197
198         /* Unique actions. */
199         void removeDups( ActionTable &actionTable );
200         void removeActionDups( FsmAp *graph );
201
202         /* Dumping the name instantiation tree. */
203         void printNameInst( NameInst *nameInst, int level );
204
205         /* Make the graph from a graph dict node. Does minimization. */
206         FsmAp *makeInstance( GraphDictEl *gdNode );
207         FsmAp *makeSpecific( GraphDictEl *gdNode );
208         FsmAp *makeAll();
209
210         /* Checking the contents of actions. */
211         void checkAction( Action *action );
212         void checkInlineList( Action *act, InlineList *inlineList );
213
214         void analyzeAction( Action *action, InlineList *inlineList );
215         void analyzeGraph( FsmAp *graph );
216         void makeExports();
217
218         void prepareMachineGen( GraphDictEl *graphDictEl );
219         void prepareMachineGenTBWrapped( GraphDictEl *graphDictEl );
220         void generateXML( ostream &out, InputData &inputData );
221         void generateReduced( InputData &inputData );
222         FsmAp *sectionGraph;
223         bool generatingSectionSubset;
224
225         void initKeyOps();
226
227         /*
228          * Data collected during the parse.
229          */
230
231         /* Dictionary of graphs. Both instances and non-instances go here. */
232         GraphDict graphDict;
233
234         /* The list of instances. */
235         GraphList instanceList;
236
237         /* Dictionary of actions. Lets actions be defined and then referenced. */
238         ActionDict actionDict;
239
240         /* Dictionary of named priorities. */
241         PriorDict priorDict;
242
243         /* Dictionary of named local errors. */
244         LocalErrDict localErrDict;
245
246         /* List of actions. Will be pasted into a switch statement. */
247         ActionList actionList;
248
249         /* The id of the next priority name and label. */
250         int nextPriorKey, nextLocalErrKey, nextNameId, nextCondId;
251         
252         /* The default priority number key for a machine. This is active during
253          * the parse of the rhs of a machine assignment. */
254         int curDefPriorKey;
255
256         int curDefLocalErrKey;
257
258         /* Alphabet type. */
259         HostType *userAlphType;
260         bool alphTypeSet;
261         InputLoc alphTypeLoc;
262
263         /* Element type and get key expression. */
264         InlineList *getKeyExpr;
265         InlineList *accessExpr;
266
267         /* Stack management */
268         InlineList *prePushExpr;
269         InlineList *postPopExpr;
270
271         /* Overriding variables. */
272         InlineList *pExpr;
273         InlineList *peExpr;
274         InlineList *eofExpr;
275         InlineList *csExpr;
276         InlineList *topExpr;
277         InlineList *stackExpr;
278         InlineList *actExpr;
279         InlineList *tokstartExpr;
280         InlineList *tokendExpr;
281         InlineList *dataExpr;
282
283         /* The alphabet range. */
284         char *lowerNum, *upperNum;
285         Key lowKey, highKey;
286         InputLoc rangeLowLoc, rangeHighLoc;
287
288         /* The name of the file the fsm is from, and the spec name. */
289         const char *fileName;
290         char *sectionName;
291         InputLoc sectionLoc;
292
293         /* Counting the action and priority ordering. */
294         int curActionOrd;
295         int curPriorOrd;
296
297         /* Root of the name tree. One root is for the instantiated machines. The
298          * other root is for exported definitions. */
299         NameInst *rootName;
300         NameInst *exportsRootName;
301         
302         /* Name tree walking. */
303         NameInst *curNameInst;
304         int curNameChild;
305
306         /* The place where resolved epsilon transitions go. These cannot go into
307          * the parse tree because a single epsilon op can resolve more than once
308          * to different nameInsts if the machine it's in is used more than once. */
309         NameVect epsilonResolvedLinks;
310         int nextEpsilonResolvedLink;
311
312         /* Root of the name tree used for doing local name searches. */
313         NameInst *localNameScope;
314
315         void setLmInRetLoc( InlineList *inlineList );
316         void initLongestMatchData();
317         void setLongestMatchData( FsmAp *graph );
318         void initNameWalk();
319         void initExportsNameWalk();
320         NameInst *nextNameScope() { return curNameInst->childVect[curNameChild]; }
321         NameFrame enterNameScope( bool isLocal, int numScopes );
322         void popNameScope( const NameFrame &frame );
323         void resetNameScope( const NameFrame &frame );
324
325         /* Make name ids to name inst pointers. */
326         NameInst **nameIndex;
327
328         /* Counter for assigning ids to longest match items. */
329         int nextLongestMatchId;
330         bool lmRequiresErrorState;
331
332         /* List of all longest match parse tree items. */
333         LmList lmList;
334
335         Action *newAction( const char *name, InlineList *inlineList );
336
337         Action *initTokStart;
338         int initTokStartOrd;
339
340         Action *setTokStart;
341         int setTokStartOrd;
342
343         Action *initActId;
344         int initActIdOrd;
345
346         Action *setTokEnd;
347         int setTokEndOrd;
348
349         void beginProcessing()
350         {
351                 ::condData = &thisCondData;
352                 ::keyOps = &thisKeyOps;
353         }
354
355         CondData thisCondData;
356         KeyOps thisKeyOps;
357
358         ExportList exportList;
359 };
360
361 void afterOpMinimize( FsmAp *fsm, bool lastInSeq = true );
362 Key makeFsmKeyHex( char *str, const InputLoc &loc, ParseData *pd );
363 Key makeFsmKeyDec( char *str, const InputLoc &loc, ParseData *pd );
364 Key makeFsmKeyNum( char *str, const InputLoc &loc, ParseData *pd );
365 Key makeFsmKeyChar( char c, ParseData *pd );
366 void makeFsmKeyArray( Key *result, char *data, int len, ParseData *pd );
367 void makeFsmUniqueKeyArray( KeySet &result, char *data, int len, 
368                 bool caseInsensitive, ParseData *pd );
369 FsmAp *makeBuiltin( BuiltinMachine builtin, ParseData *pd );
370 FsmAp *dotFsm( ParseData *pd );
371 FsmAp *dotStarFsm( ParseData *pd );
372
373 void errorStateLabels( const NameSet &locations );
374
375 struct InputItem
376 {
377         enum Type {
378                 HostData,
379                 Write,
380         };
381
382         Type type;
383         std::ostringstream data;
384         std::string name;
385         Vector<char *> writeArgs;
386
387         InputLoc loc;
388
389         InputItem *prev, *next;
390 };
391
392 /*
393  * Global data.
394  */
395
396 struct Parser;
397
398 typedef AvlMap<char*, Parser *, CmpStr> ParserDict;
399 typedef AvlMapEl<char*, Parser *> ParserDictEl;
400
401 typedef DList<InputItem> InputItemList;
402
403 extern ParserDict parserDict;
404 extern InputItemList inputItems;
405
406 #endif /* _PARSEDATA_H */