Don't allow the left machine of <: to escape through the right machine via the
[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 runLonestMatch( ParseData *pd, FsmAp *graph );
302         Action *newAction( ParseData *pd, const InputLoc &loc, const char *name, 
303                         InlineList *inlineList );
304         void makeActions( ParseData *pd );
305         void findName( ParseData *pd );
306         void restart( FsmAp *graph, TransAp *trans );
307
308         InputLoc loc;
309         LmPartList *longestMatchList;
310         const char *name;
311
312         Action *lmActSelect;
313         bool lmSwitchHandlesError;
314
315         LongestMatch *next, *prev;
316 };
317
318
319 /* List of Expressions. */
320 typedef DList<Expression> ExprList;
321
322 struct JoinOrLm
323 {
324         enum Type {
325                 JoinType,
326                 LongestMatchType
327         };
328
329         JoinOrLm( Join *join ) : 
330                 join(join), type(JoinType) {}
331         JoinOrLm( LongestMatch *longestMatch ) :
332                 longestMatch(longestMatch), type(LongestMatchType) {}
333
334         FsmAp *walk( ParseData *pd );
335         void makeNameTree( ParseData *pd );
336         void resolveNameRefs( ParseData *pd );
337         
338         Join *join;
339         LongestMatch *longestMatch;
340         Type type;
341 };
342
343 /*
344  * Join
345  */
346 struct Join
347 {
348         /* Construct with the first expression. */
349         Join( Expression *expr );
350         Join( const InputLoc &loc, Expression *expr );
351
352         /* Tree traversal. */
353         FsmAp *walk( ParseData *pd );
354         FsmAp *walkJoin( ParseData *pd );
355         void makeNameTree( ParseData *pd );
356         void resolveNameRefs( ParseData *pd );
357
358         /* Data. */
359         InputLoc loc;
360         ExprList exprList;
361 };
362
363 /*
364  * Expression
365  */
366 struct Expression
367 {
368         enum Type { 
369                 OrType,
370                 IntersectType, 
371                 SubtractType, 
372                 StrongSubtractType,
373                 TermType, 
374                 BuiltinType
375         };
376
377         /* Construct with an expression on the left and a term on the right. */
378         Expression( Expression *expression, Term *term, Type type ) : 
379                 expression(expression), term(term), 
380                 builtin(builtin), type(type), prev(this), next(this) { }
381
382         /* Construct with only a term. */
383         Expression( Term *term ) : 
384                 expression(0), term(term), builtin(builtin), 
385                 type(TermType) , prev(this), next(this) { }
386         
387         /* Construct with a builtin type. */
388         Expression( BuiltinMachine builtin ) : 
389                 expression(0), term(0), builtin(builtin), 
390                 type(BuiltinType), prev(this), next(this) { }
391
392         ~Expression();
393
394         /* Tree traversal. */
395         FsmAp *walk( ParseData *pd, bool lastInSeq = true );
396         void makeNameTree( ParseData *pd );
397         void resolveNameRefs( ParseData *pd );
398
399         /* Node data. */
400         Expression *expression;
401         Term *term;
402         BuiltinMachine builtin;
403         Type type;
404
405         Expression *prev, *next;
406 };
407
408 /*
409  * Term
410  */
411 struct Term 
412 {
413         enum Type { 
414                 ConcatType, 
415                 RightStartType,
416                 RightFinishType,
417                 LeftType,
418                 FactorWithAugType
419         };
420
421         Term( Term *term, FactorWithAug *factorWithAug ) :
422                 term(term), factorWithAug(factorWithAug), type(ConcatType) { }
423
424         Term( Term *term, FactorWithAug *factorWithAug, Type type ) :
425                 term(term), factorWithAug(factorWithAug), type(type) { }
426
427         Term( FactorWithAug *factorWithAug ) :
428                 term(0), factorWithAug(factorWithAug), type(FactorWithAugType) { }
429         
430         ~Term();
431
432         FsmAp *walk( ParseData *pd, bool lastInSeq = true );
433         void makeNameTree( ParseData *pd );
434         void resolveNameRefs( ParseData *pd );
435
436         Term *term;
437         FactorWithAug *factorWithAug;
438         Type type;
439
440         /* Priority descriptor for RightFinish type. */
441         PriorDesc priorDescs[2];
442 };
443
444
445 /* Third level of precedence. Augmenting nodes with actions and priorities. */
446 struct FactorWithAug
447 {
448         FactorWithAug( FactorWithRep *factorWithRep ) :
449                 priorDescs(0), factorWithRep(factorWithRep) { }
450         ~FactorWithAug();
451
452         /* Tree traversal. */
453         FsmAp *walk( ParseData *pd );
454         void makeNameTree( ParseData *pd );
455         void resolveNameRefs( ParseData *pd );
456
457         void assignActions( ParseData *pd, FsmAp *graph, int *actionOrd );
458         void assignPriorities( FsmAp *graph, int *priorOrd );
459
460         void assignConditions( FsmAp *graph );
461
462         /* Actions and priorities assigned to the factor node. */
463         Vector<ParserAction> actions;
464         Vector<PriorityAug> priorityAugs;
465         PriorDesc *priorDescs;
466         Vector<Label> labels;
467         Vector<EpsilonLink> epsilonLinks;
468         Vector<ConditionTest> conditions;
469
470         FactorWithRep *factorWithRep;
471 };
472
473 /* Fourth level of precedence. Trailing unary operators. Provide kleen star,
474  * optional and plus. */
475 struct FactorWithRep
476 {
477         enum Type { 
478                 StarType,
479                 StarStarType,
480                 OptionalType,
481                 PlusType, 
482                 ExactType,
483                 MaxType,
484                 MinType,
485                 RangeType,
486                 FactorWithNegType
487         };
488
489          FactorWithRep( const InputLoc &loc, FactorWithRep *factorWithRep, 
490                         int lowerRep, int upperRep, Type type ) :
491                 loc(loc), factorWithRep(factorWithRep), 
492                 factorWithNeg(0), lowerRep(lowerRep), 
493                 upperRep(upperRep), type(type) { }
494         
495         FactorWithRep( FactorWithNeg *factorWithNeg )
496                 : factorWithNeg(factorWithNeg), type(FactorWithNegType) { }
497
498         ~FactorWithRep();
499
500         /* Tree traversal. */
501         FsmAp *walk( ParseData *pd );
502         void makeNameTree( ParseData *pd );
503         void resolveNameRefs( ParseData *pd );
504
505         InputLoc loc;
506         FactorWithRep *factorWithRep;
507         FactorWithNeg *factorWithNeg;
508         int lowerRep, upperRep;
509         Type type;
510
511         /* Priority descriptor for StarStar type. */
512         PriorDesc priorDescs[2];
513 };
514
515 /* Fifth level of precedence. Provides Negation. */
516 struct FactorWithNeg
517 {
518         enum Type { 
519                 NegateType, 
520                 CharNegateType,
521                 FactorType
522         };
523
524         FactorWithNeg( const InputLoc &loc, FactorWithNeg *factorWithNeg, Type type) :
525                 loc(loc), factorWithNeg(factorWithNeg), factor(0), type(type) { }
526
527         FactorWithNeg( Factor *factor ) :
528                 factorWithNeg(0), factor(factor), type(FactorType) { }
529
530         ~FactorWithNeg();
531
532         /* Tree traversal. */
533         FsmAp *walk( ParseData *pd );
534         void makeNameTree( ParseData *pd );
535         void resolveNameRefs( ParseData *pd );
536
537         InputLoc loc;
538         FactorWithNeg *factorWithNeg;
539         Factor *factor;
540         Type type;
541 };
542
543 /*
544  * Factor
545  */
546 struct Factor
547 {
548         /* Language elements a factor node can be. */
549         enum Type {
550                 LiteralType, 
551                 RangeType, 
552                 OrExprType,
553                 RegExprType, 
554                 ReferenceType,
555                 ParenType,
556                 LongestMatchType,
557         }; 
558
559         /* Construct with a literal fsm. */
560         Factor( Literal *literal ) :
561                 literal(literal), type(LiteralType) { }
562
563         /* Construct with a range. */
564         Factor( Range *range ) : 
565                 range(range), type(RangeType) { }
566         
567         /* Construct with the or part of a regular expression. */
568         Factor( ReItem *reItem ) :
569                 reItem(reItem), type(OrExprType) { }
570
571         /* Construct with a regular expression. */
572         Factor( RegExpr *regExpr ) :
573                 regExpr(regExpr), type(RegExprType) { }
574
575         /* Construct with a reference to a var def. */
576         Factor( const InputLoc &loc, VarDef *varDef ) :
577                 loc(loc), varDef(varDef), type(ReferenceType) {}
578
579         /* Construct with a parenthesized join. */
580         Factor( Join *join ) :
581                 join(join), type(ParenType) {}
582         
583         /* Construct with a longest match operator. */
584         Factor( LongestMatch *longestMatch ) :
585                 longestMatch(longestMatch), type(LongestMatchType) {}
586
587         /* Cleanup. */
588         ~Factor();
589
590         /* Tree traversal. */
591         FsmAp *walk( ParseData *pd );
592         void makeNameTree( ParseData *pd );
593         void resolveNameRefs( ParseData *pd );
594
595         InputLoc loc;
596         Literal *literal;
597         Range *range;
598         ReItem *reItem;
599         RegExpr *regExpr;
600         VarDef *varDef;
601         Join *join;
602         LongestMatch *longestMatch;
603         int lower, upper;
604         Type type;
605 };
606
607 /* A range machine. Only ever composed of two literals. */
608 struct Range
609 {
610         Range( Literal *lowerLit, Literal *upperLit ) 
611                 : lowerLit(lowerLit), upperLit(upperLit) { }
612
613         ~Range();
614         FsmAp *walk( ParseData *pd );
615
616         Literal *lowerLit;
617         Literal *upperLit;
618 };
619
620 /* Some literal machine. Can be a number or literal string. */
621 struct Literal
622 {
623         enum LiteralType { Number, LitString };
624
625         Literal( const Token &token, LiteralType type )
626                 : token(token), type(type) { }
627
628         FsmAp *walk( ParseData *pd );
629         
630         Token token;
631         LiteralType type;
632 };
633
634 /* Regular expression. */
635 struct RegExpr
636 {
637         enum RegExpType { RecurseItem, Empty };
638
639         /* Constructors. */
640         RegExpr() : 
641                 type(Empty), caseInsensitive(false) { }
642         RegExpr(RegExpr *regExpr, ReItem *item) : 
643                 regExpr(regExpr), item(item), 
644                 type(RecurseItem), caseInsensitive(false) { }
645
646         ~RegExpr();
647         FsmAp *walk( ParseData *pd, RegExpr *rootRegex );
648
649         RegExpr *regExpr;
650         ReItem *item;
651         RegExpType type;
652         bool caseInsensitive;
653 };
654
655 /* An item in a regular expression. */
656 struct ReItem
657 {
658         enum ReItemType { Data, Dot, OrBlock, NegOrBlock };
659         
660         ReItem( const InputLoc &loc, const Token &token ) 
661                 : loc(loc), token(token), star(false), type(Data) { }
662         ReItem( const InputLoc &loc, ReItemType type )
663                 : loc(loc), star(false), type(type) { }
664         ReItem( const InputLoc &loc, ReOrBlock *orBlock, ReItemType type )
665                 : loc(loc), orBlock(orBlock), star(false), type(type) { }
666
667         ~ReItem();
668         FsmAp *walk( ParseData *pd, RegExpr *rootRegex );
669
670         InputLoc loc;
671         Token token;
672         ReOrBlock *orBlock;
673         bool star;
674         ReItemType type;
675 };
676
677 /* An or block item. */
678 struct ReOrBlock
679 {
680         enum ReOrBlockType { RecurseItem, Empty };
681
682         /* Constructors. */
683         ReOrBlock()
684                 : type(Empty) { }
685         ReOrBlock(ReOrBlock *orBlock, ReOrItem *item)
686                 : orBlock(orBlock), item(item), type(RecurseItem) { }
687
688         ~ReOrBlock();
689         FsmAp *walk( ParseData *pd, RegExpr *rootRegex );
690         
691         ReOrBlock *orBlock;
692         ReOrItem *item;
693         ReOrBlockType type;
694 };
695
696 /* An item in an or block. */
697 struct ReOrItem
698 {
699         enum ReOrItemType { Data, Range };
700
701         ReOrItem( const InputLoc &loc, const Token &token ) 
702                 : loc(loc), token(token), type(Data) {}
703         ReOrItem( const InputLoc &loc, char lower, char upper )
704                 : loc(loc), lower(lower), upper(upper), type(Range) { }
705
706         FsmAp *walk( ParseData *pd, RegExpr *rootRegex );
707
708         InputLoc loc;
709         Token token;
710         char lower;
711         char upper;
712         ReOrItemType type;
713 };
714
715
716 /*
717  * Inline code tree
718  */
719 struct InlineList;
720 struct InlineItem
721 {
722         enum Type 
723         {
724                 Text, Goto, Call, Next, GotoExpr, CallExpr, NextExpr, Ret, PChar,
725                 Char, Hold, Curs, Targs, Entry, Exec, LmSwitch, LmSetActId,
726                 LmSetTokEnd, LmOnLast, LmOnNext, LmOnLagBehind, LmInitAct,
727                 LmInitTokStart, LmSetTokStart, Break
728         };
729
730         InlineItem( const InputLoc &loc, char *data, Type type ) : 
731                 loc(loc), data(data), nameRef(0), children(0), type(type) { }
732
733         InlineItem( const InputLoc &loc, NameRef *nameRef, Type type ) : 
734                 loc(loc), data(0), nameRef(nameRef), children(0), type(type) { }
735
736         InlineItem( const InputLoc &loc, LongestMatch *longestMatch, 
737                 LongestMatchPart *longestMatchPart, Type type ) : loc(loc), data(0),
738                 nameRef(0), children(0), longestMatch(longestMatch),
739                 longestMatchPart(longestMatchPart), type(type) { } 
740
741         InlineItem( const InputLoc &loc, NameInst *nameTarg, Type type ) : 
742                 loc(loc), data(0), nameRef(0), nameTarg(nameTarg), children(0),
743                 type(type) { }
744
745         InlineItem( const InputLoc &loc, Type type ) : 
746                 loc(loc), data(0), nameRef(0), children(0), type(type) { }
747         
748         InputLoc loc;
749         char *data;
750         NameRef *nameRef;
751         NameInst *nameTarg;
752         InlineList *children;
753         LongestMatch *longestMatch;
754         LongestMatchPart *longestMatchPart;
755         Type type;
756
757         InlineItem *prev, *next;
758 };
759
760 /* Normally this would be atypedef, but that would entail including DList from
761  * ptreetypes, which should be just typedef forwards. */
762 struct InlineList : public DList<InlineItem> { };
763
764
765
766 #endif /* _PARSETREE_H */