1 /*
2  * syn.h
3  *
4  * This file includes definitions and macros associated with syntax diagrams
5  *
6  * SOFTWARE RIGHTS
7  *
8  * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
9  * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
10  * company may do whatever they wish with source code distributed with
11  * PCCTS or the code generated by PCCTS, including the incorporation of
12  * PCCTS, or its output, into commerical software.
13  *
14  * We encourage users to develop software with PCCTS.  However, we do ask
15  * that credit is given to us for developing PCCTS.  By "credit",
16  * we mean that if you incorporate our source code into one of your
17  * programs (commercial product, research project, or otherwise) that you
18  * acknowledge this fact somewhere in the documentation, research report,
19  * etc...  If you like PCCTS and have developed a nice tool with the
20  * output, please mention that you developed it using PCCTS.  In
21  * addition, we ask that this header remain intact in our source code.
22  * As long as these guidelines are kept, we expect to continue enhancing
23  * this system and expect to make other tools available as they are
24  * completed.
25  *
26  * ANTLR 1.33
27  * Terence Parr
28  * Parr Research Corporation
29  * with Purdue University and AHPCRC, University of Minnesota
30  * 1989-2001
31  */
32 
33 #include "set.h"
34 
35 #define NumNodeTypes	4
36 #define NumJuncTypes	9
37 
38 /* List the different node types */
39 #define nJunction		1
40 #define nRuleRef		2
41 #define nToken			3
42 #define nAction			4
43 
44 /* Different types of junctions */
45 #define aSubBlk			1
46 #define aOptBlk			2
47 #define aLoopBlk		3
48 #define EndBlk			4
49 #define RuleBlk			5
50 #define Generic			6	/* just a junction--no unusual characteristics */
51 #define EndRule			7
52 #define aPlusBlk		8
53 #define aLoopBegin		9
54 
55 typedef int NodeType;
56 
57 #define TreeBlockAllocSize		500
58 #define JunctionBlockAllocSize	200
59 #define ActionBlockAllocSize	50
60 #define RRefBlockAllocSize		100
61 #define TokenBlockAllocSize		100
62 
63 #ifdef __cplusplus
64 class ActionNode;
65 class Junction;
66 #endif
67 
68 /* note that 'right' is used by the tree node allocator as a ptr for linked list */
69 typedef struct _tree {
70 			struct _tree *down, *right;
71 			int token;
72 			union {
73 				int rk;	/* if token==EpToken, => how many more tokens req'd */
74 				struct _tree *tref;	/* if token==TREE_REF */
75 				set sref;			/* if token==SET */
76 			} v;
77 #ifdef TREE_DEBUG
78 			int in_use;
79             int seq;
80 #endif
81 		} Tree;
82 
83 
84 /* a predicate is defined to be a predicate action and a token tree with
85  * context info (if used); later, this struct may include the
86  * "hoisting distance" when we hoist past tokens.
87  *
88  * A tree is used to indicate && vs ||
89  *
90  *    p
91  *    |
92  *    q--r
93  *
94  * indicates p && (q||r).
95  *
96  * If expr is PRED_AND_LIST or PRED_OR_LIST, then it's an operation node
97  * and indicates the start of an && or || list.
98  */
99 
100 typedef struct _Predicate {
101 	struct _Predicate *down, *right;	/* these have to be first */
102 	struct _Predicate *up, *left;		/* doubly-link me */
103 	char *expr;
104 	Tree *tcontext;	/* used if lookahead depth of > one is needed (tree) */
105 	int k;			/* lookahead depth for this tcontext */
106 	set scontext[2];/* used if lookahead depth of one is needed (set) */
107 					/* scontext[0] is not used; only needed so genExprSets()
108 					   routine works (it expects an array)
109 					 */
110 	set completionTree;	/* which lookahead depths are required to complete tcontext? */
111     set completionSet;  /* MR10 separate completion set for sets and trees           */
112     struct _PredEntry *predEntry;         /* MR11 */
113 
114 #ifdef __cplusplus
115 	ActionNode *source;	/* where did this predicate come from? */
116 #else
117 	struct _anode *source;	/* where did this predicate come from? */
118 #endif
119 
120     char             cloned;               /* MR10 don't want to free original guard pred */
121     char             redundant;            /* MR10 predicate tree simplification          */
122     char             ampersandStyle;       /* MR10  (g)? && <<p>>?                        */
123     char             inverted;             /* MR11 ! predName */
124     char             isConst;              /* MR11 */
125     char             constValue;           /* MR11 */
126     char             conflictReported;     /* MR11 */
127 
128     set              plainSet;             /* MR12b */
129 
130     /*** remember to change new_predicate() and predicate_dup() when changing this ***/
131 
132 } Predicate;
133 
134 typedef struct _ExceptionHandler {
135 			char *signalname;
136 			char *action;
137 		} ExceptionHandler;
138 
139 typedef struct _ExceptionGroup {
140 			struct _ListNode *handlers; /* list of ExceptionHandler's */
141 			char *label;		/* label==""; implies not attached to any
142 								 * particular rule ref.
143 								 */
144 			char *altID;		/* which alt did it come from (blk#:alt#) */
145 
146             struct _ExceptionGroup  *pendingLink; /* for alternative EG MR7 */
147             struct _ExceptionGroup  *outerEG;     /* for alternative EG MR7 */
148             struct _LabelEntry      *labelEntry;  /* for alternative EG MR7 */
149             int                     forRule;                         /* MR7 */
150             int                     used;                            /* MR7 */
151 		} ExceptionGroup ;
152 
153 
154 #define TokenString(_i)			((TokenInd!=NULL)?TokenStr[TokenInd[_i]]:TokenStr[_i])
155 #define ExprString(_i)			((TokenInd!=NULL)?ExprStr[TokenInd[_i]]:ExprStr[_i])
156 
157 
158 				/* M e s s a g e  P a s s i n g  T o  N o d e s */
159 
160 /*
161  * assumes a 'Junction *r' exists.  This macro calls a function with
162  * the pointer to the node to operate on and a pointer to the rule
163  * in which it is enclosed.
164  */
165 #define TRANS(p)	{if ( (p)==NULL ) fatal("TRANS: NULL object");		\
166 					if ( (p)->ntype == nJunction ) (*(fpJTrans[((Junction *)(p))->jtype]))( p );\
167 					else (*(fpTrans[(p)->ntype]))( p );}
168 
169 #define PRINT(p)	{if ( (p)==NULL ) fatal("PRINT: NULL object");\
170 					(*(fpPrint[(p)->ntype]))( p );}
171 
172 #define REACH(p,k,rk,a) {if ( (p)==NULL ) fatal("REACH: NULL object");\
173 					(a) = (*(fpReach[(p)->ntype]))( p, k, rk );}
174 
175 #define TRAV(p,k,rk,a) {if ( (p)==NULL ) {\
176 					  if ( ContextGuardTRAV ) (a)=NULL; \
177 					  else fatal("TRAV: NULL object");\
178 				    } \
179 					else (a) = (*(fpTraverse[(p)->ntype]))( p, k, rk );}
180 
181 /**
182 *** #define TRAV(p,k,rk,a) {if ( (p)==NULL ) fatal("TRAV: NULL object");\
183 ***					(a) = (*(fpTraverse[(p)->ntype]))( p, k, rk );}
184 **/
185 
186 /* All syntax diagram nodes derive from Node -- superclass
187  */
188 #ifdef __cplusplus
189 class Node {
190 public:
191 			NodeType ntype;
192 			char *rname;		/* what rule does this element live in? */
193 			int file;			/* index in FileStr */
194 			int line;			/* line number that element occurs on */
195 		};
196 #else
197 typedef struct _node {
198 			NodeType ntype;
199 			char *rname;		/* what rule does this element live in? */
200 			int file;			/* index in FileStr */
201 			int line;			/* line number that element occurs on */
202 		} Node;
203 #endif
204 
205 #ifdef __cplusplus
206 class ActionNode : public Node {
207 public:
208 #else
209 typedef struct _anode {
210 			NodeType ntype;
211 			char *rname;		/* what rule does this action live in? */
212 			int file;			/* index in FileStr (name of file with action) */
213 			int line;			/* line number that action occurs on */
214 #endif
215 			Node *next;
216 			char *action;
217 			int is_predicate;	/* true if action is a <<...>>? predicate action */
218 			int done;			/* don't dump if action dumped (used for predicates) */
219 			int init_action;	/* is this the 1st action of 1st prod of block? */
220 			char *pred_fail;	/* what to do/print when predicate fails */
221 			Predicate  *guardpred;	/* if '(context)? =>' was present, already done */
222 			unsigned char frmwarned;/* have we dumped a warning for pred yet? */
223 			unsigned char ctxwarned;/* have we dumped a warning for pred yet? */
224             unsigned char predTooLong;     /* MR10 have we dumped warning for pred yet */
225             unsigned char noHoist;         /* MR12 literally "noHoist" */
226             Predicate         *ampersandPred;     /* MR10   (g)? && <<p>>? expr   */
227 #ifdef __cplusplus
228             Junction          *guardNodes;        /* MR11 */
229 #else
230             struct _junct     *guardNodes;        /* MR11 */
231 #endif
232             struct _PredEntry *predEntry;         /* MR11 */
233             int               inverted;           /* MR11 <<!predSymbol>>? */
234 #ifdef __cplusplus
235 		};
236 #else
237 		} ActionNode;
238 #endif
239 
240 #ifdef __cplusplus
241 class TokNode : public Node {
242 public:
243 #else
244 typedef struct _toknode {
245 			NodeType ntype;
246 			char *rname;		/* name of rule it's in */
247 			int file;			/* index in FileStr (name of file with rule) */
248 			int line;			/* line number that token occurs on */
249 #endif
250 			Node *next;
251 			int token;
252 			int astnode;		/* leaf/root/excluded (used to build AST's) */
253 			unsigned char label;/* token label or expression ? */
254 			unsigned char remapped;
255 								/* used if token id's are forced to certain positions;
256 								 * a function walks the tree reassigning token numbers */
257 			int upper_range;    /* MR13 - was char */
258 								/* used only if Token is of type T1..T2; in this case,
259 								 * use token..upper_range as the range; else
260 								 * upper_range must be 0 */
261 			unsigned char wild_card;
262 								/* indicates that the token is the "." wild-card;
263 								 * field token is ignored if wild_card is set
264 								 */
265 			unsigned int elnum; /* element number within the alternative */
266 #ifdef __cplusplus
267 			Junction *altstart;	/* pointer to node that starts alt */
268 #else
269 			struct _junct *altstart;	/* pointer to node that starts alt */
270 #endif
271 			struct _TCnode *tclass;		/* token class if tokclass ref */
272 			set tset;			/* set of tokens represented by meta token */
273 			char *el_label;		/* el_label:toknode */
274 			unsigned char complement;	/* complement the set? */
275 			ExceptionGroup *ex_group;	/* any exception[el_label] attached? */
276             unsigned char use_def_MT_handler;
277             unsigned char label_used_in_semantic_pred;  /* MR10 */
278 #ifdef __cplusplus
279 		};
280 #else
281 		} TokNode;
282 #endif
283 
284 #ifdef __cplusplus
285 class RuleRefNode : public Node {
286 public:
287 #else
288 typedef struct _rrnode {
289 			NodeType ntype;
290 			char *rname;		/* name of rule it's in */
291 			int file;			/* index in FileStr (name of file with rule)
292 								   it's in */
293 			int line;			/* line number that rule ref occurs on */
294 #endif
295 			Node *next;
296 			char *text;			/* reference to which rule */
297 			char *parms;		/* point to parameters of rule invocation
298 								   (if present) */
299 			char *assign;		/* point to left-hand-side of assignment
300 								   (if any) */
301 			int linked;			/* Has a FoLink already been established? */
302 			int astnode;		/* excluded? (used to build AST's) */
303 			unsigned int elnum; /* element number within the alternative */
304 #ifdef __cplusplus
305 			Junction *altstart;
306 #else
307 			struct _junct *altstart;
308 #endif
309 			char *el_label;		/* el_label:rrnode */
310 			ExceptionGroup *ex_group;	/* any exception[el_label] attached? */
311 #ifdef __cplusplus
312 		};
313 #else
314 		} RuleRefNode;
315 #endif
316 
317 #ifdef __cplusplus
318 class Junction : public Node {
319 public:
320 #else
321 typedef struct _junct {
322 			NodeType ntype;
323 			char *rname;		/* name of rule junction is in */
324 			int file;			/* index in FileStr (name of file with rule)
325 								   if blk == RuleBlk */
326 			int line;			/* line number that rule occurs on */
327 #endif
328             int seq;            /* MR10 sequence number */
329 			char ignore;		/* used by FIRST computation to ignore
330 								   empty alt added for the (...)+ blks */
331 			char visited;		/* used by recursive routines to avoid
332 								   infinite recursion */
333 			char pvisited;		/* used by print routines to avoid
334 								   infinite recursion */
335 			char fvisited;		/* used by FoLink() to avoid
336 								   infinite recursion */
337 			char *lock;			/* used by REACH to track infinite recursion */
338 			char *pred_lock;	/* used by find_predicates to track infinite recursion */
339 			int altnum;			/* used in subblocks. altnum==0 means not an
340 								   alt of subrule */
341 			int jtype;			/* annotation for code-gen/FIRST/FOLLOW.
342 								   Junction type */
343 #ifdef __cplusplus
344 			Junction *end;		/* pointer to node with EndBlk in it
345 								   if blk == a block type */
346 #else
347 			struct _junct *end;	/* pointer to node with EndBlk in it
348 								   if blk == a block type */
349 #endif
350 			Node *p1, *p2;
351 			char  halt;			/* never move past a junction with halt==TRUE */ /* MR10 was int */
352 			char *pdecl;		/* point to declaration of parameters on rule
353 								   (if present) */
354 			char *parm;			/* point to parameter of block invocation
355 								   (if present) */
356 			char predparm;		/* indicates that the 'parm' is a predicate
357 								 * to be used in the while loop generated
358 								 * for blocks */ /* MR10 was int */
359 			char *ret;			/* point to return type of rule (if present) */
360 			char *erraction;	/* point to error action (if present) */
361 			int blockid;		/* this is a unique ID */
362 			char *exception_label;	/* goto label for this alt */
363 			set *fset;			/* used for code generation */
364 			Tree *ftree;		/* used for code generation */
365 			Predicate *predicate;/* predicate that can be used to disambiguate */
366 			char guess;			/* true if (...)? block */
367             char alpha_beta_guess_end;      /* MR14 1 => end block of guess sub block  */
368             Node *guess_analysis_point;     /* MR14 */
369 			char approx;		/* limit block to use linear approx lookahead? */
370 			set tokrefs;		/* if ith element of alt is tokref then i is member */
371 			set rulerefs;		/* if ith element of alt is rule ref then i is member */
372 			struct _ListNode *exceptions; /* list of exceptions groups for rule */
373 			struct _ListNode *el_labels;  /* list of element labels for rule */
374             ExceptionGroup   *outerEG;                               /* MR7 */
375             int              curAltNum;                              /* MR7 */
376             char* pFirstSetSymbol;   /* #pragma FirstSetSymbol(Foo)     MR21 */
377 #ifdef __cplusplus
378             Junction         *pendingLink;                           /* MR7 */
379 #else
380             struct _junct    *pendingLink;                           /* MR7 */
381 #endif
382             char             overlap_warning;                        /* MR10 */
383 #ifdef __cplusplus
384 		};
385 #else
386 		} Junction;
387 #endif
388 
389 typedef struct { Node *left, *right;} Graph;
390 
391