Need to unset the final state status of the start state in kleene star.
[external/ragel.git] / ragel / parsetree.h
1 /*
2  *  Copyright 2001-2006 Adrian Thurston <thurston@cs.queensu.ca>
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 _PARSETREE_H
23 #define _PARSETREE_H
24
25 #include "ragel.h"
26 #include "avlmap.h"
27 #include "bstmap.h"
28 #include "vector.h"
29 #include "dlist.h"
30
31 struct NameInst;
32
33 /* Types of builtin machines. */
34 enum BuiltinMachine
35 {
36         BT_Any,
37         BT_Ascii,
38         BT_Extend,
39         BT_Alpha,
40         BT_Digit,
41         BT_Alnum,
42         BT_Lower,
43         BT_Upper,
44         BT_Cntrl,
45         BT_Graph,
46         BT_Print,
47         BT_Punct,
48         BT_Space,
49         BT_Xdigit,
50         BT_Lambda,
51         BT_Empty
52 };
53
54
55 struct ParseData;
56
57 /* Leaf type. */
58 struct Literal;
59
60 /* Tree nodes. */
61
62 struct Term;
63 struct FactorWithAug;
64 struct FactorWithRep;
65 struct FactorWithNeg;
66 struct Factor;
67 struct Expression;
68 struct Join;
69 struct JoinOrLm;
70 struct LongestMatch;
71 struct LongestMatchPart;
72 struct LmPartList;
73 struct Range;
74
75 /* Type of augmentation. Describes locations in the machine. */
76 enum AugType
77 {
78         /* Transition actions/priorities. */
79         at_start,
80         at_all,
81         at_finish,
82         at_leave,
83
84         /* Global error actions. */
85         at_start_gbl_error,
86         at_all_gbl_error,
87         at_final_gbl_error,
88         at_not_start_gbl_error,
89         at_not_final_gbl_error,
90         at_middle_gbl_error,
91
92         /* Local error actions. */
93         at_start_local_error,
94         at_all_local_error,
95         at_final_local_error,
96         at_not_start_local_error,
97         at_not_final_local_error,
98         at_middle_local_error,
99         
100         /* To State Action embedding. */
101         at_start_to_state,
102         at_all_to_state,
103         at_final_to_state,
104         at_not_start_to_state,
105         at_not_final_to_state,
106         at_middle_to_state,
107
108         /* From State Action embedding. */
109         at_start_from_state,
110         at_all_from_state,
111         at_final_from_state,
112         at_not_start_from_state,
113         at_not_final_from_state,
114         at_middle_from_state,
115
116         /* EOF Action embedding. */
117         at_start_eof,
118         at_all_eof,
119         at_final_eof,
120         at_not_start_eof,
121         at_not_final_eof,
122         at_middle_eof
123 };
124
125 /* IMPORTANT: These must follow the same order as the state augs in AugType
126  * since we will be using this to compose AugType. */
127 enum StateAugType
128 {
129         sat_start = 0,
130         sat_all,
131         sat_final,
132         sat_not_start,
133         sat_not_final,
134         sat_middle
135 };
136
137 struct Action;
138 struct PriorDesc;
139 struct RegExpr;
140 struct ReItem;
141 struct ReOrBlock;
142 struct ReOrItem;
143 struct ExplicitMachine;
144 struct InlineItem;
145 struct InlineList;
146
147 /* Reference to a named state. */
148 typedef Vector<char*> NameRef;
149 typedef Vector<NameRef*> NameRefList;
150 typedef Vector<NameInst*> NameTargList;
151
152 /* Structure for storing location of epsilon transitons. */
153 struct EpsilonLink
154 {
155         EpsilonLink( const InputLoc &loc, NameRef &target )
156                 : loc(loc), target(target) { }
157
158         InputLoc loc;
159         NameRef target;
160 };
161
162 struct Label
163 {
164         Label( const InputLoc &loc, char *data )
165                 : loc(loc), data(data) { }
166
167         InputLoc loc;
168         char *data;
169 };
170
171 /* Structrue represents an action assigned to some FactorWithAug node. The
172  * factor with aug will keep an array of these. */
173 struct ParserAction
174 {
175         ParserAction( const InputLoc &loc, AugType type, int localErrKey, Action *action )
176                 : loc(loc), type(type), localErrKey(localErrKey), action(action) { }
177
178         InputLoc loc;
179         AugType type;
180         int localErrKey;
181         Action *action;
182 };
183
184 struct ConditionTest
185 {
186         ConditionTest( const InputLoc &loc, AugType type, Action *action, bool sense ) : 
187                 loc(loc), type(type), action(action), sense(sense) { }
188
189         InputLoc loc;
190         AugType type;
191         Action *action;
192         bool sense;
193 };
194
195 struct Token
196 {
197         char *data;
198         int length;
199         InputLoc loc;
200
201         void prepareLitString( Token &result, bool &caseInsensitive );
202         void append( const Token &other );
203         void set( const char *str, int len );
204 };
205
206 /* Store the value and type of a priority augmentation. */
207 struct PriorityAug
208 {
209         PriorityAug( AugType type, int priorKey, int priorValue ) :
210                 type(type), priorKey(priorKey), priorValue(priorValue) { }
211
212         AugType type;
213         int priorKey;
214         int priorValue;
215 };
216
217 /*
218  * A Variable Definition
219  */
220 struct VarDef
221 {
222         VarDef( const char *name, JoinOrLm *joinOrLm )
223                 : name(name), joinOrLm(joinOrLm), isExport(false) { }
224         
225         /* Parse tree traversal. */
226         FsmAp *walk( ParseData *pd );
227         void makeNameTree( const InputLoc &loc, ParseData *pd );
228         void resolveNameRefs( ParseData *pd );
229
230         const char *name;
231         JoinOrLm *joinOrLm;
232         bool isExport;
233 };
234
235
236 /*
237  * LongestMatch
238  *
239  * Wherever possible the item match will execute on the character. If not
240  * possible the item match will execute on a lookahead character and either
241  * hold the current char (if one away) or backup.
242  *
243  * How to handle the problem of backing up over a buffer break?
244  * 
245  * Don't want to use pending out transitions for embedding item match because
246  * the role of item match action is different: it may sometimes match on the
247  * final transition, or may match on a lookahead character.
248  *
249  * Don't want to invent a new operator just for this. So just trail action
250  * after machine, this means we can only use literal actions.
251  *
252  * The item action may 
253  *
254  * What states of the machine will be final. The item actions that wrap around
255  * on the last character will go straight to the start state.
256  *
257  * Some transitions will be lookahead transitions, they will hold the current
258  * character. Crossing them with regular transitions must be restricted
259  * because it does not make sense. The transition cannot simultaneously hold
260  * and consume the current character.
261  */
262 struct LongestMatchPart
263 {
264         LongestMatchPart( Join *join, Action *action, 
265                         InputLoc &semiLoc, int longestMatchId )
266         : 
267                 join(join), action(action), semiLoc(semiLoc), 
268                 longestMatchId(longestMatchId), inLmSelect(false) { }
269
270         InputLoc getLoc();
271         
272         Join *join;
273         Action *action;
274         InputLoc semiLoc;
275
276         Action *setActId;
277         Action *actOnLast;
278         Action *actOnNext;
279         Action *actLagBehind;
280         int longestMatchId;
281         bool inLmSelect;
282         LongestMatch *longestMatch;
283
284         LongestMatchPart *prev, *next;
285 };
286
287 /* Declare a new type so that ptreetypes.h need not include dlist.h. */
288 struct LmPartList : DList<LongestMatchPart> {};
289
290 struct LongestMatch
291 {
292         /* Construct with a list of joins */
293         LongestMatch( const InputLoc &loc, LmPartList *longestMatchList ) : 
294                 loc(loc), longestMatchList(longestMatchList), name(0), 
295                 lmSwitchHandlesError(false) { }
296
297         /* Tree traversal. */
298         FsmAp *walk( ParseData *pd );
299         void makeNameTree( ParseData *pd );
300         void resolveNameRefs( ParseData *pd );
301         void transferScannerLeavingActions( FsmAp *graph );
302         void runLongestMatch( ParseData *pd, FsmAp *graph );
303         Action *newAction( ParseData *pd, const InputLoc &loc, const char *name, 
304                         InlineList *inlineList );
305         void makeActions( ParseData *pd );
306         void findName( ParseData *pd );
307         void restart( FsmAp *graph, TransAp *trans );
308
309         InputLoc loc;
310         LmPartList *longestMatchList;
311         const char *name;
312
313         Action *lmActSelect;
314         bool lmSwitchHandlesError;
315
316         LongestMatch *next, *prev;
317 };
318
319
320 /* List of Expressions. */
321 typedef DList<Expression> ExprList;
322
323 struct JoinOrLm
324 {
325         enum Type {
326                 JoinType,
327                 LongestMatchType
328         };
329
330         JoinOrLm( Join *join ) : 
331                 join(join), type(JoinType) {}
332         JoinOrLm( LongestMatch *longestMatch ) :
333                 longestMatch(longestMatch), type(LongestMatchType) {}
334
335         FsmAp *walk( ParseData *pd );
336         void makeNameTree( ParseData *pd );
337         void resolveNameRefs( ParseData *pd );
338         
339         Join *join;
340         LongestMatch *longestMatch;
341         Type type;
342 };
343
344 /*
345  * Join
346  */
347 struct Join
348 {
349         /* Construct with the first expression. */
350         Join( Expression *expr );
351         Join( const InputLoc &loc, Expression *expr );
352
353         /* Tree traversal. */
354         FsmAp *walk( ParseData *pd );
355         FsmAp *walkJoin( ParseData *pd );
356         void makeNameTree( ParseData *pd );
357         void resolveNameRefs( ParseData *pd );
358
359         /* Data. */
360         InputLoc loc;
361         ExprList exprList;
362 };
363
364 /*
365  * Expression
366  */
367 struct Expression
368 {
369         enum Type { 
370                 OrType,
371                 IntersectType, 
372                 SubtractType, 
373                 StrongSubtractType,
374                 TermType, 
375                 BuiltinType
376         };
377
378         /* Construct with an expression on the left and a term on the right. */
379         Expression( Expression *expression, Term *term, Type type ) : 
380                 expression(expression), term(term), 
381                 builtin(builtin), type(type), prev(this), next(this) { }
382
383         /* Construct with only a term. */
384         Expression( Term *term ) : 
385                 expression(0), term(term), builtin(builtin), 
386                 type(TermType) , prev(this), next(this) { }
387         
388         /* Construct with a builtin type. */
389         Expression( BuiltinMachine builtin ) : 
390                 expression(0), term(0), builtin(builtin), 
391                 type(BuiltinType), prev(this), next(this) { }
392
393         ~Expression();
394
395         /* Tree traversal. */
396         FsmAp *walk( ParseData *pd, bool lastInSeq = true );
397         void makeNameTree( ParseData *pd );
398         void resolveNameRefs( ParseData *pd );
399
400         /* Node data. */
401         Expression *expression;
402         Term *term;
403         BuiltinMachine builtin;
404         Type type;
405
406         Expression *prev, *next;
407 };
408
409 /*
410  * Term
411  */
412 struct Term 
413 {
414         enum Type { 
415                 ConcatType, 
416                 RightStartType,
417                 RightFinishType,
418                 LeftType,
419                 FactorWithAugType
420         };
421
422         Term( Term *term, FactorWithAug *factorWithAug ) :
423                 term(term), factorWithAug(factorWithAug), type(ConcatType) { }
424
425         Term( Term *term, FactorWithAug *factorWithAug, Type type ) :
426                 term(term), factorWithAug(factorWithAug), type(type) { }
427
428         Term( FactorWithAug *factorWithAug ) :
429                 term(0), factorWithAug(factorWithAug), type(FactorWithAugType) { }
430         
431         ~Term();
432
433         FsmAp *walk( ParseData *pd, bool lastInSeq = true );
434         void makeNameTree( ParseData *pd );
435         void resolveNameRefs( ParseData *pd );
436
437         Term *term;
438         FactorWithAug *factorWithAug;
439         Type type;
440
441         /* Priority descriptor for RightFinish type. */
442         PriorDesc priorDescs[2];
443 };
444
445
446 /* Third level of precedence. Augmenting nodes with actions and priorities. */
447 struct FactorWithAug
448 {
449         FactorWithAug( FactorWithRep *factorWithRep ) :
450                 priorDescs(0), factorWithRep(factorWithRep) { }
451         ~FactorWithAug();
452
453         /* Tree traversal. */
454         FsmAp *walk( ParseData *pd );
455         void makeNameTree( ParseData *pd );
456         void resolveNameRefs( ParseData *pd );
457
458         void assignActions( ParseData *pd, FsmAp *graph, int *actionOrd );
459         void assignPriorities( FsmAp *graph, int *priorOrd );
460
461         void assignConditions( FsmAp *graph );
462
463         /* Actions and priorities assigned to the factor node. */
464         Vector<ParserAction> actions;
465         Vector<PriorityAug> priorityAugs;
466         PriorDesc *priorDescs;
467         Vector<Label> labels;
468         Vector<EpsilonLink> epsilonLinks;
469         Vector<ConditionTest> conditions;
470
471         FactorWithRep *factorWithRep;
472 };
473
474 /* Fourth level of precedence. Trailing unary operators. Provide kleen star,
475  * optional and plus. */
476 struct FactorWithRep
477 {
478         enum Type { 
479                 StarType,
480                 StarStarType,
481                 OptionalType,
482                 PlusType, 
483                 ExactType,
484                 MaxType,
485                 MinType,
486                 RangeType,
487                 FactorWithNegType
488         };
489
490          FactorWithRep( const InputLoc &loc, FactorWithRep *factorWithRep, 
491                         int lowerRep, int upperRep, Type type ) :
492                 loc(loc), factorWithRep(factorWithRep), 
493                 factorWithNeg(0), lowerRep(lowerRep), 
494                 upperRep(upperRep), type(type) { }
495         
496         FactorWithRep( FactorWithNeg *factorWithNeg )
497                 : factorWithNeg(factorWithNeg), type(FactorWithNegType) { }
498
499         ~FactorWithRep();
500
501         /* Tree traversal. */
502         FsmAp *walk( ParseData *pd );
503         void makeNameTree( ParseData *pd );
504         void resolveNameRefs( ParseData *pd );
505
506         InputLoc loc;
507         FactorWithRep *factorWithRep;
508         FactorWithNeg *factorWithNeg;
509         int lowerRep, upperRep;
510         Type type;
511
512         /* Priority descriptor for StarStar type. */
513         PriorDesc priorDescs[2];
514 };
515
516 /* Fifth level of precedence. Provides Negation. */
517 struct FactorWithNeg
518 {
519         enum Type { 
520                 NegateType, 
521                 CharNegateType,
522                 FactorType
523         };
524
525         FactorWithNeg( const InputLoc &loc, FactorWithNeg *factorWithNeg, Type type) :
526                 loc(loc), factorWithNeg(factorWithNeg), factor(0), type(type) { }
527
528         FactorWithNeg( Factor *factor ) :
529                 factorWithNeg(0), factor(factor), type(FactorType) { }
530
531         ~FactorWithNeg();
532
533         /* Tree traversal. */
534         FsmAp *walk( ParseData *pd );
535         void makeNameTree( ParseData *pd );
536         void resolveNameRefs( ParseData *pd );
537
538         InputLoc loc;
539         FactorWithNeg *factorWithNeg;
540         Factor *factor;
541         Type type;
542 };
543
544 /*
545  * Factor
546  */
547 struct Factor
548 {
549         /* Language elements a factor node can be. */
550         enum Type {
551                 LiteralType, 
552                 RangeType, 
553                 OrExprType,
554                 RegExprType, 
555                 ReferenceType,
556                 ParenType,
557                 LongestMatchType,
558         }; 
559
560         /* Construct with a literal fsm. */
561         Factor( Literal *literal ) :
562                 literal(literal), type(LiteralType) { }
563
564         /* Construct with a range. */
565         Factor( Range *range ) : 
566                 range(range), type(RangeType) { }
567         
568         /* Construct with the or part of a regular expression. */
569         Factor( ReItem *reItem ) :
570                 reItem(reItem), type(OrExprType) { }
571
572         /* Construct with a regular expression. */
573         Factor( RegExpr *regExpr ) :
574                 regExpr(regExpr), type(RegExprType) { }
575
576         /* Construct with a reference to a var def. */
577         Factor( const InputLoc &loc, VarDef *varDef ) :
578                 loc(loc), varDef(varDef), type(ReferenceType) {}
579
580         /* Construct with a parenthesized join. */
581         Factor( Join *join ) :
582                 join(join), type(ParenType) {}
583         
584         /* Construct with a longest match operator. */
585         Factor( LongestMatch *longestMatch ) :
586                 longestMatch(longestMatch), type(LongestMatchType) {}
587
588         /* Cleanup. */
589         ~Factor();
590
591         /* Tree traversal. */
592         FsmAp *walk( ParseData *pd );
593         void makeNameTree( ParseData *pd );
594         void resolveNameRefs( ParseData *pd );
595
596         InputLoc loc;
597         Literal *literal;
598         Range *range;
599         ReItem *reItem;
600         RegExpr *regExpr;
601         VarDef *varDef;
602         Join *join;
603         LongestMatch *longestMatch;
604         int lower, upper;
605         Type type;
606 };
607
608 /* A range machine. Only ever composed of two literals. */
609 struct Range
610 {
611         Range( Literal *lowerLit, Literal *upperLit ) 
612                 : lowerLit(lowerLit), upperLit(upperLit) { }
613
614         ~Range();
615         FsmAp *walk( ParseData *pd );
616
617         Literal *lowerLit;
618         Literal *upperLit;
619 };
620
621 /* Some literal machine. Can be a number or literal string. */
622 struct Literal
623 {
624         enum LiteralType { Number, LitString };
625
626         Literal( const Token &token, LiteralType type )
627                 : token(token), type(type) { }
628
629         FsmAp *walk( ParseData *pd );
630         
631         Token token;
632         LiteralType type;
633 };
634
635 /* Regular expression. */
636 struct RegExpr
637 {
638         enum RegExpType { RecurseItem, Empty };
639
640         /* Constructors. */
641         RegExpr() : 
642                 type(Empty), caseInsensitive(false) { }
643         RegExpr(RegExpr *regExpr, ReItem *item) : 
644                 regExpr(regExpr), item(item), 
645                 type(RecurseItem), caseInsensitive(false) { }
646
647         ~RegExpr();
648         FsmAp *walk( ParseData *pd, RegExpr *rootRegex );
649
650         RegExpr *regExpr;
651         ReItem *item;
652         RegExpType type;
653         bool caseInsensitive;
654 };
655
656 /* An item in a regular expression. */
657 struct ReItem
658 {
659         enum ReItemType { Data, Dot, OrBlock, NegOrBlock };
660         
661         ReItem( const InputLoc &loc, const Token &token ) 
662                 : loc(loc), token(token), star(false), type(Data) { }
663         ReItem( const InputLoc &loc, ReItemType type )
664                 : loc(loc), star(false), type(type) { }
665         ReItem( const InputLoc &loc, ReOrBlock *orBlock, ReItemType type )
666                 : loc(loc), orBlock(orBlock), star(false), type(type) { }
667
668         ~ReItem();
669         FsmAp *walk( ParseData *pd, RegExpr *rootRegex );
670
671         InputLoc loc;
672         Token token;
673         ReOrBlock *orBlock;
674         bool star;
675         ReItemType type;
676 };
677
678 /* An or block item. */
679 struct ReOrBlock
680 {
681         enum ReOrBlockType { RecurseItem, Empty };
682
683         /* Constructors. */
684         ReOrBlock()
685                 : type(Empty) { }
686         ReOrBlock(ReOrBlock *orBlock, ReOrItem *item)
687                 : orBlock(orBlock), item(item), type(RecurseItem) { }
688
689         ~ReOrBlock();
690         FsmAp *walk( ParseData *pd, RegExpr *rootRegex );
691         
692         ReOrBlock *orBlock;
693         ReOrItem *item;
694         ReOrBlockType type;
695 };
696
697 /* An item in an or block. */
698 struct ReOrItem
699 {
700         enum ReOrItemType { Data, Range };
701
702         ReOrItem( const InputLoc &loc, const Token &token ) 
703                 : loc(loc), token(token), type(Data) {}
704         ReOrItem( const InputLoc &loc, char lower, char upper )
705                 : loc(loc), lower(lower), upper(upper), type(Range) { }
706
707         FsmAp *walk( ParseData *pd, RegExpr *rootRegex );
708
709         InputLoc loc;
710         Token token;
711         char lower;
712         char upper;
713         ReOrItemType type;
714 };
715
716
717 /*
718  * Inline code tree
719  */
720 struct InlineList;
721 struct InlineItem
722 {
723         enum Type 
724         {
725                 Text, Goto, Call, Next, GotoExpr, CallExpr, NextExpr, Ret, PChar,
726                 Char, Hold, Curs, Targs, Entry, Exec, LmSwitch, LmSetActId,
727                 LmSetTokEnd, LmOnLast, LmOnNext, LmOnLagBehind, LmInitAct,
728                 LmInitTokStart, LmSetTokStart, Break
729         };
730
731         InlineItem( const InputLoc &loc, char *data, Type type ) : 
732                 loc(loc), data(data), nameRef(0), children(0), type(type) { }
733
734         InlineItem( const InputLoc &loc, NameRef *nameRef, Type type ) : 
735                 loc(loc), data(0), nameRef(nameRef), children(0), type(type) { }
736
737         InlineItem( const InputLoc &loc, LongestMatch *longestMatch, 
738                 LongestMatchPart *longestMatchPart, Type type ) : loc(loc), data(0),
739                 nameRef(0), children(0), longestMatch(longestMatch),
740                 longestMatchPart(longestMatchPart), type(type) { } 
741
742         InlineItem( const InputLoc &loc, NameInst *nameTarg, Type type ) : 
743                 loc(loc), data(0), nameRef(0), nameTarg(nameTarg), children(0),
744                 type(type) { }
745
746         InlineItem( const InputLoc &loc, Type type ) : 
747                 loc(loc), data(0), nameRef(0), children(0), type(type) { }
748         
749         InputLoc loc;
750         char *data;
751         NameRef *nameRef;
752         NameInst *nameTarg;
753         InlineList *children;
754         LongestMatch *longestMatch;
755         LongestMatchPart *longestMatchPart;
756         Type type;
757
758         InlineItem *prev, *next;
759 };
760
761 /* Normally this would be atypedef, but that would entail including DList from
762  * ptreetypes, which should be just typedef forwards. */
763 struct InlineList : public DList<InlineItem> { };
764
765
766
767 #endif /* _PARSETREE_H */