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
37 #include "mergesort.h"
38 #include "rlcodegen.h"
41 #include "sbsttable.h"
43 #define TRANS_ERR_TRANS 0
44 #define STATE_ERR_STATE 0
45 #define FUNC_NO_FUNC 0
60 Text, Goto, Call, Next, GotoExpr, CallExpr, NextExpr, Ret,
61 PChar, Char, Hold, Exec, HoldTE, ExecTE, Curs, Targs, Entry,
62 LmSwitch, LmSetActId, LmSetTokEnd, LmGetTokEnd, LmInitTokStart,
63 LmInitAct, LmSetTokStart, SubAction, Break
66 InlineItem( const InputLoc &loc, Type type ) :
67 loc(loc), data(0), targId(0), targState(0),
68 lmId(0), children(0), offset(0),
69 handlesError(false), type(type) { }
74 RedStateAp *targState;
81 InlineItem *prev, *next;
84 /* Normally this would be atypedef, but that would entail including DList from
85 * ptreetypes, which should be just typedef forwards. */
86 struct InlineList : public DList<InlineItem> { };
88 /* Element in list of actions. Contains the string for the code to exectute. */
91 public DListEl<Action>
105 /* Data collected during parse. */
108 InlineList *inlineList;
113 /* Number of references in the final machine. */
115 { return numTransRefs + numToStateRefs + numFromStateRefs + numEofRefs; }
118 int numFromStateRefs;
127 /* Transistion Action Element. */
128 typedef SBstMapEl< int, Action* > ActionTableEl;
130 /* Transition Action Table. */
132 : public SBstMap< int, Action*, CmpOrd<int> >
134 void setAction( int ordering, Action *action );
135 void setActions( int *orderings, Action **actions, int nActs );
136 void setActions( const ActionTable &other );
139 /* Compare of a whole action table element (key & value). */
140 struct CmpActionTableEl
142 static int compare( const ActionTableEl &action1,
143 const ActionTableEl &action2 )
145 if ( action1.key < action2.key )
147 else if ( action1.key > action2.key )
149 else if ( action1.value < action2.value )
151 else if ( action1.value > action2.value )
157 /* Compare for ActionTable. */
158 typedef CmpSTable< ActionTableEl, CmpActionTableEl > CmpActionTable;
161 typedef BstSet<RedStateAp*> RedStateSet;
162 typedef BstSet<int> IntSet;
164 /* Reduced action. */
167 public AvlTreeEl<RedAction>
178 bAnyCurStateRef(false),
182 const ActionTable &getKey()
190 /* Number of references in the final machine. */
192 { return numTransRefs + numToStateRefs + numFromStateRefs + numEofRefs; }
195 int numFromStateRefs;
198 bool anyNextStmt() { return bAnyNextStmt; }
199 bool anyCurStateRef() { return bAnyCurStateRef; }
200 bool anyBreakStmt() { return bAnyBreakStmt; }
203 bool bAnyCurStateRef;
206 typedef AvlTree<RedAction, ActionTable, CmpActionTable> ActionTableMap;
208 /* Reduced transition. */
211 public AvlTreeEl<RedTransAp>
213 RedTransAp( RedStateAp *targ, RedAction *action, int id )
214 : targ(targ), action(action), id(id), labelNeeded(true) { }
219 bool partitionBoundary;
223 /* Compare of transitions for the final reduction of transitions. Comparison
224 * is on target and the pointer to the shared action table. It is assumed that
225 * when this is used the action tables have been reduced. */
228 static int compare( const RedTransAp &t1, const RedTransAp &t2 )
230 if ( t1.targ < t2.targ )
232 else if ( t1.targ > t2.targ )
234 else if ( t1.action < t2.action )
236 else if ( t1.action > t2.action )
243 typedef AvlBasic<RedTransAp, CmpRedTransAp> TransApSet;
245 /* Element in out range. */
249 RedTransEl( Key lowKey, Key highKey, RedTransAp *value )
250 : lowKey(lowKey), highKey(highKey), value(value) { }
256 typedef Vector<RedTransEl> RedTransList;
257 typedef Vector<RedStateAp*> RedStateVect;
259 typedef BstMapEl<RedStateAp*, unsigned long long> RedSpanMapEl;
260 typedef BstMap<RedStateAp*, unsigned long long> RedSpanMap;
262 /* Compare used by span map sort. Reverse sorts by the span. */
263 struct CmpRedSpanMapEl
265 static int compare( const RedSpanMapEl &smel1, const RedSpanMapEl &smel2 )
267 if ( smel1.value > smel2.value )
269 else if ( smel1.value < smel2.value )
276 /* Sorting state-span map entries by span. */
277 typedef MergeSort<RedSpanMapEl, CmpRedSpanMapEl> RedSpanMapSort;
279 /* Set of entry ids that go into this state. */
280 typedef Vector<int> EntryIdVect;
281 typedef Vector<char*> EntryNameVect;
283 typedef Vector< Action* > CondSet;
288 : key(0), baseKey(0) {}
294 Condition *next, *prev;
296 typedef DList<Condition> ConditionList;
304 CondSpace *next, *prev;
306 typedef DList<CondSpace> CondSpaceList;
313 CondSpace *condSpace;
315 StateCond *prev, *next;
317 typedef DList<StateCond> StateCondList;
318 typedef Vector<StateCond*> StateCondVect;
336 bAnyRegCurStateRef(false),
337 partitionBoundary(false),
342 /* Transitions out. */
343 RedTransList outSingle;
344 RedTransList outRange;
345 RedTransAp *defTrans;
347 /* For flat conditions. */
348 Key condLowKey, condHighKey;
349 CondSpace **condList;
353 RedTransAp **transList;
355 /* The list of states that transitions from this state go to. */
356 RedStateVect targStates;
362 RedAction *toStateAction;
363 RedAction *fromStateAction;
364 RedAction *eofAction;
366 StateCondList stateCondList;
367 StateCondVect stateCondVect;
369 /* Pointers for the list of states. */
370 RedStateAp *prev, *next;
372 bool anyRegCurStateRef() { return bAnyRegCurStateRef; }
373 bool bAnyRegCurStateRef;
376 bool partitionBoundary;
378 RedTransAp **inTrans;
382 /* List of states. */
383 typedef DList<RedStateAp> RedStateList;
385 /* Set of reduced transitons. Comparison is by pointer. */
386 typedef BstSet< RedTransAp*, CmpOrd<RedTransAp*> > RedTransSet;
388 /* Next version of the fsm machine. */
394 bool forcedErrorState;
399 /* Next State Id doubles as the total number of state ids. */
403 ActionTableMap actionMap;
404 RedStateList stateList;
405 RedStateSet entryPoints;
406 RedStateAp *startState;
407 RedStateAp *errState;
408 RedTransAp *errTrans;
409 RedTransAp *errActionTrans;
410 RedStateAp *firstFinState;
414 /* Is is it possible to extend a range by bumping ranges that span only
415 * one character to the singles array. */
416 bool canExtend( const RedTransList &list, int pos );
418 /* Pick single transitions from the ranges. */
419 void moveTransToSingle( RedStateAp *state );
424 /* Move a selected transition from ranges to default. */
425 void moveToDefault( RedTransAp *defTrans, RedStateAp *state );
427 /* Pick a default transition by largest span. */
428 RedTransAp *chooseDefaultSpan( RedStateAp *state );
429 void chooseDefaultSpan();
431 /* Pick a default transition by most number of ranges. */
432 RedTransAp *chooseDefaultNumRanges( RedStateAp *state );
433 void chooseDefaultNumRanges();
435 /* Pick a default transition tailored towards goto driven machine. */
436 RedTransAp *chooseDefaultGoto( RedStateAp *state );
437 void chooseDefaultGoto();
439 /* Ordering states by transition connections. */
440 void optimizeStateOrdering( RedStateAp *state );
441 void optimizeStateOrdering();
443 /* Ordering states by transition connections. */
444 void depthFirstOrdering( RedStateAp *state );
445 void depthFirstOrdering();
448 void sequentialStateIds();
449 void sortStateIdsByFinal();
451 /* Arrange states in by final id. This is a stable sort. */
452 void sortStatesByFinal();
454 /* Locating the first final state. This is the final state with the lowest
456 void findFirstFinState();
458 void assignActionLocs();
460 RedTransAp *getErrorTrans();
461 RedStateAp *getErrorState();
463 /* Is every char in the alphabet covered? */
464 bool alphabetCovered( RedTransList &outRange );
466 RedTransAp *allocateTrans( RedStateAp *targState, RedAction *actionTable );
468 void partitionFsm( int nParts );
474 #endif /* _REDFSM_H */