2 * Copyright 2001-2006 Adrian Thurston <thurston@cs.queensu.ca>
5 /* This file is part of Ragel.
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.
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.
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
35 #include "parsetree.h"
40 /* Nodes in the tree that use this action. */
41 typedef Vector<NameInst*> ActionRefs;
43 /* Element in list of actions. Contains the string for the code to exectute. */
46 public DListEl<Action>,
47 public AvlTreeEl<Action>
51 Action( const InputLoc &loc, char *name, InlineList *inlineList )
55 inlineList(inlineList),
67 /* Key for action dictionary. */
68 char *getKey() const { return name; }
70 /* Data collected during parse. */
73 InlineList *inlineList;
76 void actionName( ostream &out )
81 out << loc.line << ":" << loc.col;
84 /* Places in the input text that reference the action. */
85 ActionRefs actionRefs;
87 /* Number of references in the final machine. */
89 { return numTransRefs + numToStateRefs + numFromStateRefs + numEofRefs; }
100 /* A list of actions. */
101 typedef DList<Action> ActionList;
102 typedef AvlTree<Action, char *, CmpStr> ActionDict;
104 /* Structure for reverse action mapping. */
105 struct RevActionMapEl
115 struct FactorWithAug;
116 struct FactorWithLabel;
117 struct FactorWithRep;
118 struct FactorWithNeg;
127 typedef DList<LongestMatch> LmList;
129 /* Graph dictionary. */
132 public AvlTreeEl<GraphDictEl>,
133 public DListEl<GraphDictEl>
135 GraphDictEl( char *k )
136 : key(k), value(0), isInstance(false) { }
137 GraphDictEl( char *k, VarDef *value )
138 : key(k), value(value), isInstance(false) { }
140 const char *getKey() { return key; }
146 /* Location info of graph definition. Points to variable name of assignment. */
150 typedef AvlTree<GraphDictEl, char*, CmpStr> GraphDict;
151 typedef DList<GraphDictEl> GraphList;
153 /* Priority name dictionary. */
154 typedef AvlMapEl<char*, int> PriorDictEl;
155 typedef AvlMap<char*, int, CmpStr> PriorDict;
157 /* Local error name dictionary. */
158 typedef AvlMapEl<char*, int> LocalErrDictEl;
159 typedef AvlMap<char*, int, CmpStr> LocalErrDict;
161 /* Tree of instantiated names. */
162 typedef BstMapEl<char*, NameInst*> NameMapEl;
163 typedef BstMap<char*, NameInst*, CmpStr> NameMap;
164 typedef Vector<NameInst*> NameVect;
165 typedef BstSet<NameInst*> NameSet;
167 /* Node in the tree of instantiated names. */
170 NameInst( const InputLoc &loc, NameInst *parent, char *name, int id, bool isLabel ) :
171 loc(loc), parent(parent), name(name), id(id), isLabel(isLabel),
172 isLongestMatch(false), numRefs(0), numUses(0), start(0), final(0) {}
176 /* Keep parent pointers in the name tree to retrieve
177 * fully qulified names. */
188 /* Names underneath us, excludes anonymous names. */
191 /* All names underneath us in order of appearance. */
194 /* Join scopes need an implicit "final" target. */
195 NameInst *start, *final;
197 /* During a fsm generation walk, lists the names that are referenced by
198 * epsilon operations in the current scope. After the link is made by the
199 * epsilon reference and the join operation is complete, the label can
200 * have its refcount decremented. Once there are no more references the
201 * entry point can be removed from the fsm returned. */
202 NameVect referencedNames;
204 /* Pointers for the name search queue. */
205 NameInst *prev, *next;
207 /* Check if this name inst or any name inst below is referenced. */
211 typedef DList<NameInst> NameInstList;
213 /* Stack frame used in walking the name tree. */
216 NameInst *prevNameInst;
218 NameInst *prevLocalScope;
221 /* Class to collect information about the machine during the
225 /* Create a new parse data object. This is done at the beginning of every
226 * fsm specification. */
227 ParseData( char *fileName, char *sectionName, const InputLoc §ionLoc );
231 * Setting up the graph dict.
234 /* Initialize a graph dict with the basic fsms. */
235 void initGraphDict();
236 void createBuiltin( char *name, BuiltinMachine builtin );
238 /* Make a name id in the current name instantiation scope if it is not
240 NameInst *addNameInst( const InputLoc &loc, char *data, bool isLabel );
242 void makeNameTree( GraphDictEl *gdNode );
243 void fillNameIndex( NameInst *from );
244 void printNameTree();
246 /* Increments the usage count on entry names. Names that are no longer
247 * needed will have their entry points unset. */
248 void unsetObsoleteEntries( FsmAp *graph );
250 /* Resove name references in action code and epsilon transitions. */
251 NameSet resolvePart( NameInst *refFrom, char *data, bool recLabelsOnly );
252 void resolveFrom( NameSet &result, NameInst *refFrom,
253 const NameRef &nameRef, int namePos );
254 NameInst *resolveStateRef( const NameRef &nameRef, InputLoc &loc, Action *action );
255 void resolveNameRefs( InlineList *inlineList, Action *action );
256 void resolveActionNameRefs();
258 /* Set the alphabet type. If type types are not valid returns false. */
259 bool setAlphType( char *s1, char *s2 );
260 bool setAlphType( char *s1 );
262 /* Unique actions. */
263 void removeDups( ActionTable &actionTable );
264 void removeActionDups( FsmAp *graph );
266 /* Dumping the name instantiation tree. */
267 void printNameInst( NameInst *nameInst, int level );
269 /* Make the graph from a graph dict node. Does minimization. */
270 FsmAp *makeInstance( GraphDictEl *gdNode );
271 FsmAp *makeSpecific( GraphDictEl *gdNode );
274 /* Checking the contents of actions. */
275 void checkAction( Action *action );
276 void checkInlineList( Action *act, InlineList *inlineList );
278 void analyzeAction( Action *action, InlineList *inlineList );
279 void analyzeGraph( FsmAp *graph );
281 void prepareMachineGen( GraphDictEl *graphDictEl );
282 void generateXML( ostream &out );
284 bool generatingSectionSubset;
289 * Data collected during the parse.
292 /* Dictionary of graphs. Both instances and non-instances go here. */
295 /* The list of instances. */
296 GraphList instanceList;
298 /* Dictionary of actions. Lets actions be defined and then referenced. */
299 ActionDict actionDict;
301 /* Dictionary of named priorities. */
304 /* Dictionary of named local errors. */
305 LocalErrDict localErrDict;
307 /* List of actions. Will be pasted into a switch statement. */
308 ActionList actionList;
310 /* The id of the next priority name and label. */
311 int nextPriorKey, nextLocalErrKey, nextNameId;
313 /* The default priority number key for a machine. This is active during
314 * the parse of the rhs of a machine assignment. */
317 int curDefLocalErrKey;
320 HostType *userAlphType;
323 /* Element type and get key expression. */
324 InlineList *getKeyExpr;
325 InlineList *accessExpr;
326 InlineList *curStateExpr;
328 /* The alphabet range. */
329 char *lowerNum, *upperNum;
331 InputLoc rangeLowLoc, rangeHighLoc;
333 /* The name of the file the fsm is from, and the spec name. */
338 /* Number of errors encountered parsing the fsm spec. */
341 /* Counting the action and priority ordering. */
345 /* Root of the name tree. */
347 NameInst *curNameInst;
350 /* The place where resolved epsilon transitions go. These cannot go into
351 * the parse tree because a single epsilon op can resolve more than once
352 * to different nameInsts if the machine it's in is used more than once. */
353 NameVect epsilonResolvedLinks;
354 int nextEpsilonResolvedLink;
356 /* Root of the name tree used for doing local name searches. */
357 NameInst *localNameScope;
359 void setLmInRetLoc( InlineList *inlineList );
360 void initLongestMatchData();
361 void setLongestMatchData( FsmAp *graph );
363 NameInst *nextNameScope() { return curNameInst->childVect[curNameChild]; }
364 NameFrame enterNameScope( bool isLocal, int numScopes );
365 void popNameScope( const NameFrame &frame );
366 void resetNameScope( const NameFrame &frame );
368 /* Make name ids to name inst pointers. */
369 NameInst **nameIndex;
371 /* Counter for assigning ids to longest match items. */
372 int nextLongestMatchId;
373 bool lmRequiresErrorState;
375 /* List of all longest match parse tree items. */
378 Action *newAction( char *name, InlineList *inlineList );
380 Action *initTokStart;
392 void beginProcessing()
394 ::condData = &thisCondData;
395 ::keyOps = &thisKeyOps;
398 CondData thisCondData;
402 void afterOpMinimize( FsmAp *fsm, bool lastInSeq = true );
403 Key makeFsmKeyHex( char *str, const InputLoc &loc, ParseData *pd );
404 Key makeFsmKeyDec( char *str, const InputLoc &loc, ParseData *pd );
405 Key makeFsmKeyNum( char *str, const InputLoc &loc, ParseData *pd );
406 Key makeFsmKeyChar( char c, ParseData *pd );
407 void makeFsmKeyArray( Key *result, char *data, int len, ParseData *pd );
408 void makeFsmUniqueKeyArray( KeySet &result, char *data, int len,
409 bool caseInsensitive, ParseData *pd );
410 FsmAp *makeBuiltin( BuiltinMachine builtin, ParseData *pd );
411 FsmAp *dotFsm( ParseData *pd );
412 FsmAp *dotStarFsm( ParseData *pd );
414 void errorStateLabels( const NameSet &locations );
416 /* Data used by the parser specific to the current file. Supports the include
417 * system, since a new parser is executed for each included file. */
420 InputData( char *fileName, char *includeSpec, char *includeTo ) :
421 pd(0), sectionName(0), defaultParseData(0),
422 first_line(1), first_column(1),
423 last_line(1), last_column(0),
424 fileName(fileName), includeSpec(includeSpec),
425 includeTo(includeTo), active(true)
428 /* For collecting a name references. */
430 NameRefList nameRefList;
432 /* The parse data. For each fsm spec, the parser collects things that it parses
433 * in data structures in here. */
437 ParseData *defaultParseData;
446 /* If this is an included file, this contains the specification to search
447 * for. IncludeTo will contain the spec name that does the includng. */
457 typedef AvlMap<char*, Parser *, CmpStr> ParserDict;
458 typedef AvlMapEl<char*, Parser *> ParserDictEl;
460 extern ParserDict parserDict;
463 #endif /* _PARSEDATA_H */