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"
40 #include "sbsttable.h"
42 #define TRANS_ERR_TRANS 0
43 #define STATE_ERR_STATE 0
44 #define FUNC_NO_FUNC 0
52 /* Location in an input file. */
66 Text, Goto, Call, Next, GotoExpr, CallExpr, NextExpr, Ret,
67 PChar, Char, Hold, Exec, HoldTE, ExecTE, Curs, Targs, Entry,
68 LmSwitch, LmSetActId, LmSetTokEnd, LmGetTokEnd, LmInitTokStart,
69 LmInitAct, LmSetTokStart, SubAction, Break
72 InlineItem( const InputLoc &loc, Type type ) :
73 loc(loc), data(0), targId(0), targState(0),
74 lmId(0), children(0), offset(0),
75 handlesError(false), type(type) { }
80 RedStateAp *targState;
87 InlineItem *prev, *next;
90 /* Normally this would be atypedef, but that would entail including DList from
91 * ptreetypes, which should be just typedef forwards. */
92 struct InlineList : public DList<InlineItem> { };
94 /* Element in list of actions. Contains the string for the code to exectute. */
97 public DListEl<Action>
111 /* Data collected during parse. */
114 InlineList *inlineList;
119 /* Number of references in the final machine. */
121 { return numTransRefs + numToStateRefs + numFromStateRefs + numEofRefs; }
124 int numFromStateRefs;
133 /* Transistion Action Element. */
134 typedef SBstMapEl< int, Action* > ActionTableEl;
136 /* Transition Action Table. */
138 : public SBstMap< int, Action*, CmpOrd<int> >
140 void setAction( int ordering, Action *action );
141 void setActions( int *orderings, Action **actions, int nActs );
142 void setActions( const ActionTable &other );
145 /* Compare of a whole action table element (key & value). */
146 struct CmpActionTableEl
148 static int compare( const ActionTableEl &action1,
149 const ActionTableEl &action2 )
151 if ( action1.key < action2.key )
153 else if ( action1.key > action2.key )
155 else if ( action1.value < action2.value )
157 else if ( action1.value > action2.value )
163 /* Compare for ActionTable. */
164 typedef CmpSTable< ActionTableEl, CmpActionTableEl > CmpActionTable;
167 typedef BstSet<RedStateAp*> RedStateSet;
168 typedef BstSet<int> IntSet;
170 /* Reduced action. */
173 public AvlTreeEl<RedAction>
184 bAnyCurStateRef(false),
188 const ActionTable &getKey()
196 /* Number of references in the final machine. */
198 { return numTransRefs + numToStateRefs + numFromStateRefs + numEofRefs; }
201 int numFromStateRefs;
204 bool anyNextStmt() { return bAnyNextStmt; }
205 bool anyCurStateRef() { return bAnyCurStateRef; }
206 bool anyBreakStmt() { return bAnyBreakStmt; }
209 bool bAnyCurStateRef;
212 typedef AvlTree<RedAction, ActionTable, CmpActionTable> ActionTableMap;
214 /* Reduced transition. */
217 public AvlTreeEl<RedTransAp>
219 RedTransAp( RedStateAp *targ, RedAction *action, int id )
220 : targ(targ), action(action), id(id), labelNeeded(true) { }
225 bool partitionBoundary;
229 /* Compare of transitions for the final reduction of transitions. Comparison
230 * is on target and the pointer to the shared action table. It is assumed that
231 * when this is used the action tables have been reduced. */
234 static int compare( const RedTransAp &t1, const RedTransAp &t2 )
236 if ( t1.targ < t2.targ )
238 else if ( t1.targ > t2.targ )
240 else if ( t1.action < t2.action )
242 else if ( t1.action > t2.action )
249 typedef AvlBasic<RedTransAp, CmpRedTransAp> TransApSet;
251 /* Element in out range. */
255 RedTransEl( Key lowKey, Key highKey, RedTransAp *value )
256 : lowKey(lowKey), highKey(highKey), value(value) { }
262 typedef Vector<RedTransEl> RedTransList;
263 typedef Vector<RedStateAp*> RedStateVect;
265 typedef BstMapEl<RedStateAp*, unsigned long long> RedSpanMapEl;
266 typedef BstMap<RedStateAp*, unsigned long long> RedSpanMap;
268 /* Compare used by span map sort. Reverse sorts by the span. */
269 struct CmpRedSpanMapEl
271 static int compare( const RedSpanMapEl &smel1, const RedSpanMapEl &smel2 )
273 if ( smel1.value > smel2.value )
275 else if ( smel1.value < smel2.value )
282 /* Sorting state-span map entries by span. */
283 typedef MergeSort<RedSpanMapEl, CmpRedSpanMapEl> RedSpanMapSort;
285 /* Set of entry ids that go into this state. */
286 typedef Vector<int> EntryIdVect;
287 typedef Vector<char*> EntryNameVect;
289 typedef Vector< Action* > CondSet;
294 : key(0), baseKey(0) {}
300 Condition *next, *prev;
302 typedef DList<Condition> ConditionList;
310 CondSpace *next, *prev;
312 typedef DList<CondSpace> CondSpaceList;
319 CondSpace *condSpace;
321 StateCond *prev, *next;
323 typedef DList<StateCond> StateCondList;
324 typedef Vector<StateCond*> StateCondVect;
342 bAnyRegCurStateRef(false),
343 partitionBoundary(false),
348 /* Transitions out. */
349 RedTransList outSingle;
350 RedTransList outRange;
351 RedTransAp *defTrans;
353 /* For flat conditions. */
354 Key condLowKey, condHighKey;
355 CondSpace **condList;
359 RedTransAp **transList;
361 /* The list of states that transitions from this state go to. */
362 RedStateVect targStates;
368 RedAction *toStateAction;
369 RedAction *fromStateAction;
370 RedAction *eofAction;
372 StateCondList stateCondList;
373 StateCondVect stateCondVect;
375 /* Pointers for the list of states. */
376 RedStateAp *prev, *next;
378 bool anyRegCurStateRef() { return bAnyRegCurStateRef; }
379 bool bAnyRegCurStateRef;
382 bool partitionBoundary;
384 RedTransAp **inTrans;
388 /* List of states. */
389 typedef DList<RedStateAp> RedStateList;
391 /* Set of reduced transitons. Comparison is by pointer. */
392 typedef BstSet< RedTransAp*, CmpOrd<RedTransAp*> > RedTransSet;
394 /* Next version of the fsm machine. */
400 bool forcedErrorState;
405 /* Next State Id doubles as the total number of state ids. */
409 ActionTableMap actionMap;
410 RedStateList stateList;
411 RedStateSet entryPoints;
412 RedStateAp *startState;
413 RedStateAp *errState;
414 RedTransAp *errTrans;
415 RedTransAp *errActionTrans;
416 RedStateAp *firstFinState;
420 bool bAnyToStateActions;
421 bool bAnyFromStateActions;
424 bool bAnyActionGotos;
425 bool bAnyActionCalls;
427 bool bAnyRegActionRets;
428 bool bAnyRegActionByValControl;
429 bool bAnyRegNextStmt;
430 bool bAnyRegCurStateRef;
432 bool bAnyLmSwitchError;
444 unsigned long long maxSpan;
445 unsigned long long maxCondSpan;
446 int maxFlatIndexOffset;
451 int maxCondIndexOffset;
455 bool anyToStateActions() { return bAnyToStateActions; }
456 bool anyFromStateActions() { return bAnyFromStateActions; }
457 bool anyRegActions() { return bAnyRegActions; }
458 bool anyEofActions() { return bAnyEofActions; }
459 bool anyActionGotos() { return bAnyActionGotos; }
460 bool anyActionCalls() { return bAnyActionCalls; }
461 bool anyActionRets() { return bAnyActionRets; }
462 bool anyRegActionRets() { return bAnyRegActionRets; }
463 bool anyRegActionByValControl() { return bAnyRegActionByValControl; }
464 bool anyRegNextStmt() { return bAnyRegNextStmt; }
465 bool anyRegCurStateRef() { return bAnyRegCurStateRef; }
466 bool anyRegBreak() { return bAnyRegBreak; }
467 bool anyLmSwitchError() { return bAnyLmSwitchError; }
468 bool anyConditions() { return bAnyConditions; }
471 /* Is is it possible to extend a range by bumping ranges that span only
472 * one character to the singles array. */
473 bool canExtend( const RedTransList &list, int pos );
475 /* Pick single transitions from the ranges. */
476 void moveTransToSingle( RedStateAp *state );
481 /* Move a selected transition from ranges to default. */
482 void moveToDefault( RedTransAp *defTrans, RedStateAp *state );
484 /* Pick a default transition by largest span. */
485 RedTransAp *chooseDefaultSpan( RedStateAp *state );
486 void chooseDefaultSpan();
488 /* Pick a default transition by most number of ranges. */
489 RedTransAp *chooseDefaultNumRanges( RedStateAp *state );
490 void chooseDefaultNumRanges();
492 /* Pick a default transition tailored towards goto driven machine. */
493 RedTransAp *chooseDefaultGoto( RedStateAp *state );
494 void chooseDefaultGoto();
496 /* Ordering states by transition connections. */
497 void optimizeStateOrdering( RedStateAp *state );
498 void optimizeStateOrdering();
500 /* Ordering states by transition connections. */
501 void depthFirstOrdering( RedStateAp *state );
502 void depthFirstOrdering();
505 void sequentialStateIds();
506 void sortStateIdsByFinal();
508 /* Arrange states in by final id. This is a stable sort. */
509 void sortStatesByFinal();
511 /* Locating the first final state. This is the final state with the lowest
513 void findFirstFinState();
515 void assignActionLocs();
517 RedTransAp *getErrorTrans();
518 RedStateAp *getErrorState();
520 /* Is every char in the alphabet covered? */
521 bool alphabetCovered( RedTransList &outRange );
523 RedTransAp *allocateTrans( RedStateAp *targState, RedAction *actionTable );
525 void partitionFsm( int nParts );
531 #endif /* _REDFSM_H */