]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/CodeTools/TianoTools/Pccts/antlr/antlr.g
Restructuring for better separation of Tool packages.
[mirror_edk2.git] / Tools / CodeTools / TianoTools / Pccts / antlr / antlr.g
CommitLineData
878ddf1f 1/*\r
2 * antlr.g -- PCCTS Version 1.xx ANTLR\r
3 *\r
4 * Parse an antlr input grammar and build a syntax-diagram.\r
5 *\r
6 * Written in itself (needs at least 1.06 to work)\r
7 *\r
8 * SOFTWARE RIGHTS\r
9 *\r
10 * We reserve no LEGAL rights to the Purdue Compiler Construction Tool\r
11 * Set (PCCTS) -- PCCTS is in the public domain. An individual or\r
12 * company may do whatever they wish with source code distributed with\r
13 * PCCTS or the code generated by PCCTS, including the incorporation of\r
14 * PCCTS, or its output, into commerical software.\r
15 *\r
16 * We encourage users to develop software with PCCTS. However, we do ask\r
17 * that credit is given to us for developing PCCTS. By "credit",\r
18 * we mean that if you incorporate our source code into one of your\r
19 * programs (commercial product, research project, or otherwise) that you\r
20 * acknowledge this fact somewhere in the documentation, research report,\r
21 * etc... If you like PCCTS and have developed a nice tool with the\r
22 * output, please mention that you developed it using PCCTS. In\r
23 * addition, we ask that this header remain intact in our source code.\r
24 * As long as these guidelines are kept, we expect to continue enhancing\r
25 * this system and expect to make other tools available as they are\r
26 * completed.\r
27 *\r
28 * ANTLR 1.33\r
29 * Terence Parr\r
30 * Parr Research Corporation\r
31 * with Purdue University and AHPCRC, University of Minnesota\r
32 * 1989-1995\r
33 */\r
34\r
35/* MR1 */\r
36/* MR1 10-Apr-97 MR1 Replace #if logic with #include "pcctscfg.h" */\r
37/* MR1 */\r
38\r
39#header <<\r
40 #include "pcctscfg.h"\r
41 #include "set.h"\r
42 #include <ctype.h>\r
43 #include "syn.h"\r
44 #include "hash.h"\r
45 #include "generic.h"\r
46 #define zzcr_attr(attr,tok,t)\r
47 >>\r
48\r
49<<\r
50\r
51/* MR20 G. Hobbelt For Borland C++ 4.x & 5.x compiling with ALL warnings enabled */\r
52#if defined(__TURBOC__)\r
53#pragma warn -aus /* unused assignment of 'xxx' */\r
54#endif\r
55\r
56\r
57#ifdef __USE_PROTOS\r
58static void chkToken(char *, char *, char *, int);\r
59#else\r
60static void chkToken();\r
61#endif\r
62\r
63#ifdef __USE_PROTOS\r
64static int isDLGmaxToken(char *Token); /* MR3 */\r
65#else\r
66static int isDLGmaxToken(); /* MR3 */\r
67#endif\r
68\r
69static int class_nest_level = 0;\r
70\r
71/* MR20 G. Hobbelt extern definitions moved to antlr.h */\r
72\r
73>>\r
74\r
75#lexaction <<\r
76/* maintained, but not used for now */\r
77set AST_nodes_refd_in_actions = set_init;\r
78int inAlt = 0;\r
79set attribsRefdFromAction = set_init; /* MR20 */\r
80int UsedOldStyleAttrib = 0;\r
81int UsedNewStyleLabel = 0;\r
82#ifdef __USE_PROTOS\r
83char *inline_set(char *);\r
84#else\r
85char *inline_set();\r
86#endif\r
87\r
88/* MR1 10-Apr-97 MR1 Previously unable to put right shift operator */\r
89/* MR1 in DLG action */\r
90\r
91int tokenActionActive=0; /* MR1 */\r
92\r
93>>\r
94\r
95#lexclass STRINGS\r
96#token QuotedTerm "\"" << zzmode(START); >>\r
97#token "\n|\r|\r\n" <<\r
98 zzline++;\r
99 warn("eoln found in string");\r
100 zzskip();\r
101 >>\r
102#token "\\(\n|\r|\r\n)" << zzline++; zzmore(); >>\r
103#token "\\~[]" << zzmore(); >>\r
104#token "~[\n\r\"\\]+" << zzmore(); >>\r
105\r
106#lexclass ACTION_STRINGS\r
107#token "\"" << zzmode(ACTIONS); zzmore(); >>\r
108#token "\n|\r|\r\n" <<\r
109 zzline++;\r
110 warn("eoln found in string (in user action)");\r
111 zzskip();\r
112 >>\r
113#token "\\(\n|\r|\r\n)" << zzline++; zzmore(); >>\r
114#token "\\~[]" << zzmore(); >>\r
115#token "~[\n\r\"\\]+" << zzmore(); >>\r
116\r
117#lexclass ACTION_CHARS\r
118#token "'" << zzmode(ACTIONS); zzmore(); >>\r
119#token "\n|\r|\r\n" <<\r
120 zzline++;\r
121 warn("eoln found in char literal (in user action)");\r
122 zzskip();\r
123 >>\r
124#token "\\~[]" << zzmore(); >>\r
125#token "~[\n\r'\\]+" << zzmore(); >>\r
126\r
127#lexclass ACTION_COMMENTS\r
128#token "\*/" << zzmode(ACTIONS); zzmore(); >>\r
129#token "\*" << zzmore(); >>\r
130#token "\n|\r|\r\n" << zzline++; zzmore(); DAWDLE; >>\r
131#token "~[\n\r\*]+" << zzmore(); >>\r
132\r
133#lexclass TOK_DEF_COMMENTS\r
134#token "\*/" << zzmode(PARSE_ENUM_FILE);\r
135 zzmore(); >>\r
136#token "\*" << zzmore(); >>\r
137#token "\n|\r|\r\n" << zzline++; zzmore(); DAWDLE; >>\r
138#token "~[\n\r\*]+" << zzmore(); >>\r
139\r
140#lexclass TOK_DEF_CPP_COMMENTS\r
141#token "\n|\r|\r\n" << zzline++; zzmode(PARSE_ENUM_FILE); zzskip(); DAWDLE; >>\r
142#token "~[\n\r]+" << zzskip(); >>\r
143\r
144#lexclass ACTION_CPP_COMMENTS\r
145#token "\n|\r|\r\n" << zzline++; zzmode(ACTIONS); zzmore(); DAWDLE; >>\r
146#token "~[\n\r]+" << zzmore(); >>\r
147\r
148#lexclass CPP_COMMENTS\r
149#token "\n|\r|\r\n" << zzline++; zzmode(START); zzskip(); DAWDLE; >>\r
150#token "~[\n\r]+" << zzskip(); >>\r
151\r
152#lexclass COMMENTS\r
153#token "\*/" << zzmode(START); zzskip(); >>\r
154#token "\*" << zzskip(); >>\r
155#token "\n|\r|\r\n" << zzline++; zzskip(); DAWDLE; >>\r
156#token "~[\n\r\*]+" << zzskip(); >>\r
157\r
158/*\r
159 * This lexical class accepts actions of type [..] and <<..>>\r
160 *\r
161 * It translates the following special items for C:\r
162 *\r
163 * $j --> "zzaArg(current zztasp, j)"\r
164 * $i.j --> "zzaArg(zztaspi, j)"\r
165 * $i.nondigit> "zzaArg(current zztasp, i).nondigit"\r
166 * $$ --> "zzaRet"\r
167 * $alnum --> "alnum" (used to ref parameters)\r
168 * $rule --> "zzaRet"\r
169 * $retval --> "_retv.retval" if > 1 return values else "_retv"\r
170 * $[token, text] --> "zzconstr_attr(token, text)"\r
171 * $[] --> "zzempty_attr()"\r
172 *\r
173 * It translates the following special items for C++:\r
174 * (attributes are now stored with 'Token' and $i's are only\r
175 * pointers to the Tokens. Rules don't have attributes now.)\r
176 *\r
177 * $j --> "_tbj" where b is the block level\r
178 * $i.j --> "_tij"\r
179 * $j->nondigit> "_tbj->nondigit"\r
180 * $$ --> "$$"\r
181 * $alnum --> "alnum" (used to ref parameters)\r
182 * $rule --> "$rule"\r
183 * $retval --> "_retv.retval" if > 1 return values else "_retv"\r
184 * $[token, text] --> invalid\r
185 * $[] --> invalid\r
186 *\r
187 * And, for trees:\r
188 *\r
189 * #0 --> "(*_root)"\r
190 * #i --> "zzastArg(i)"\r
191 * #[args] --> "zzmk_ast(zzastnew(), args)"\r
192 * #[] --> "zzastnew()"\r
193 * #( root, child1, ..., childn )\r
194 * --> "zztmake(root, child1, ...., childn, NULL)"\r
195 * #() --> "NULL"\r
196 *\r
197 * For C++, ...\r
198 *\r
199 * #0 --> "(*_root)"\r
200 * #i --> "_astbi" where b is the block level\r
201 * #alnum --> "alnum_ast" (used to ref #label)\r
202 * #[args] --> "new AST(args)"\r
203 * #[] --> "new AST"\r
204 * #( root, child1, ..., childn )\r
205 * --> "AST::tmake(root, child1, ...., childn, NULL)"\r
206 * #() --> "NULL"\r
207 *\r
208 * To escape,\r
209 *\r
210 * \] --> ]\r
211 * \) --> )\r
212 * \$ --> $\r
213 * \# --> #\r
214 *\r
215 * A stack is used to nest action terminators because they can be nested\r
216 * like crazy: << #[$[..],..] >>\r
217 */\r
218#lexclass ACTIONS\r
219#token Action "\>\>" << /* these do not nest */\r
220 zzmode(START);\r
221 NLATEXT[0] = ' ';\r
222 NLATEXT[1] = ' ';\r
223 zzbegexpr[0] = ' ';\r
224 zzbegexpr[1] = ' ';\r
225 if ( zzbufovf ) {\r
226 err( eMsgd("action buffer overflow; size %d",ZZLEXBUFSIZE));\r
227 }\r
228\r
229/* MR1 10-Apr-97 MR1 Previously unable to put right shift operator */\r
230/* MR1 in DLG action */\r
231/* MR1 Doesn't matter what kind of action it is - reset*/\r
232\r
233 tokenActionActive=0; /* MR1 */\r
234 >>\r
235#token Pred "\>\>?" << /* these do not nest */\r
236 zzmode(START);\r
237 NLATEXT[0] = ' ';\r
238 NLATEXT[1] = ' ';\r
239 zzbegexpr[0] = '\0';\r
240 if ( zzbufovf ) {\r
241 err( eMsgd("predicate buffer overflow; size %d",ZZLEXBUFSIZE));\r
242 };\r
243#ifdef __cplusplus__\r
244/* MR10 */ list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred);\r
245#else\r
246#ifdef __STDC__\r
247/* MR10 */ list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred);\r
248#else\r
249#ifdef __USE_PROTOS\r
250/* MRxx */ list_apply(CurActionLabels, (void (*)(void *))mark_label_used_in_sem_pred);\r
251#else\r
252/* MR10 */ list_apply(CurActionLabels,mark_label_used_in_sem_pred);\r
253#endif\r
254#endif\r
255#endif\r
256 >>\r
257#token PassAction "\]" << if ( topint() == ']' ) {\r
258 popint();\r
259 if ( istackempty() ) /* terminate action */\r
260 {\r
261 zzmode(START);\r
262 NLATEXT[0] = ' ';\r
263 zzbegexpr[0] = ' ';\r
264 if ( zzbufovf ) {\r
265 err( eMsgd("parameter buffer overflow; size %d",ZZLEXBUFSIZE));\r
266 }\r
267 }\r
268 else {\r
269 /* terminate $[..] and #[..] */\r
270 if ( GenCC ) zzreplstr("))");\r
271 else zzreplstr(")");\r
272 zzmore();\r
273 }\r
274 }\r
275 else if ( topint() == '|' ) { /* end of simple [...] */\r
276 popint();\r
277 zzmore();\r
278 }\r
279 else zzmore();\r
280 >>\r
281#token "consumeUntil\( [\ \t]* \{~[\}]+\} [\ \t]* \)"\r
282 <<\r
283 zzmore();\r
284 zzreplstr(inline_set(zzbegexpr+\r
285 strlen("consumeUntil(")));\r
286 >>\r
287#token "consumeUntil\( ~[\)]+ \)"\r
288 << zzmore(); >>\r
289#token "\n|\r|\r\n" << zzline++; zzmore(); DAWDLE; >>\r
290#token "\>" << zzmore(); >>\r
291#token "$" << zzmore(); >>\r
292#token "$$" << if ( !GenCC ) {zzreplstr("zzaRet"); zzmore();}\r
293 else err("$$ use invalid in C++ mode"); >>\r
294\r
295#token "$\[\]" << if ( !GenCC ) {zzreplstr("zzempty_attr"); zzmore();}\r
296 else err("$[] use invalid in C++ mode"); >>\r
297#token "$\[" <<\r
298 pushint(']');\r
299 if ( !GenCC ) zzreplstr("zzconstr_attr(");\r
300 else err("$[..] use invalid in C++ mode");\r
301 zzmore();\r
302 >>\r
303#token "$[0-9]+" <<{\r
304 static char buf[100];\r
305 numericActionLabel=1; /* MR10 */\r
306 if ( strlen(zzbegexpr)>(size_t)85 )\r
307 fatal("$i attrib ref too big");\r
308 set_orel(atoi(zzbegexpr+1), &attribsRefdFromAction);\r
309 if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%d,%s)",\r
310 BlkLevel-1,zzbegexpr+1);\r
311 else sprintf(buf,"_t%d%s",\r
312 BlkLevel-1,zzbegexpr+1);\r
313 zzreplstr(buf);\r
314 zzmore();\r
315 UsedOldStyleAttrib = 1;\r
316 if ( UsedNewStyleLabel )\r
317 err("cannot mix old-style $i with new-style labels");\r
318 }\r
319 >>\r
320#token "$[0-9]+." <<{\r
321 static char buf[100];\r
322 numericActionLabel=1; /* MR10 */\r
323 if ( strlen(zzbegexpr)>(size_t)85 )\r
324 fatal("$i.field attrib ref too big");\r
325 zzbegexpr[strlen(zzbegexpr)-1] = ' ';\r
326 set_orel(atoi(zzbegexpr+1), &attribsRefdFromAction);\r
327 if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%d,%s).",\r
328 BlkLevel-1,zzbegexpr+1);\r
329 else sprintf(buf,"_t%d%s.",\r
330 BlkLevel-1,zzbegexpr+1);\r
331 zzreplstr(buf);\r
332 zzmore();\r
333 UsedOldStyleAttrib = 1;\r
334 if ( UsedNewStyleLabel )\r
335 err("cannot mix old-style $i with new-style labels");\r
336 }\r
337 >>\r
338#token "$[0-9]+.[0-9]+" <<{\r
339 static char buf[100];\r
340 static char i[20], j[20];\r
341 char *p,*q;\r
342 numericActionLabel=1; /* MR10 */\r
343 if (strlen(zzbegexpr)>(size_t)85) fatal("$i.j attrib ref too big");\r
344 for (p=zzbegexpr+1,q= &i[0]; *p!='.'; p++) {\r
345 if ( q == &i[20] )\r
346 fatalFL("i of $i.j attrib ref too big",\r
347 FileStr[CurFile], zzline );\r
348 *q++ = *p;\r
349 }\r
350 *q = '\0';\r
351 for (p++, q= &j[0]; *p!='\0'; p++) {\r
352 if ( q == &j[20] )\r
353 fatalFL("j of $i.j attrib ref too big",\r
354 FileStr[CurFile], zzline );\r
355 *q++ = *p;\r
356 }\r
357 *q = '\0';\r
358 if ( !GenCC ) sprintf(buf,"zzaArg(zztasp%s,%s)",i,j);\r
359 else sprintf(buf,"_t%s%s",i,j);\r
360 zzreplstr(buf);\r
361 zzmore();\r
362 UsedOldStyleAttrib = 1;\r
363 if ( UsedNewStyleLabel )\r
364 err("cannot mix old-style $i with new-style labels");\r
365 }\r
366 >>\r
367#token "$[_a-zA-Z][_a-zA-Z0-9]*"\r
368 <<{ static char buf[300]; LabelEntry *el;\r
369 zzbegexpr[0] = ' ';\r
370 if ( CurRule != NULL &&\r
371 strcmp(CurRule, &zzbegexpr[1])==0 ) {\r
372 if ( !GenCC ) zzreplstr("zzaRet");\r
373 }\r
374 else if ( CurRetDef != NULL &&\r
375 strmember(CurRetDef, &zzbegexpr[1])) {\r
376 if ( hasMultipleOperands( CurRetDef ) ) {\r
377 require (strlen(zzbegexpr)<=(size_t)285,\r
378 "$retval attrib ref too big");\r
379 sprintf(buf,"_retv.%s",&zzbegexpr[1]);\r
380 zzreplstr(buf);\r
381 }\r
382 else zzreplstr("_retv");\r
383 }\r
384 else if ( CurParmDef != NULL &&\r
385 strmember(CurParmDef, &zzbegexpr[1])) {\r
386 ;\r
387 }\r
388 else if ( Elabel==NULL ) {\r
389 { err("$-variables in actions outside of rules are not allowed"); }\r
390 } else if ( (el=(LabelEntry *)hash_get(Elabel, &zzbegexpr[1]))!=NULL ) {\r
391/* MR10 */\r
392/* MR10 */ /* element labels might exist without an elem when */\r
393/* MR10 */ /* it is a forward reference (to a rule) */\r
394/* MR10 */\r
395/* MR10 */ if ( GenCC && (el->elem == NULL || el->elem->ntype==nRuleRef) )\r
396/* MR10 */ { err(eMsg1("There are no token ptrs for rule references: '$%s'",&zzbegexpr[1])); }\r
397/* MR10 */\r
398/* MR10 */ if ( !GenCC && (el->elem == NULL || el->elem->ntype==nRuleRef) && GenAST) {\r
399/* MR10 */ err("You can no longer use attributes returned by rules when also using ASTs");\r
400/* MR10 */ err(" Use upward inheritance (\"rule >[Attrib a] : ... <<$a=...\>\>\")");\r
401/* MR10 */ };\r
402/* MR10 */\r
403/* MR10 */ /* keep track of <<... $label ...>> for semantic predicates in guess mode */\r
404/* MR10 */ /* element labels contain pointer to the owners node */\r
405/* MR10 */\r
406/* MR10 */ if (el->elem != NULL && el->elem->ntype == nToken) {\r
407/* MR10 */ list_add(&CurActionLabels,el);\r
408/* MR10 */ };\r
409 }\r
410 else\r
411 warn(eMsg1("$%s not parameter, return value, (defined) element label",&zzbegexpr[1]));\r
412 }\r
413 zzmore();\r
414 >>\r
415#token "#0" << zzreplstr("(*_root)"); zzmore(); chkGTFlag(); >>\r
416#token "#\[\]" << if ( GenCC ) {\r
417 if (NewAST) zzreplstr("(newAST)");\r
418 else zzreplstr("(new AST)");}\r
419 else {zzreplstr("zzastnew()");} zzmore();\r
420 chkGTFlag();\r
421 >>\r
422#token "#\(\)" << zzreplstr("NULL"); zzmore(); chkGTFlag(); >>\r
423#token "#[0-9]+" <<{\r
424 static char buf[100];\r
425 if ( strlen(zzbegexpr)>(size_t)85 )\r
426 fatal("#i AST ref too big");\r
427 if ( GenCC ) sprintf(buf,"_ast%d%s",BlkLevel-1,zzbegexpr+1);\r
428 else sprintf(buf,"zzastArg(%s)",zzbegexpr+1);\r
429 zzreplstr(buf);\r
430 zzmore();\r
431 set_orel(atoi(zzbegexpr+1), &AST_nodes_refd_in_actions);\r
432 chkGTFlag();\r
433 }\r
434 >>\r
435\r
436/* MR14 Arpad Beszedes 26-May-98\r
437 Add support for #line directives when antlr source is pre-processed\r
438 #lexclass ACTIONS\r
439*/\r
440\r
441#token "#line[\ \t]* [0-9]+ {[\ \t]* \"~[\"]+\" ([\ \t]* [0-9]*)* } (\n|\r|\r\n)"\r
442 <<\r
443 zzline = atoi(zzbegexpr+5) - 1; zzline++; zzmore();\r
444 getFileNameFromTheLineInfo(FileStr[CurFile], zzbegexpr);\r
445 >>\r
446\r
447#token "#line ~[\n\r]* (\n|\r|\r\n)"\r
448 <<\r
449 zzline++; zzmore();\r
450 >>\r
451\r
452/* MR14 end of a block to support #line in antlr source code */\r
453\r
454#token "#[_a-zA-Z][_a-zA-Z0-9]*"\r
455 <<\r
456 if ( !(strcmp(zzbegexpr, "#ifdef")==0 ||\r
457 strcmp(zzbegexpr, "#if")==0 ||\r
458 strcmp(zzbegexpr, "#else")==0 ||\r
459 strcmp(zzbegexpr, "#endif")==0 ||\r
460 strcmp(zzbegexpr, "#ifndef")==0 ||\r
461 strcmp(zzbegexpr, "#define")==0 ||\r
462 strcmp(zzbegexpr, "#pragma")==0 ||\r
463 strcmp(zzbegexpr, "#undef")==0 ||\r
464 strcmp(zzbegexpr, "#import")==0 ||\r
465 strcmp(zzbegexpr, "#line")==0 ||\r
466 strcmp(zzbegexpr, "#include")==0 ||\r
467 strcmp(zzbegexpr, "#error")==0) )\r
468 {\r
469 static char buf[100];\r
470 sprintf(buf, "%s_ast", zzbegexpr+1);\r
471/* MR27 */ list_add(&CurAstLabelsInActions, mystrdup(zzbegexpr+1));\r
472 zzreplstr(buf);\r
473 chkGTFlag();\r
474 }\r
475 zzmore();\r
476 >>\r
477#token "#\[" <<\r
478 pushint(']');\r
479 if ( GenCC ) {\r
480 if (NewAST) zzreplstr("(newAST(");\r
481 else zzreplstr("(new AST("); }\r
482 else zzreplstr("zzmk_ast(zzastnew(),");\r
483 zzmore();\r
484 chkGTFlag();\r
485 >>\r
486#token "#\(" <<\r
487 pushint('}');\r
488 if ( GenCC ) {\r
489 if (tmakeInParser) {\r
490 zzreplstr("tmake(");\r
491 }\r
492 else {\r
493 zzreplstr("ASTBase::tmake(");\r
494 }\r
495 }\r
496 else {\r
497 zzreplstr("zztmake(");\r
498 }\r
499 zzmore();\r
500 chkGTFlag();\r
501 >>\r
502#token "#" << zzmore(); >>\r
503#token "\)" <<\r
504 if ( istackempty() )\r
505 zzmore();\r
506 else if ( topint()==')' ) {\r
507 popint();\r
508 }\r
509 else if ( topint()=='}' ) {\r
510 popint();\r
511 /* terminate #(..) */\r
512 zzreplstr(", NULL)");\r
513 }\r
514 zzmore();\r
515 >>\r
516#token "\[" <<\r
517 pushint('|'); /* look for '|' to terminate simple [...] */\r
518 zzmore();\r
519 >>\r
520#token "\(" <<\r
521 pushint(')');\r
522 zzmore();\r
523 >>\r
524\r
525#token "\\\]" << zzreplstr("]"); zzmore(); >>\r
526#token "\\\)" << zzreplstr(")"); zzmore(); >>\r
527\r
528/* MR1 10-Apr-97 MR1 Previously unable to put right shift operator */\r
529/* MR1 in DLG action */\r
530\r
531#token "\\>" << if (! tokenActionActive) zzreplstr(">"); /* MR1 */\r
532 zzmore(); /* MR1 */\r
533 >> /* MR1 */\r
534\r
535\r
536#token "'" << zzmode(ACTION_CHARS); zzmore();>>\r
537#token "\"" << zzmode(ACTION_STRINGS); zzmore();>>\r
538#token "\\$" << zzreplstr("$"); zzmore(); >>\r
539#token "\\#" << zzreplstr("#"); zzmore(); >>\r
540#token "\\(\n|\r|\r\n)" << zzline++; zzmore(); >>\r
541#token "\\~[\]\)>$#]" << zzmore(); >> /* escaped char, always ignore */\r
542#token "/" << zzmore(); >>\r
543#token "/\*" << zzmode(ACTION_COMMENTS); zzmore(); >>\r
544#token "\*/" << warn("Missing /*; found dangling */ in action"); zzmore(); >>\r
545#token "//" << zzmode(ACTION_CPP_COMMENTS); zzmore(); >>\r
546#token "~[\n\r\)\(\\$#\>\]\[\"'/]+" << zzmore(); >>\r
547\r
548#lexclass START\r
549#token "[\t\ ]+" << zzskip(); >> /* Ignore White */\r
550#token "\n|\r|\r\n" << zzline++; zzskip(); >> /* Track Line # */\r
551#token "\[" << zzmode(ACTIONS); zzmore();\r
552 istackreset();\r
553 pushint(']'); >>\r
554#token "\<\<" << action_file=CurFile; action_line=zzline;\r
555 zzmode(ACTIONS); zzmore();\r
556 list_free(&CurActionLabels,0); /* MR10 */\r
557 numericActionLabel=0; /* MR10 */\r
558 istackreset();\r
559 pushint('>'); >>\r
560#token "\"" << zzmode(STRINGS); zzmore(); >>\r
561#token "/\*" << zzmode(COMMENTS); zzskip(); >>\r
562#token "\*/" << warn("Missing /*; found dangling */"); zzskip(); >>\r
563#token "//" << zzmode(CPP_COMMENTS); zzskip(); >>\r
564\r
565/* MR14 Arpad Beszedes 26-May-98\r
566 Add support for #line directives when antlr source is pre-processed\r
567 #lexclass START\r
568*/\r
569\r
570#token "#line[\ \t]* [0-9]+ {[\ \t]* \"~[\"]+\" ([\ \t]* [0-9]*)* } (\n|\r|\r\n)"\r
571 <<\r
572 zzline = atoi(zzbegexpr+5) - 1; zzline++; zzmore();\r
573 getFileNameFromTheLineInfo(FileStr[CurFile], zzbegexpr);\r
574 >>\r
575\r
576#token "#line ~[\n\r]* (\n|\r|\r\n)"\r
577 <<\r
578 zzline++; zzmore();\r
579 >>\r
580\r
581/* MR14 end of a block to support #line in antlr source code */\r
582\r
583/* */\r
584/* 8-Apr-97 Regularize escape sequence for ">>" */\r
585/* appearing in string literals */\r
586/* */\r
587\r
588#token "\>\>" << warn("Missing <<; found dangling \>\>"); zzskip(); >> /* MR1 */\r
589#token WildCard "."\r
590#token "\@" <<FoundException = 1; /* MR6 */\r
591 FoundAtOperator = 1;>> /* MR6 */\r
592#token Eof "@"\r
593 << /* L o o k F o r A n o t h e r F i l e */\r
594 {\r
595 FILE *new_input;\r
596 new_input = NextFile();\r
597 if ( new_input == NULL ) { NLA=Eof; return; }\r
598 fclose( input );\r
599 input = new_input;\r
600 zzrdstream( input );\r
601 zzskip(); /* Skip the Eof (@) char i.e continue */\r
602 }\r
603 >>\r
604\r
605#token LABEL\r
606\r
607#errclass "grammar-element" { element }\r
608#errclass "meta-symbol" { "\}" "!" ";" "\|" "\~" "^" "\)" }\r
609\r
610#token Pragma "{\\}#pragma" /* MR21 */\r
611#token FirstSetSymbol "{\\}#FirstSetSymbol" /* MR21 */\r
612/*\r
613 * Get a grammar -- Build a list of rules like:\r
614 *\r
615 * o-->Rule1--o\r
616 * |\r
617 * o-->Rule2--o\r
618 * |\r
619 * ...\r
620 * |\r
621 * o-->RuleN--o\r
622 */\r
623\r
624/* rule grammar */\r
625\r
626grammar : <<Graph g;>>\r
627 ( "{\\}#header" Action /* MR13 */\r
628 <<\r
629 if ( HdrAction==NULL ) {\r
630 HdrAction = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));\r
631 require(HdrAction!=NULL, "rule grammar: cannot allocate header action");\r
632 strcpy(HdrAction, LATEXT(1));\r
633 }\r
634 else warn("additional #header statement ignored");\r
635 >>\r
636 | "{\\}#first" Action\r
637 <<\r
638 if ( FirstAction==NULL ) {\r
639 FirstAction = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));\r
640 require(FirstAction!=NULL, "rule grammar: cannot allocate #first action");\r
641 strcpy(FirstAction, LATEXT(1));\r
642 } else {\r
643 warn("additional #first statement ignored");\r
644 };\r
645 >>\r
646\r
647 | "{\\}#parser" QuotedTerm\r
648 <<\r
649 if ( GenCC ) {\r
650 warn("#parser meta-op incompatible with -CC; ignored");\r
651 }\r
652 else {\r
653 if ( strcmp(ParserName,"zzparser")==0 ) {\r
654 ParserName=StripQuotes(mystrdup(LATEXT(1)));\r
655 if ( RulePrefix[0]!='\0' )\r
656 {\r
657 warn("#parser meta-op incompatible with '-gp prefix'; '-gp' ignored");\r
658 RulePrefix[0]='\0';\r
659 }\r
660 }\r
661 else warn("additional #parser statement ignored");\r
662 }\r
663 >>\r
664 | "{\\}#tokdefs" QuotedTerm\r
665 <<{\r
666 char *fname;\r
667 zzantlr_state st; FILE *f; struct zzdlg_state dst;\r
668 UserTokenDefsFile = mystrdup(LATEXT(1));\r
669 zzsave_antlr_state(&st);\r
670 zzsave_dlg_state(&dst);\r
671 fname = mystrdup(LATEXT(1));\r
672 f = fopen(StripQuotes(fname), "r");\r
673 if ( f==NULL ) {warn(eMsg1("cannot open token defs file '%s'", fname+1));}\r
674 else {\r
675 ANTLRm(enum_file(fname+1), f, PARSE_ENUM_FILE);\r
676 UserDefdTokens = 1;\r
677 }\r
678 zzrestore_antlr_state(&st);\r
679 zzrestore_dlg_state(&dst);\r
680 }>>\r
681 )*\r
682 ( Action\r
683 <<{\r
684 UserAction *ua = newUserAction(LATEXT(1));\r
685 ua->file = action_file; ua->line = action_line;\r
686 if ( class_nest_level>0 ) list_add(&class_before_actions, ua);\r
687 else list_add(&BeforeActions, ua);\r
688 }>>\r
689 | laction\r
690 | lmember /* MR1 */\r
691 | lprefix /* MR1 */\r
692 | aLexclass\r
693 | token\r
694 | error\r
695 | tclass\r
696 | aPred /* MR11 */\r
697 | default_exception_handler\r
698 | class_def\r
699 | "\}"\r
700 <<\r
701 if ( class_nest_level==0 )\r
702 warn("missing class definition for trailing '}'");\r
703 class_nest_level--;\r
704 >>\r
705 )*\r
706 \r
707 rule <<g=$3; SynDiag = (Junction *) $3.left;>>\r
708 ( rule\r
709\r
710 <<if ( $1.left!=NULL ) {\r
711 g.right = NULL;\r
712\r
713/* MR21a */ /* Avoid use of a malformed graph when CannotContinue */\r
714/* MR21a */ /* is already set */\r
715/* MR21a */\r
716/* MR21a */ if (! (CannotContinue && g.left == NULL)) {\r
717/* MR21a */ g = Or(g, $1);\r
718/* MR21a */ }\r
719/* MR21a */ }\r
720 >>\r
721\r
722 | aLexclass\r
723 | token\r
724 | error\r
725 | tclass\r
726 | aPred /* MR11 */\r
727 | class_def\r
728 | "\}"\r
729 <<\r
730 if ( class_nest_level==0 )\r
731 warn("missing class definition for trailing '}'");\r
732 class_nest_level--;\r
733 >>\r
734 )*\r
735 ( Action\r
736 <<{\r
737 UserAction *ua = newUserAction(LATEXT(1));\r
738 ua->file = action_file; ua->line = action_line;\r
739 if ( class_nest_level>0 ) list_add(&class_after_actions, ua);\r
740 else list_add(&AfterActions, ua);\r
741 }>>\r
742 | laction\r
743 | lmember /* MR1 */\r
744 | lprefix /* MR1 */\r
745 | error\r
746 | tclass\r
747 | class_def\r
748 | aPred /* MR11 */\r
749 | "\}"\r
750 <<\r
751 if ( class_nest_level==0 )\r
752 warn("missing class definition for trailing '}'");\r
753 class_nest_level--;\r
754 >>\r
755 )*\r
756 Eof\r
757 ;\r
758 <<CannotContinue=TRUE;>>\r
759\r
760/* rule class_def */\r
761\r
762class_def\r
763 : <<int go=1; char name[MaxRuleName+1];>>\r
764 "class"\r
765 ( NonTerminal <<if(go) strncpy(name,LATEXT(1),MaxRuleName);>>\r
766 | TokenTerm <<if(go) strncpy(name,LATEXT(1),MaxRuleName);>>\r
767 )\r
768 <<\r
769 if ( CurrentClassName[0]!='\0' && strcmp(CurrentClassName,name)!=0\r
770 && GenCC ) {\r
771 err("only one grammar class allowed in this release");\r
772 go = 0;\r
773 }\r
774 else strcpy(CurrentClassName, name);\r
775 >>\r
776 <<if ( !GenCC ) { err("class meta-op used without C++ option"); }>>\r
777\r
778/* MR10 */ (~ "\{"\r
779/* MR10 */ <<if (ClassDeclStuff == NULL) {\r
780/* MR10 */ ClassDeclStuff=(char *)calloc(MaxClassDeclStuff+1,sizeof(char));\r
781/* MR10 */ };\r
782/* MR10 */ strncat(ClassDeclStuff," ",MaxClassDeclStuff);\r
783/* MR10 */ strncat(ClassDeclStuff,LATEXT(1),MaxClassDeclStuff);\r
784/* MR22 */ do {\r
785/* MR22 */ if (0 == strcmp(LATEXT(1),"public")) break;\r
786/* MR22 */ if (0 == strcmp(LATEXT(1),"private")) break;\r
787/* MR22 */ if (0 == strcmp(LATEXT(1),"protected")) break;\r
788/* MR22 */ if (0 == strcmp(LATEXT(1),"virtual")) break;\r
789/* MR22 */ if (0 == strcmp(LATEXT(1),",")) break;\r
790/* MR22 */ if (0 == strcmp(LATEXT(1),":")) break;\r
791/* MR22 */ if (BaseClassName != NULL) break;\r
792/* MR22 */ BaseClassName=(char *)calloc(strlen(LATEXT(1))+1,sizeof(char));\r
793/* MR22 */ require(BaseClassName!=NULL, "rule grammar: cannot allocate base class name");\r
794/* MR22 */ strcpy(BaseClassName,LATEXT(1));\r
795/* MR22 */ } while (0);\r
796/* MR10 */ >>\r
797/* MR10 */ )*\r
798\r
799 "\{"\r
800 <<\r
801 no_classes_found = 0;\r
802 if ( class_nest_level>=1 ) {warn("cannot have nested classes");}\r
803 else class_nest_level++;\r
804 >>\r
805 ;\r
806 <<CannotContinue=TRUE;>>\r
807\r
808/*\r
809 * Build -o-->o-R-o-->o- where -o-R-o- is the block from rule 'block'.\r
810 * Construct the RuleBlk front and EndRule node on the end of the\r
811 * block. This is used to add FOLLOW pointers to the rule end. Add the\r
812 * new rule name to the Rname hash table and sets its rulenum.\r
813 * Store the parameter definitions if any are found.\r
814 *\r
815 * Note that locks are required on the RuleBlk and EndRule nodes to thwart\r
816 * infinite recursion.\r
817 *\r
818 * Return the left graph pointer == NULL to indicate error/dupl rule def.\r
819 */\r
820\r
821/* rule rule */\r
822\r
823rule : <<\r
824\r
825 ExceptionGroup *eg;\r
826 RuleEntry *q; Junction *p; Graph r; int f, l; ECnode *e;\r
827 set toksrefd, rulesrefd;\r
828 char *pdecl=NULL, *ret=NULL, *a; CurRetDef = CurParmDef = NULL;\r
829 CurExGroups = NULL;\r
830 CurElementLabels = NULL;\r
831 CurAstLabelsInActions = NULL; /* MR27 */\r
832 /* We want a new element label hash table for each rule */\r
833 if ( Elabel!=NULL ) killHashTable(Elabel);\r
834 Elabel = newHashTable();\r
835 attribsRefdFromAction = empty;\r
836 >>\r
837 NonTerminal\r
838 <<q=NULL;\r
839 if ( hash_get(Rname, LATEXT(1))!=NULL ) {\r
840 err(eMsg1("duplicate rule definition: '%s'",LATEXT(1)));\r
841 CannotContinue=TRUE;\r
842 }\r
843 else\r
844 {\r
845 q = (RuleEntry *)hash_add(Rname,\r
846 LATEXT(1),\r
847 (Entry *)newRuleEntry(LATEXT(1)));\r
848 CurRule = q->str;\r
849 }\r
850 CurRuleNode = q;\r
851 f = CurFile; l = zzline;\r
852 NumRules++;\r
853 >>\r
854 { "!" <<if ( q!=NULL ) q->noAST = TRUE;>> }\r
855 { <<;>>\r
856 {"\<"}\r
857 PassAction\r
858 << pdecl = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));\r
859 require(pdecl!=NULL, "rule rule: cannot allocate param decl");\r
860 strcpy(pdecl, LATEXT(1));\r
861 CurParmDef = pdecl;\r
862 >>\r
863 }\r
864 { "\>"\r
865 PassAction\r
866 << ret = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));\r
867 require(ret!=NULL, "rule rule: cannot allocate ret type");\r
868 strcpy(ret, LATEXT(1));\r
869 CurRetDef = ret;\r
870 >>\r
871 }\r
872 { QuotedTerm <<if ( q!=NULL ) q->egroup=mystrdup(LATEXT(1));>> }\r
873 <<\r
874 if ( GenEClasseForRules && q!=NULL ) {\r
875 e = newECnode;\r
876 require(e!=NULL, "cannot allocate error class node");\r
877 if ( q->egroup == NULL ) {a = q->str; a[0] = (char)toupper(a[0]);}\r
878 else a = q->egroup;\r
879 if ( Tnum( a ) == 0 )\r
880 {\r
881 e->tok = addTname( a );\r
882 list_add(&eclasses, (char *)e);\r
883 if ( q->egroup == NULL ) a[0] = (char)tolower(a[0]);\r
884 /* refers to itself */\r
885 list_add(&(e->elist), mystrdup(q->str));\r
886 }\r
887 else {\r
888 warn(eMsg1("default errclass for '%s' would conflict with token/errclass/tokclass",a));\r
889 if ( q->egroup == NULL ) a[0] = (char)tolower(a[0]);\r
890 free((char *)e);\r
891 }\r
892 }\r
893 >>\r
894 <<BlkLevel++;\r
895 if (BlkLevel >= MAX_BLK_LEVEL) fatal("Blocks nested too deeply");\r
896/* MR23 */ CurBlockID_array[BlkLevel] = CurBlockID;\r
897/* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum; \r
898 >>\r
899\r
900 ":" <<inAlt=1;>>\r
901 block[&toksrefd, &rulesrefd]\r
902 <<r = makeBlk($7,0, NULL /* pFirstSetSymbol */ );\r
903 CurRuleBlk = (Junction *)r.left;\r
904 CurRuleBlk->blockid = CurBlockID;\r
905 CurRuleBlk->jtype = RuleBlk;\r
906 if ( q!=NULL ) CurRuleBlk->rname = q->str;\r
907 CurRuleBlk->file = f;\r
908 CurRuleBlk->line = l;\r
909 CurRuleBlk->pdecl = pdecl;\r
910 CurRuleBlk->ret = ret;\r
911 CurRuleBlk->lock = makelocks();\r
912 CurRuleBlk->pred_lock = makelocks();\r
913 CurRuleBlk->tokrefs = toksrefd;\r
914 CurRuleBlk->rulerefs = rulesrefd;\r
915 p = newJunction(); /* add EndRule Node */\r
916 ((Junction *)r.right)->p1 = (Node *)p;\r
917 r.right = (Node *) p;\r
918 p->jtype = EndRule;\r
919 p->lock = makelocks();\r
920 p->pred_lock = makelocks();\r
921 CurRuleBlk->end = p;\r
922 if ( q!=NULL ) q->rulenum = NumRules;\r
923 $7 = r;\r
924 >>\r
925 <<\r
926 /* MR23 */ CurBlockID_array[BlkLevel] = (-1);\r
927 /* MR23 */ CurAltNum_array[BlkLevel] = (-1); \r
928 --BlkLevel;\r
929 >>\r
930 <<altFixup();leFixup();egFixup();>> /* MR7 */\r
931 ";" <<inAlt=0;>>\r
932 { Action\r
933 << a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));\r
934 require(a!=NULL, "rule rule: cannot allocate error action");\r
935 strcpy(a, LATEXT(1));\r
936 CurRuleBlk->erraction = a;\r
937 >>\r
938 }\r
939 ( exception_group > [eg]\r
940 <<if ( eg!=NULL ) {\r
941 list_add(&CurExGroups, (void *)eg);\r
942 if (eg->label == NULL || *eg->label=='\0' ) q->has_rule_exception = 1;\r
943 }\r
944 >>\r
945 )*\r
946 <<if ( q==NULL ) $0.left = NULL; else $0 = $7;>>\r
947 <<CurRuleBlk->exceptions = CurExGroups;>>\r
948 <<CurRuleBlk->el_labels = CurElementLabels;>>\r
949 <<CurRuleNode->ast_labels_in_actions = CurAstLabelsInActions;>> /* MR27 */\r
950 <<CurRuleNode = NULL;>> /* MR27 Moved */\r
951 ;\r
952 <<CannotContinue=TRUE;>>\r
953\r
954/*\r
955 * pragma : "{\\}#pragma" "dup\-labeled\-tokens"\r
956 * <<Pragma_DupLabeledTokens=1;>>\r
957 * ;\r
958 */\r
959\r
960/* rule laction */\r
961\r
962laction : <<char *a;>>\r
963\r
964 "{\\}#lexaction"\r
965 Action\r
966 <<\r
967 a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));\r
968 require(a!=NULL, "rule laction: cannot allocate action");\r
969 strcpy(a, LATEXT(1));\r
970 list_add(&LexActions, a);\r
971 >>\r
972 ;\r
973 <<CannotContinue=TRUE;>>\r
974\r
975/* MR1 */\r
976/* MR1 11-Apr-97 Provide mechanism for inserting code into DLG class */\r
977/* MR1 via #lexmember <<....>> & #lexprefix <<...>> */\r
978/* MR1 */\r
979\r
980/* rule lmember */\r
981\r
982lmember: <<char *a;>> /* MR1 */\r
983\r
984/* MR1 */ "{\\}#lexmember"\r
985/* MR1 */ Action\r
986/* MR1 */ <<\r
987/* MR1 */ if (! GenCC) {\r
988/* MR1 */ err("Use #lexmember only in C++ mode (to insert code in DLG class header");\r
989/* MR1 */ } else {\r
990/* MR1 */ a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));\r
991/* MR1 */ require(a!=NULL, "rule lmember: cannot allocate action");\r
992/* MR1 */ strcpy(a, LATEXT(1));\r
993/* MR1 */ list_add(&LexMemberActions, a);\r
994/* MR1 */ };\r
995/* MR1 */ >>\r
996/* MR1 */ ;\r
997/* MR1 */ <<CannotContinue=TRUE;>>\r
998\r
999/* rule lprefix */\r
1000\r
1001lprefix: <<char *a;>> /* MR1 */\r
1002\r
1003/* MR1 */ "{\\}#lexprefix"\r
1004/* MR1 */ Action\r
1005/* MR1 */ <<\r
1006/* MR1 */ if (! GenCC) {\r
1007/* MR1 */ err("Use #lexprefix only in C++ mode (to insert code in DLG class header");\r
1008/* MR1 */ } else {\r
1009/* MR1 */ a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));\r
1010/* MR1 */ require(a!=NULL, "rule lprefix: cannot allocate action");\r
1011/* MR1 */ strcpy(a, LATEXT(1));\r
1012/* MR1 */ list_add(&LexPrefixActions, a);\r
1013/* MR1 */ };\r
1014/* MR1 */ >>\r
1015/* MR1 */ ;\r
1016/* MR1 */ <<CannotContinue=TRUE;>>\r
1017\r
1018/*\r
1019 * #pred upper <<isupper()>>? predicate literal\r
1020 * #pred lower <<islower()>>? predicate literal\r
1021 * #pred up_or_low upper || lower predicate expression\r
1022 * concealed interdependence\r
1023 * #pred up_or_low_2 <<isletter()>>? A || B predicate literal equals predicate expr\r
1024 * analyze using lower||upper\r
1025 * generate using isLetter()\r
1026 */\r
1027\r
1028/* rule aPref */\r
1029\r
1030aPred: <<PredEntry *predEntry=NULL;\r
1031 char *name=NULL;\r
1032 Predicate *predExpr=NULL;\r
1033 char *predLiteral=NULL;\r
1034 int save_file;\r
1035 int save_line;\r
1036 int predExprPresent=0;\r
1037 >>\r
1038\r
1039 "{\\}#pred"\r
1040\r
1041 <<\r
1042 MR_usingPredNames=1; /* will need to use -mrhoist version of genPredTree */\r
1043 >>\r
1044\r
1045 /* used to allow NonTerminal but it caused problems\r
1046 when a rule name immediately followed a #pred statement */\r
1047\r
1048 TokenTerm <<name=mystrdup(LATEXT(1));>>\r
1049\r
1050 <<\r
1051 /* don't free - referenced in predicates */\r
1052\r
1053 CurPredName=(char *)calloc(1,strlen(name) + 10);\r
1054 strcat(CurPredName,"#pred ");\r
1055 strcat(CurPredName,name);\r
1056\r
1057 predEntry=(PredEntry *) hash_get(Pname,name);\r
1058 if (predEntry != NULL) {\r
1059 warnFL(eMsg1("#pred %s previously defined - ignored",name),\r
1060 FileStr[action_file],action_line);\r
1061 name=NULL;\r
1062 };\r
1063 >>\r
1064\r
1065 (\r
1066\r
1067 Pred <<predLiteral=mystrdup(LATEXT(1));\r
1068 save_line=action_line;\r
1069 save_file=action_file;\r
1070 >>\r
1071\r
1072 {\r
1073 predOrExpr>[predExpr] <<predExprPresent=1;>>\r
1074 }\r
1075\r
1076 <<if (predLiteral != NULL && name != NULL) {\r
1077\r
1078 /*\r
1079 * predExpr may be NULL due to syntax errors\r
1080 * or simply omitted by the user\r
1081 */\r
1082\r
1083 predEntry=newPredEntry(name);\r
1084 predEntry->file=save_file;\r
1085 predEntry->line=save_line;\r
1086 predExpr=MR_predFlatten(predExpr);\r
1087 predEntry->predLiteral=predLiteral;\r
1088 if (! predExprPresent || predExpr == NULL) {\r
1089 predExpr=new_pred();\r
1090 predExpr->expr=predLiteral;\r
1091 predExpr->source=newActionNode();\r
1092 predExpr->source->action=predExpr->expr;\r
1093 predExpr->source->rname=CurPredName;\r
1094 predExpr->source->line=action_line;\r
1095 predExpr->source->file=action_file;\r
1096 predExpr->source->is_predicate=1;\r
1097 predExpr->k=predicateLookaheadDepth(predExpr->source);\r
1098 };\r
1099 predEntry->pred=predExpr;\r
1100 hash_add(Pname,name,(Entry *)predEntry);\r
1101 predExpr=NULL;\r
1102 };\r
1103 predicate_free(predExpr);\r
1104 >>\r
1105\r
1106 |\r
1107 <<save_line=zzline; save_file=CurFile;>>\r
1108\r
1109 predOrExpr>[predExpr]\r
1110\r
1111 <<if (predExpr != NULL && name != NULL) {\r
1112 predEntry=newPredEntry(name);\r
1113 predEntry->file=CurFile;\r
1114 predEntry->line=zzline;\r
1115 predExpr=MR_predFlatten(predExpr);\r
1116 predEntry->pred=predExpr;\r
1117 hash_add(Pname,name,(Entry *)predEntry);\r
1118 predExpr=NULL;\r
1119 };\r
1120 predicate_free(predExpr);\r
1121 >>\r
1122 )\r
1123 {";"}\r
1124;\r
1125\r
1126/* fail */\r
1127\r
1128<<predicate_free(predExpr);\r
1129>>\r
1130\r
1131/* rule predOrExpr */\r
1132\r
1133predOrExpr>[Predicate *result] :\r
1134 <<Predicate *ORnode;\r
1135 Predicate *predExpr;\r
1136 Predicate **tail=NULL;\r
1137 >>\r
1138 predAndExpr>[predExpr]\r
1139 <<\r
1140 ORnode=new_pred();\r
1141 ORnode->expr=PRED_OR_LIST;\r
1142 if (predExpr != NULL) {\r
1143 ORnode->down=predExpr;\r
1144 tail=&predExpr->right;\r
1145 };\r
1146 >>\r
1147 ( "\|\|" predAndExpr>[predExpr]\r
1148 <<\r
1149 if (predExpr != NULL) {\r
1150 *tail=predExpr;\r
1151 tail=&predExpr->right;\r
1152 };\r
1153 >>\r
1154 )*\r
1155 <<\r
1156 $result=ORnode;\r
1157 ORnode=NULL;\r
1158 >>\r
1159;\r
1160\r
1161/* fail */\r
1162\r
1163<<predicate_free(ORnode);>>\r
1164\r
1165/* rule predAndExpr */\r
1166\r
1167predAndExpr>[Predicate *result] :\r
1168 <<Predicate *ANDnode;\r
1169 Predicate *predExpr;\r
1170 Predicate **tail=NULL;\r
1171 >>\r
1172 predPrimary>[predExpr]\r
1173 <<\r
1174 ANDnode=new_pred();\r
1175 ANDnode->expr=PRED_AND_LIST;\r
1176 if (predExpr != NULL) {\r
1177 ANDnode->down=predExpr;\r
1178 tail=&predExpr->right;\r
1179 };\r
1180 >>\r
1181 ( "&&" predPrimary>[predExpr]\r
1182 <<\r
1183 if (predExpr != NULL) {\r
1184 *tail=predExpr;\r
1185 tail=&predExpr->right;\r
1186 };\r
1187 >>\r
1188 )*\r
1189 <<\r
1190 $result=ANDnode;\r
1191 ANDnode=NULL;\r
1192 >>\r
1193;\r
1194\r
1195/* fail */\r
1196\r
1197<<predicate_free(ANDnode);>>\r
1198\r
1199\r
1200/* rule predPrimary */\r
1201\r
1202predPrimary>[Predicate *result] :\r
1203 <<\r
1204 char *name=NULL;\r
1205 PredEntry *predEntry=NULL;\r
1206 Predicate *predExpr=NULL;\r
1207 >>\r
1208\r
1209 TokenTerm <<name=mystrdup(LATEXT(1));>>\r
1210\r
1211 <<\r
1212 predEntry=(PredEntry *) hash_get(Pname,name);\r
1213 if (predEntry == NULL) {\r
1214 warnFL(eMsg1("no previously defined #pred with name \"%s\"",name),\r
1215 FileStr[CurFile],zzline);\r
1216 name=NULL;\r
1217 $result=NULL;\r
1218 } else {\r
1219 predExpr=predicate_dup(predEntry->pred);\r
1220 predExpr->predEntry=predEntry;\r
1221 $result=predExpr;\r
1222 };\r
1223 >>\r
1224\r
1225 | "\(" predOrExpr>[predExpr] "\)"\r
1226 <<\r
1227 $result=predExpr;\r
1228 >>\r
1229\r
1230 | "!" predPrimary>[predExpr]\r
1231 <<\r
1232 predExpr->inverted=!predExpr->inverted;\r
1233 $result=predExpr;\r
1234 >>\r
1235;\r
1236\r
1237/* fail */ <<\r
1238 predicate_free(predExpr);\r
1239 >>\r
1240\r
1241/* rule aLexclass */\r
1242\r
1243aLexclass: "{\\}#lexclass" TokenTerm <<lexclass(mystrdup(LATEXT(1)));>>\r
1244 ;\r
1245 <<CannotContinue=TRUE;>>\r
1246\r
1247/* rule error */\r
1248\r
1249error : <<char *t=NULL; ECnode *e; int go=1; TermEntry *p;>>\r
1250 "{\\}#errclass"\r
1251 (<<;>> TokenTerm <<t=mystrdup(LATEXT(1));>>\r
1252 | QuotedTerm <<t=mystrdup(LATEXT(1));>>\r
1253 )\r
1254 <<e = newECnode;\r
1255 require(e!=NULL, "cannot allocate error class node");\r
1256 e->lexclass = CurrentLexClass;\r
1257 if ( Tnum( (t=StripQuotes(t)) ) == 0 )\r
1258 {\r
1259 if ( hash_get(Texpr, t) != NULL )\r
1260 warn(eMsg1("errclass name conflicts with regular expression '%s'",t));\r
1261 e->tok = addTname( t );\r
1262 set_orel(e->tok, &imag_tokens);\r
1263 require((p=(TermEntry *)hash_get(Tname, t)) != NULL,\r
1264 "hash table mechanism is broken");\r
1265 p->classname = 1; /* entry is errclass name, not token */\r
1266 list_add(&eclasses, (char *)e);\r
1267 }\r
1268 else\r
1269 {\r
1270 warn(eMsg1("redefinition of errclass or conflict w/token or tokclass '%s'; ignored",t));\r
1271 free( (char *)e );\r
1272 go=0;\r
1273 }\r
1274 >>\r
1275 "\{"\r
1276 ( NonTerminal <<if ( go ) t=mystrdup(LATEXT(1));>>\r
1277 | TokenTerm <<if ( go ) t=mystrdup(LATEXT(1));>>\r
1278 | QuotedTerm <<if ( go ) t=mystrdup(LATEXT(1));>>\r
1279 )\r
1280 <<if ( go ) list_add(&(e->elist), t);>>\r
1281 (\r
1282 ( NonTerminal <<if ( go ) t=mystrdup(LATEXT(1));>>\r
1283 | TokenTerm <<if ( go ) t=mystrdup(LATEXT(1));>>\r
1284 | QuotedTerm <<if ( go ) t=mystrdup(LATEXT(1));>>\r
1285 )\r
1286 <<if ( go ) list_add(&(e->elist), t);>>\r
1287 )*\r
1288 "\}"\r
1289 ;\r
1290 <<CannotContinue=TRUE;>>\r
1291\r
1292/* rule tclass */\r
1293\r
1294tclass : <<char *t=NULL; TCnode *e; int go=1,tok,totok; TermEntry *p, *term, *toterm;>>\r
1295 <<char *akaString=NULL; int save_file; int save_line;>>\r
1296 <<char *totext=NULL; >>\r
1297 "{\\}#tokclass" TokenTerm <<t=mystrdup(LATEXT(1));>>\r
1298 <<e = newTCnode;\r
1299 require(e!=NULL, "cannot allocate token class node");\r
1300 e->lexclass = CurrentLexClass;\r
1301 if ( Tnum( t ) == 0 )\r
1302 {\r
1303 e->tok = addTname( t );\r
1304 set_orel(e->tok, &imag_tokens);\r
1305 set_orel(e->tok, &tokclasses);\r
1306 require((p=(TermEntry *)hash_get(Tname, t)) != NULL,\r
1307 "hash table mechanism is broken");\r
1308 p->classname = 1; /* entry is class name, not token */\r
1309 p->tclass = e; /* save ptr to this tclass def */\r
1310 list_add(&tclasses, (char *)e);\r
1311 }\r
1312 else\r
1313 {\r
1314 warn(eMsg1("redefinition of tokclass or conflict w/token '%s'; ignored",t));\r
1315 free( (char *)e );\r
1316 go=0;\r
1317 }\r
1318 >>\r
1319/* MR23 */ {\r
1320/* MR23 */ "\("\r
1321/* MR23 */ QuotedTerm\r
1322/* MR23 */ <<akaString=mystrdup(StripQuotes(LATEXT(1)));\r
1323/* MR11 */ save_file=CurFile;save_line=zzline;\r
1324/* MR23 */ >>\r
1325/* MR23 */ "\)"\r
1326/* MR23 */ }\r
1327/* MR23 */\r
1328/* MR23 */\r
1329/* MR23 */ <<\r
1330/* MR23 */ if (p!= NULL && akaString != NULL) {\r
1331/* MR23 */ if (p->akaString != NULL) {\r
1332/* MR23 */ if (strcmp(p->akaString,akaString) != 0) {\r
1333/* MR23 */ warnFL(eMsg2("this #tokclass statment conflicts with a previous #tokclass %s(\"%s\") statement",\r
1334/* MR23 */ t,p->akaString),\r
1335/* MR23 */ FileStr[save_file],save_line);\r
1336/* MR23 */ };\r
1337/* MR23 */ } else {\r
1338/* MR23 */ p->akaString=akaString;\r
1339/* MR23 */ };\r
1340/* MR23 */ };\r
1341/* MR23 */ >>\r
1342\r
1343 "\{"\r
1344 (\r
1345 ( TokenTerm\r
1346 <<if ( go ) {\r
1347 term = (TermEntry *) hash_get(Tname, LATEXT(1));\r
1348 if ( term==NULL && UserDefdTokens ) {\r
1349 err("implicit token definition not allowed with #tokdefs");\r
1350 go = 0;\r
1351 }\r
1352 else {t=mystrdup(LATEXT(1)); tok=addTname(LATEXT(1));}\r
1353 }>>\r
1354\r
1355 {\r
1356 ".."\r
1357 TokenTerm\r
1358\r
1359 <<if ( go ) {\r
1360 toterm = (TermEntry *) hash_get(Tname, LATEXT(1));\r
1361 if ( toterm==NULL && UserDefdTokens ) {\r
1362 err("implicit token definition not allowed with #tokdefs");\r
1363 go = 0;\r
1364 } else {\r
1365 totext=mystrdup(LATEXT(1)); totok=addTname(LATEXT(1));\r
1366 }\r
1367 }\r
1368 >>\r
1369 }\r
1370\r
1371 | QuotedTerm\r
1372 <<if ( go ) {\r
1373 term = (TermEntry *) hash_get(Texpr, LATEXT(1));\r
1374 if ( term==NULL && UserDefdTokens ) {\r
1375 err("implicit token definition not allowed with #tokdefs");\r
1376 go = 0;\r
1377 }\r
1378 else {t=mystrdup(LATEXT(1)); tok=addTexpr(LATEXT(1));}\r
1379 }>>\r
1380 )\r
1381 <<if ( go ) {\r
1382 if (totext == NULL) {\r
1383 list_add(&(e->tlist), t);\r
1384 } else {\r
1385 list_add(&(e->tlist),"..");\r
1386 list_add(&(e->tlist),t);\r
1387 list_add(&(e->tlist),totext);\r
1388 }\r
1389 totext=NULL;\r
1390 }\r
1391 >>\r
1392 )+ // MR15 Manfred Kogler - forbid empty #tokclass sets (was "+")\r
1393 "\}"\r
1394 ;\r
1395 <<CannotContinue=TRUE;>>\r
1396\r
1397/* rule token */\r
1398\r
1399token : <<char *t=NULL, *e=NULL, *a=NULL; int tnum=0;>>\r
1400 <<char *akaString=NULL; TermEntry *te;int save_file=0,save_line=0;>> /* MR11 */\r
1401 "{\\}#token"\r
1402\r
1403/* MR1 10-Apr-97 MR1 Allow shift right operator in DLG actions */\r
1404/* MR1 Danger when parser feedback to lexer */\r
1405/* MR1 */\r
1406\r
1407 <<tokenActionActive=1;>> /* MR1 */\r
1408 { TokenTerm <<t=mystrdup(LATEXT(1));>>\r
1409\r
1410/* MR11 */ {\r
1411/* MR11 */ "\("\r
1412/* MR11 */ QuotedTerm\r
1413/* MR11 */ <<akaString=mystrdup(StripQuotes(LATEXT(1)));\r
1414/* MR11 */ save_file=CurFile;save_line=zzline;\r
1415/* MR11 */ >>\r
1416/* MR11 */ "\)"\r
1417/* MR11 */ }\r
1418\r
1419 { "=" "[0-9]+" /* define the token type number */\r
1420 <<tnum = atoi(LATEXT(1));>>\r
1421 }\r
1422 }\r
1423 { QuotedTerm <<e=mystrdup(LATEXT(1));>> }\r
1424 { Action\r
1425 <<\r
1426 a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));\r
1427 require(a!=NULL, "rule token: cannot allocate action");\r
1428 strcpy(a, LATEXT(1));\r
1429 >>\r
1430 }\r
1431\r
1432 { ";" } /* MR11 */\r
1433\r
1434 <<chkToken(t, e, a, tnum);>>\r
1435\r
1436 <<if (t != NULL) {\r
1437 te=(TermEntry *)hash_get(Tname,t);\r
1438 if (te != NULL && akaString != NULL) {\r
1439 if (te->akaString != NULL) {\r
1440 if (strcmp(te->akaString,akaString) != 0) {\r
1441 warnFL(eMsg2("this #token statment conflicts with a previous #token %s(\"%s\") statement",\r
1442 t,te->akaString),\r
1443 FileStr[save_file],save_line);\r
1444 };\r
1445 } else {\r
1446 te->akaString=akaString;\r
1447 };\r
1448 };\r
1449 };\r
1450 >>\r
1451 ;\r
1452 <<CannotContinue=TRUE;>>\r
1453\r
1454/* rule block */\r
1455\r
1456block[set *toksrefd, set *rulesrefd]\r
1457 : <<\r
1458 Graph g, b;\r
1459 set saveblah;\r
1460 int saveinalt = inAlt;\r
1461 ExceptionGroup *eg;\r
1462 *$toksrefd = empty;\r
1463 *$rulesrefd = empty;\r
1464 set_clr(AST_nodes_refd_in_actions);\r
1465 CurBlockID++;\r
1466/* MR23 */ CurBlockID_array[BlkLevel] = CurBlockID;\r
1467 CurAltNum = 1;\r
1468/* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum; \r
1469 saveblah = attribsRefdFromAction;\r
1470 attribsRefdFromAction = empty;\r
1471 >>\r
1472\r
1473 alt[toksrefd,rulesrefd] <<b = g = $1;>>\r
1474\r
1475 <<\r
1476 if ( ((Junction *)g.left)->p1->ntype == nAction )\r
1477 {\r
1478 ActionNode *actionNode=(ActionNode *)\r
1479 ( ( (Junction *)g.left) ->p1);\r
1480 if (!actionNode->is_predicate )\r
1481 {\r
1482 actionNode->init_action = TRUE;\r
1483/* MR12c */ if (actionNode->noHoist) {\r
1484/* MR12c */ errFL("<<nohoist>> appears as init-action - use <<>> <<nohoist>>",\r
1485/* MR12c */ FileStr[actionNode->file],actionNode->line);\r
1486/* MR12c */ };\r
1487 }\r
1488 }\r
1489 ((Junction *)g.left)->blockid = CurBlockID;\r
1490 >>\r
1491\r
1492 ( exception_group > [eg]\r
1493 <<\r
1494 if ( eg!=NULL ) {\r
1495/* MR7 ***** eg->altID = makeAltID(CurBlockID,CurAltNum); *****/\r
1496/* MR7 ***** CurAltStart->exception_label = eg->altID; *****/\r
1497 list_add(&CurExGroups, (void *)eg);\r
1498 }\r
1499 >>\r
1500 )*\r
1501 <<CurAltNum++;\r
1502/* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum;\r
1503 >>\r
1504\r
1505 ( "\|" <<inAlt=1;>>\r
1506 alt[toksrefd,rulesrefd] <<g = Or(g, $2);>>\r
1507 <<\r
1508 ((Junction *)g.left)->blockid = CurBlockID;\r
1509 >>\r
1510\r
1511 ( exception_group > [eg]\r
1512 <<\r
1513 if ( eg!=NULL ) {\r
1514/* MR7 ***** eg->altID = makeAltID(CurBlockID,CurAltNum); *****/\r
1515/* MR7 ***** CurAltStart->exception_label = eg->altID; *****/\r
1516 list_add(&CurExGroups, (void *)eg);\r
1517 }\r
1518 >>\r
1519 )*\r
1520\r
1521 <<CurAltNum++;\r
1522/* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum; \r
1523 >>\r
1524\r
1525 )*\r
1526 <<$0 = b;>>\r
1527 <<attribsRefdFromAction = saveblah; inAlt = saveinalt;>>\r
1528 ;\r
1529 <<CannotContinue=TRUE;>>\r
1530\r
1531/* rule alt */\r
1532\r
1533alt[set *toksrefd, set *rulesrefd]\r
1534 : <<int n=0; Graph g; int e_num=0, old_not=0; Node *node; set elems, dif;\r
1535 int first_on_line = 1, use_def_MT_handler = 0;\r
1536 g.left=NULL; g.right=NULL;\r
1537\r
1538 CurAltStart = NULL;\r
1539 elems = empty;\r
1540 inAlt = 1;\r
1541 >>\r
1542 { "\@" /* handle MismatchedToken signals with default handler */\r
1543 <<use_def_MT_handler = 1;>>\r
1544 }\r
1545\r
1546 ( <<;>> /* MR9 Removed unreferenced variable "tok" */\r
1547 { <<old_not=0;>> "\~" <<old_not=1;>> }\r
1548 element[old_not, first_on_line, use_def_MT_handler] > [node]\r
1549 <<if ( node!=NULL && node->ntype!=nAction ) first_on_line = 0;>>\r
1550 <<\r
1551 if ( $2.left!=NULL ) {\r
1552 g = Cat(g, $2);\r
1553 n++;\r
1554 if ( node!=NULL ) {\r
1555 if ( node->ntype!=nAction ) e_num++;\r
1556 /* record record number of all rule and token refs */\r
1557 if ( node->ntype==nToken ) {\r
1558 TokNode *tk = (TokNode *)((Junction *)$2.left)->p1;\r
1559 tk->elnum = e_num;\r
1560 set_orel(e_num, &elems);\r
1561 }\r
1562 else if ( node->ntype==nRuleRef ) {\r
1563 RuleRefNode *rn = (RuleRefNode *)((Junction *)$2.left)->p1;\r
1564 rn->elnum = e_num;\r
1565 set_orel(e_num, $rulesrefd);\r
1566 }\r
1567 }\r
1568 }\r
1569 >>\r
1570 )*\r
1571 <<if ( n == 0 ) g = emptyAlt();\r
1572 $0 = g;\r
1573 /* We want to reduce number of LT(i) calls and the number of\r
1574 * local attribute variables in C++ mode (for moment, later we'll\r
1575 * do for C also). However, if trees are being built, they\r
1576 * require most of the attrib variables to create the tree nodes\r
1577 * with; therefore, we gen a token ptr for each token ref in C++\r
1578 */\r
1579 if ( GenCC && !GenAST )\r
1580 {\r
1581 /* This now free's the temp set -ATG 5/6/95 */\r
1582 set temp;\r
1583 temp = set_and(elems, attribsRefdFromAction);\r
1584 set_orin($toksrefd, temp);\r
1585 set_free(temp);\r
1586 }\r
1587 else set_orin($toksrefd, elems);\r
1588 if ( GenCC ) {\r
1589 dif = set_dif(attribsRefdFromAction, elems);\r
1590 if ( set_deg(dif)>0 )\r
1591 err("one or more $i in action(s) refer to non-token elements");\r
1592 set_free(dif);\r
1593 }\r
1594 set_free(elems);\r
1595 set_free(attribsRefdFromAction);\r
1596 inAlt = 0;\r
1597 >>\r
1598 ;\r
1599 <<CannotContinue=TRUE;>>\r
1600\r
1601/* rule element_label */\r
1602\r
1603element_label > [LabelEntry *label]\r
1604 : <<TermEntry *t=NULL; LabelEntry *l=NULL; RuleEntry *r=NULL; char *lab;>>\r
1605 LABEL <<lab = mystrdup(LATEXT(1));>>\r
1606 <<\r
1607 UsedNewStyleLabel = 1;\r
1608 if ( UsedOldStyleAttrib ) err("cannot mix with new-style labels with old-style $i");\r
1609 t = (TermEntry *) hash_get(Tname, lab);\r
1610 if ( t==NULL ) t = (TermEntry *) hash_get(Texpr, lab);\r
1611 if ( t==NULL ) r = (RuleEntry *) hash_get(Rname, lab);\r
1612 if ( t!=NULL ) {\r
1613 err(eMsg1("label definition clashes with token/tokclass definition: '%s'", lab));\r
1614 $label = NULL;\r
1615 }\r
1616 else if ( r!=NULL ) {\r
1617 err(eMsg1("label definition clashes with rule definition: '%s'", lab));\r
1618 $label = NULL;\r
1619 }\r
1620 else {\r
1621 /* we don't clash with anybody else */\r
1622 l = (LabelEntry *) hash_get(Elabel, lab);\r
1623 if ( l==NULL ) { /* ok to add new element label */\r
1624 l = (LabelEntry *)hash_add(Elabel,\r
1625 lab,\r
1626 (Entry *)newLabelEntry(lab));\r
1627 /* add to list of element labels for this rule */\r
1628 list_add(&CurElementLabels, (void *)lab);\r
1629/* MR7 */ leAdd(l); /* list of labels waiting for exception group definitions */\r
1630 $label = l;\r
1631 }\r
1632 else {\r
1633 err(eMsg1("label definitions must be unique per rule: '%s'", lab));\r
1634 $label = NULL;\r
1635 }\r
1636 }\r
1637 >>\r
1638 ":"\r
1639 ;\r
1640\r
1641/* rule element */\r
1642\r
1643element[int old_not, int first_on_line, int use_def_MT_handler] > [Node *node]\r
1644 : <<\r
1645 Attrib blk;\r
1646 Predicate *pred = NULL;\r
1647 int local_use_def_MT_handler=0;\r
1648 ActionNode *act;\r
1649 RuleRefNode *rr;\r
1650 set toksrefd, rulesrefd;\r
1651 TermEntry *term;\r
1652 TokNode *p=NULL; RuleRefNode *q; int approx=0;\r
1653 LabelEntry *label=NULL;\r
1654 int predMsgDone=0;\r
1655 int semDepth=0;\r
1656 int ampersandStyle;\r
1657 int height; /* MR11 */\r
1658 int equal_height; /* MR11 */\r
1659\r
1660 char* pFirstSetSymbol = NULL; /* MR21 */\r
1661\r
1662 $node = NULL;\r
1663 >>\r
1664 {element_label>[label]}\r
1665 ( TokenTerm\r
1666 <<\r
1667 term = (TermEntry *) hash_get(Tname, LATEXT(1));\r
1668 if ( term==NULL && UserDefdTokens ) {\r
1669 err("implicit token definition not allowed with #tokdefs");\r
1670 $$.left = $$.right = NULL;\r
1671 }\r
1672 else {\r
1673 $$ = buildToken(LATEXT(1));\r
1674 p=((TokNode *)((Junction *)$$.left)->p1);\r
1675 term = (TermEntry *) hash_get(Tname, LATEXT(1));\r
1676 require( term!= NULL, "hash table mechanism is broken");\r
1677 p->tclass = term->tclass;\r
1678 p->complement = $old_not;\r
1679 if ( label!=NULL ) {\r
1680 p->el_label = label->str;\r
1681 label->elem = (Node *)p;\r
1682 }\r
1683 }\r
1684 >>\r
1685 { ".."\r
1686 ( QuotedTerm\r
1687 <<if ( p!=NULL ) setUpperRange(p, LATEXT(1));>>\r
1688 | TokenTerm\r
1689 <<if ( p!=NULL ) setUpperRange(p, LATEXT(1));>>\r
1690 )\r
1691 }\r
1692 <<\r
1693 if ( p!=NULL && (p->upper_range!=0 || p->tclass || $old_not) )\r
1694 list_add(&MetaTokenNodes, (void *)p);\r
1695 >>\r
1696 ( "^" <<if ( p!=NULL ) p->astnode=ASTroot;>>\r
1697 | <<if ( p!=NULL ) p->astnode=ASTchild;>>\r
1698 | "!" <<if ( p!=NULL ) p->astnode=ASTexclude;>>\r
1699 )\r
1700 { "\@" <<local_use_def_MT_handler = 1;>> }\r
1701 <<\r
1702 if ( p!=NULL && $first_on_line ) {\r
1703 CurAltStart = (Junction *)$$.left;\r
1704 altAdd(CurAltStart); /* MR7 */\r
1705 p->altstart = CurAltStart;\r
1706 }\r
1707 if ( p!=NULL )\r
1708 p->use_def_MT_handler = $use_def_MT_handler || local_use_def_MT_handler;\r
1709 $node = (Node *)p;\r
1710 >>\r
1711 | QuotedTerm\r
1712 <<\r
1713 term = (TermEntry *) hash_get(Texpr, LATEXT(1));\r
1714 if ( term==NULL && UserDefdTokens ) {\r
1715 err("implicit token definition not allowed with #tokdefs");\r
1716 $$.left = $$.right = NULL;\r
1717 }\r
1718 else {\r
1719 $$ = buildToken(LATEXT(1)); p=((TokNode *)((Junction *)$$.left)->p1);\r
1720 p->complement = $old_not;\r
1721 if ( label!=NULL ) {\r
1722 p->el_label = label->str;\r
1723 label->elem = (Node *)p;\r
1724 }\r
1725 }\r
1726 >>\r
1727 { ".."\r
1728 ( QuotedTerm\r
1729 <<if ( p!=NULL ) setUpperRange(p, LATEXT(1));>>\r
1730 | TokenTerm\r
1731 <<if ( p!=NULL ) setUpperRange(p, LATEXT(1));>>\r
1732 )\r
1733 }\r
1734 ( "^" <<if ( p!=NULL ) p->astnode=ASTroot;>>\r
1735 | <<if ( p!=NULL ) p->astnode=ASTchild;>>\r
1736 | "!" <<if ( p!=NULL ) p->astnode=ASTexclude;>>\r
1737 )\r
1738 { "\@" <<local_use_def_MT_handler = 1;>> }\r
1739 <<\r
1740 if ( p!=NULL && (p->upper_range!=0 || p->tclass || $old_not) )\r
1741 list_add(&MetaTokenNodes, (void *)p);\r
1742 >>\r
1743 <<\r
1744 if ( $first_on_line ) {\r
1745 CurAltStart = (Junction *)$$.left;\r
1746 altAdd(CurAltStart); /* MR7 */\r
1747 p->altstart = CurAltStart;\r
1748 }\r
1749 if ( p!=NULL )\r
1750 p->use_def_MT_handler = $use_def_MT_handler || local_use_def_MT_handler;\r
1751 $node = (Node *)p;\r
1752 >>\r
1753\r
1754 | <<if ( $old_not ) warn("~ WILDCARD is an undefined operation (implies 'nothing')");>>\r
1755 "."\r
1756 <<$$ = buildWildCard(LATEXT(1)); p=((TokNode *)((Junction *)$$.left)->p1);>>\r
1757 ( "^" <<p->astnode=ASTroot;>>\r
1758 | <<p->astnode=ASTchild;>>\r
1759 | "!" <<p->astnode=ASTexclude;>>\r
1760 )\r
1761 <<list_add(&MetaTokenNodes, (void *)p);>>\r
1762 <<\r
1763 if ( $first_on_line ) {\r
1764 CurAltStart = (Junction *)$$.left;\r
1765 altAdd(CurAltStart); /* MR7 */\r
1766 p->altstart = CurAltStart;\r
1767 if ( label!=NULL ) {\r
1768 p->el_label = label->str;\r
1769 label->elem = (Node *)p;\r
1770 }\r
1771 }\r
1772 $node = (Node *)p;\r
1773 >>\r
1774\r
1775 | <<if ( $old_not ) warn("~ NONTERMINAL is an undefined operation");>>\r
1776 NonTerminal\r
1777 <<$$ = buildRuleRef(LATEXT(1));>>\r
1778 { "!" <<q = (RuleRefNode *) ((Junction *)$$.left)->p1;\r
1779 q->astnode=ASTexclude;>>\r
1780 }\r
1781 { {"\<"}\r
1782 PassAction <<addParm(((Junction *)$$.left)->p1, LATEXT(1));>>\r
1783 }\r
1784 <<rr=(RuleRefNode *) ((Junction *)$$.left)->p1;>>\r
1785 { <<char *a;>>\r
1786 "\>"\r
1787 PassAction\r
1788 <<\r
1789 a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));\r
1790 require(a!=NULL, "rule element: cannot allocate assignment");\r
1791 strcpy(a, LATEXT(1));\r
1792 rr->assign = a;\r
1793 >>\r
1794 }\r
1795 <<\r
1796 if ( label!=NULL ) {\r
1797 rr->el_label = label->str;\r
1798 label->elem = (Node *)rr;\r
1799 }\r
1800 if ( $first_on_line ) {\r
1801 CurAltStart = (Junction *)$$.left;\r
1802 altAdd(CurAltStart); /* MR7 */\r
1803 ((RuleRefNode *)((Junction *)$$.left)->p1)->altstart = CurAltStart;\r
1804 }\r
1805 $node = (Node *)rr;\r
1806 >>\r
1807 )\r
1808\r
1809 | <<if ( $old_not ) warn("~ ACTION is an undefined operation");>>\r
1810 Action <<$0 = buildAction(LATEXT(1),action_file,action_line, 0);>>\r
1811 <<if ( $first_on_line ) { /* MR7 */\r
1812 CurAltStart = (Junction *)$0.left; /* MR7 */\r
1813 altAdd(CurAltStart); /* MR7 */\r
1814 };>> /* MR7 */\r
1815 <<$node = (Node *) ((Junction *)$0.left)->p1;>>\r
1816\r
1817 | <<if ( $old_not ) warn("~ SEMANTIC-PREDICATE is an undefined operation");>>\r
1818 Pred <<$0 = buildAction(LATEXT(1),action_file,action_line, 1);>>\r
1819 <<act = (ActionNode *) ((Junction *)$0.left)->p1;>>\r
1820 <<if (numericActionLabel) { /* MR10 */\r
1821 list_add(&NumericPredLabels,act); /* MR10 */\r
1822 numericActionLabel=0; /* MR10 */\r
1823 }; /* MR10 */\r
1824 >>\r
1825 { <<char *a;>>\r
1826 PassAction\r
1827 <<\r
1828 a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));\r
1829 require(a!=NULL, "rule element: cannot allocate predicate fail action");\r
1830 strcpy(a, LATEXT(1));\r
1831 act->pred_fail = a;\r
1832 >>\r
1833 }\r
1834 <<if ( $first_on_line ) { /* MR7 */\r
1835 CurAltStart = (Junction *)$0.left; /* MR7 */\r
1836 altAdd(CurAltStart); /* MR7 */\r
1837 };>> /* MR7 */\r
1838 <<$node = (Node *)act;>>\r
1839\r
1840 | <<if ( $old_not ) warn("~ BLOCK is an undefined operation");>>\r
1841 <<BlkLevel++;\r
1842 if (BlkLevel >= MAX_BLK_LEVEL) fatal("Blocks nested too deeply");\r
1843/* MR23 */ CurBlockID_array[BlkLevel] = CurBlockID;\r
1844/* MR23 */ CurAltNum_array[BlkLevel] = CurAltNum; \r
1845 >>\r
1846 { Pragma\r
1847 ( "approx" <<approx=LL_k;>>\r
1848 | "LL\(1\)" <<approx = 1;>> /* MR20 */\r
1849 | "LL\(2\)" <<approx = 2;>> /* MR20 */\r
1850 )\r
1851 }\r
1852\r
1853/* MR21 */ { FirstSetSymbol\r
1854/* MR21 */ "\("\r
1855/* MR21 */ ( NonTerminal\r
1856/* MR21 */ <<\r
1857/* MR21 */ pFirstSetSymbol = (char *) calloc(strlen(LATEXT(1))+1,\r
1858/* MR21 */ sizeof(char));\r
1859/* MR21 */ require(pFirstSetSymbol!=NULL,\r
1860/* MR21 */ "cannot allocate first set name");\r
1861/* MR21 */ strcpy(pFirstSetSymbol, LATEXT(1));\r
1862/* MR21 */ >>\r
1863/* MR21 */ | TokenTerm\r
1864/* MR21 */ <<\r
1865/* MR21 */ pFirstSetSymbol = (char *) calloc(strlen(LATEXT(1))+1,\r
1866/* MR21 */ sizeof(char));\r
1867/* MR21 */ require(pFirstSetSymbol!=NULL,\r
1868/* MR21 */ "cannot allocate first set name");\r
1869/* MR21 */ strcpy(pFirstSetSymbol, LATEXT(1));\r
1870/* MR21 */ >>\r
1871/* MR21 */ )\r
1872/* MR21 */ "\)"\r
1873/* MR21 */ }\r
1874\r
1875 (\r
1876\r
1877 "\(" block[&toksrefd,&rulesrefd] "\)"\r
1878 <<blk = $$ = $2;\r
1879 /* MR23 */ CurBlockID_array[BlkLevel] = (-1);\r
1880 /* MR23 */ CurAltNum_array[BlkLevel] = (-1); \r
1881 --BlkLevel;\r
1882 >>\r
1883\r
1884 ( "\*" <<$$ = makeLoop($$,approx,pFirstSetSymbol);>>\r
1885 | "\+" <<$$ = makePlus($$,approx,pFirstSetSymbol);>>\r
1886 | "?"\r
1887 ( \r
1888 ( "=>" <<ampersandStyle=0;>>\r
1889 | "&&" <<ampersandStyle=1;>> /* MR10 (g)? && <<p>>? */\r
1890 )\r
1891 Pred /* generalized predicate */\r
1892 /* first make into a predicate */\r
1893 <<$$ = buildAction(LATEXT(1),action_file,action_line,1);>>\r
1894 <<act = (ActionNode *) ((Junction *)$$.left)->p1;>>\r
1895 <<semDepth=predicateLookaheadDepth(act);>> /* MR10 */\r
1896 <<if (numericActionLabel) { /* MR10 */\r
1897 list_add(&NumericPredLabels,act); /* MR10 */\r
1898 numericActionLabel=0; /* MR10 */\r
1899 }; /* MR10 */\r
1900 >>\r
1901 { <<char *a;>>\r
1902 PassAction\r
1903 <<\r
1904 a = (char *)calloc(strlen(LATEXT(1))+1, sizeof(char));\r
1905 require(a!=NULL, "rule element: cannot allocate predicate fail action");\r
1906 strcpy(a, LATEXT(1));\r
1907 act->pred_fail = a;\r
1908 >>\r
1909 }\r
1910 <<if ($first_on_line) { /* MR7 */\r
1911 CurAltStart=(Junction *)$$.left; /* MR7 */\r
1912 altAdd(CurAltStart); /* MR7 */\r
1913 };>>\r
1914 <<$node = (Node *)act;>>\r
1915\r
1916 /* for now, just snag context */\r
1917 <<\r
1918 pred = computePredFromContextGuard(blk,&predMsgDone); /* MR10 */\r
1919 if ( pred==NULL) { /* MR10 */\r
1920 if ( !predMsgDone) err("invalid or missing context guard"); /* MR10 */\r
1921 predMsgDone=1; /* MR10 */\r
1922 } else { /* MR10 */\r
1923 act->guardNodes=(Junction *)blk.left; /* MR11 */\r
1924 pred->expr = act->action;\r
1925 pred->source = act;\r
1926/* MR10 */ pred->ampersandStyle = ampersandStyle; /* 0 means (g)? => ... 1 means (g)? && ... */\r
1927/* MR13 */ if (pred->tcontext != NULL) {\r
1928/* MR13 */ height=MR_max_height_of_tree(pred->tcontext);\r
1929/* MR13 */ equal_height=MR_all_leaves_same_height(pred->tcontext,height);\r
1930/* MR13 */ if (! equal_height) {\r
1931/* MR13 */ errFL("in guarded predicates all tokens in the guard must be at the same height",\r
1932/* MR13 */ FileStr[act->file],act->line);\r
1933/* MR13 */ };\r
1934/* MR13 */ }\r
1935/* MR10 */ if (ampersandStyle) {\r
1936/* MR10 */ act->ampersandPred = pred;\r
1937/* MR11 */ if (! HoistPredicateContext) {\r
1938/* MR11 */ errFL("without \"-prc on\" (guard)? && <<pred>>? ... doesn't make sense",\r
1939/* MR11 */ FileStr[act->file],act->line);\r
1940/* MR11 */ };\r
1941/* MR10 */ } else {\r
1942/* MR10 */ act->guardpred = pred;\r
1943/* MR10 */ };\r
1944/* MR10 */ if (pred->k != semDepth) {\r
1945/* MR10 */ warn(eMsgd2("length of guard (%d) does not match the length of semantic predicate (%d)",\r
1946/* MR10 */ pred->k,semDepth));\r
1947/* MR10 */ };\r
1948 }\r
1949 >>\r
1950 | <<$$ = makeBlk($$,approx,pFirstSetSymbol);\r
1951 FoundGuessBlk = 1;\r
1952 ((Junction *) ((Junction *)$$.left)->p1)->guess=1;\r
1953 if ( !$first_on_line ) {\r
1954 err("(...)? predicate must be first element of production");\r
1955 }\r
1956 >>\r
1957 )\r
1958 | <<$$ = makeBlk($$,approx,pFirstSetSymbol);>>\r
1959 )\r
1960 <<\r
1961 if ( pred==NULL && !predMsgDone) { /* MR10 */\r
1962 ((Junction *)((Junction *)$$.left)->p1)->blockid = CurBlockID;\r
1963 ((Junction *)((Junction *)$$.left)->p1)->tokrefs = toksrefd;\r
1964 ((Junction *)((Junction *)$$.left)->p1)->rulerefs = rulesrefd;\r
1965 if ( $first_on_line ) { /* MR7 */\r
1966 CurAltStart = (Junction *)((Junction *)((Junction *)$$.left)->p1); /* MR7 */\r
1967 altAdd(CurAltStart); /* MR7 */\r
1968 }; /* MR7 */\r
1969 $node = (Node *) ((Junction *)$$.left)->p1;\r
1970 }\r
1971 >>\r
1972\r
1973 | "\{" block[&toksrefd,&rulesrefd]\r
1974 <<$$ = makeOpt($2,approx,pFirstSetSymbol);\r
1975 /* MR23 */ CurBlockID_array[BlkLevel] = (-1);\r
1976 /* MR23 */ CurAltNum_array[BlkLevel] = (-1); \r
1977 --BlkLevel;\r
1978 >>\r
1979 "\}"\r
1980 <<\r
1981 ((Junction *)((Junction *)$$.left)->p1)->blockid = CurBlockID;\r
1982 ((Junction *)((Junction *)$$.left)->p1)->tokrefs = toksrefd;\r
1983 ((Junction *)((Junction *)$$.left)->p1)->rulerefs = rulesrefd;\r
1984 >>\r
1985 <<if ( $first_on_line ) { /* MR7 */\r
1986 CurAltStart = (Junction *) ((Junction *)((Junction *)$$.left)->p1); /* MR7 */\r
1987 altAdd(CurAltStart); /* MR7 */\r
1988 };\r
1989 >>\r
1990 <<$node = (Node *) ((Junction *)$$.left)->p1;>>\r
1991\r
1992 )\r
1993\r
1994/* Error catching alternatives */\r
1995 | "\*" <<warn("don't you want a ')' with that '*'?"); CannotContinue=TRUE;>>\r
1996 | "\+" <<warn("don't you want a ')' with that '+'?"); CannotContinue=TRUE;>>\r
1997 | "\>" <<warn("'>' can only appear after a nonterminal"); CannotContinue=TRUE;>>\r
1998 | PassAction <<warn("[...] out of context 'rule > [...]'");\r
1999 CannotContinue=TRUE;>>\r
2000 ;\r
2001 <<CannotContinue=TRUE;>>\r
2002\r
2003/* rule default_exception_handler */\r
2004\r
2005default_exception_handler\r
2006 : exception_group > [DefaultExGroup]\r
2007 ;\r
2008\r
2009/* rule exception_group */\r
2010\r
2011exception_group > [ExceptionGroup *eg]\r
2012 : <<ExceptionHandler *h; LabelEntry *label=NULL; /* MR6 */\r
2013 FoundException = 1; FoundExceptionGroup = 1;>> /* MR6 */\r
2014\r
2015 "exception" <<$eg = (ExceptionGroup *)calloc(1, sizeof(ExceptionGroup));>>\r
2016 { <<char *p;>>\r
2017 PassAction /* did they attach a label? */\r
2018 <<\r
2019 p = LATEXT(1)+1;\r
2020 p[strlen(p)-1] = '\0'; /* kill trailing space */\r
2021 label = (LabelEntry *) hash_get(Elabel, LATEXT(1)+1);\r
2022 if ( label==NULL )\r
2023 {\r
2024 err(eMsg1("unknown label in exception handler: '%s'", LATEXT(1)+1));\r
2025 }\r
2026 >>\r
2027 }\r
2028 ( exception_handler > [h]\r
2029 <<list_add(&($eg->handlers), (void *)h);>>\r
2030 )*\r
2031 { "default" ":" Action\r
2032 <<{\r
2033 ExceptionHandler *eh = (ExceptionHandler *)\r
2034 calloc(1, sizeof(ExceptionHandler));\r
2035 char *a = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));\r
2036 require(eh!=NULL, "exception: cannot allocate handler");\r
2037 require(a!=NULL, "exception: cannot allocate action");\r
2038 strcpy(a, LATEXT(1));\r
2039 eh->action = a;\r
2040 eh->signalname = (char *) calloc(strlen("default")+1, sizeof(char));\r
2041 require(eh->signalname!=NULL, "exception: cannot allocate sig name");\r
2042 strcpy(eh->signalname, "default");\r
2043 list_add(&($eg->handlers), (void *)eh);\r
2044 }>>\r
2045 }\r
2046\r
2047 <<\r
2048 if ( label!=NULL ) {\r
2049 /* Record ex group in sym tab for this label */\r
2050 if ( label->ex_group!=NULL ) {\r
2051 err(eMsg1("duplicate exception handler for label '%s'",label->str));\r
2052 } else {\r
2053 label->ex_group = $eg;\r
2054 /* Label the exception group itself */\r
2055 $eg->label = label->str;\r
2056 /* Make the labelled element pt to the exception also */\r
2057/* MR6 */ if (label->elem == NULL) {\r
2058/* MR6 */ err(eMsg1("reference in exception handler to undefined label '%s'",label->str));\r
2059/* MR6 */ } else {\r
2060 switch ( label->elem->ntype ) {\r
2061 case nRuleRef :\r
2062 {\r
2063 RuleRefNode *r = (RuleRefNode *)label->elem;\r
2064 r->ex_group = $eg;\r
2065 break;\r
2066 }\r
2067 case nToken :\r
2068 {\r
2069 TokNode *t = (TokNode *)label->elem;\r
2070 t->ex_group = $eg;\r
2071 break;\r
2072 }\r
2073 } /* end switch */\r
2074/* MR6 */ }; /* end test on label->elem */\r
2075 } /* end test on label->ex_group */\r
2076\r
2077 } /* end test on exception label */\r
2078\r
2079/* MR7 */\r
2080/* MR7 */ if (BlkLevel == 1 && label == NULL) {\r
2081/* MR7 */ $eg->forRule=1;\r
2082/* MR7 */ } else if (label == NULL) {\r
2083/* MR7 */ $eg->altID = makeAltID(CurBlockID_array[BlkLevel], CurAltNum_array[BlkLevel]);\r
2084/* MR7 */ egAdd($eg);\r
2085/* MR7 */ } else {\r
2086/* MR7 */ $eg->labelEntry=label;\r
2087/* MR7 */ };\r
2088/* MR7 */\r
2089/* MR7 */ /* You may want to remove this exc from the rule list */\r
2090/* MR7 */ /* and handle at the labeled element site. */\r
2091/* MR7 */\r
2092/* MR7 */ if (label != NULL) {\r
2093/* MR7 */ $eg = NULL;\r
2094/* MR7 */ };\r
2095\r
2096 >>\r
2097 ;\r
2098 <<CannotContinue=TRUE;>>\r
2099\r
2100/* rule exception_handler */\r
2101\r
2102exception_handler > [ExceptionHandler *eh]\r
2103 : <<;>> /* MR9 Removed unreferenced variable "a" */\r
2104 "catch"\r
2105 <<\r
2106 $eh = (ExceptionHandler *)calloc(1, sizeof(ExceptionHandler));\r
2107 require($eh!=NULL, "exception: cannot allocate handler");\r
2108 >>\r
2109 ( NonTerminal\r
2110 <<\r
2111 $eh->signalname = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));\r
2112 require($eh->signalname!=NULL, "exception: cannot allocate sig name");\r
2113 strcpy($eh->signalname, LATEXT(1));\r
2114 >>\r
2115 | TokenTerm\r
2116 <<\r
2117 $eh->signalname = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));\r
2118 require($eh->signalname!=NULL, "exception: cannot allocate sig name");\r
2119 strcpy($eh->signalname, LATEXT(1));\r
2120 >>\r
2121 )\r
2122 ":"\r
2123 { <<$eh->action = NULL;>>\r
2124 Action\r
2125 <<\r
2126 $eh->action = (char *) calloc(strlen(LATEXT(1))+1, sizeof(char));\r
2127 require($eh->action!=NULL, "exception: cannot allocate action");\r
2128 strcpy($eh->action, LATEXT(1));\r
2129 >>\r
2130 }\r
2131 ;\r
2132 <<CannotContinue=TRUE;>>\r
2133\r
2134#token NonTerminal "[a-z] [A-Za-z0-9_]*"\r
2135 <<\r
2136 while ( zzchar==' ' || zzchar=='\t' ) {\r
2137 zzadvance();\r
2138 }\r
2139 if ( zzchar == ':' && inAlt ) NLA = LABEL;\r
2140 >>\r
2141#token TokenTerm "[A-Z] [A-Za-z0-9_]*"\r
2142 <<\r
2143 while ( zzchar==' ' || zzchar=='\t' ) {\r
2144 zzadvance();\r
2145 }\r
2146 if ( zzchar == ':' && inAlt ) NLA = LABEL;\r
2147 >>\r
2148#token "{\\}#[A-Za-z0-9_]*" <<warn(eMsg1("unknown meta-op: %s",LATEXT(1))); zzskip(); >>\r
2149\r
2150#lexclass PARSE_ENUM_FILE\r
2151\r
2152#token "[\t\ ]+" << zzskip(); >> /* Ignore White */\r
2153#token "\n|\r|\r\n" << zzline++; zzskip(); >> /* Track Line # */\r
2154#token "//" << zzmode(TOK_DEF_CPP_COMMENTS); zzmore(); >>\r
2155#token "/\*" << zzmode(TOK_DEF_COMMENTS); zzskip(); >>\r
2156#token "#ifdef" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >>\r
2157#token "#if" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >>\r
2158#token "#ifndef" << ; >>\r
2159#token "#else" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >>\r
2160#token "#endif" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >>\r
2161#token "#undef" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >>\r
2162#token "#import" << zzmode(TOK_DEF_CPP_COMMENTS); zzskip(); >>\r
2163#token "@" << ; >>\r
2164\r
2165/* rule enum_file */\r
2166\r
2167enum_file[char *fname]\r
2168 : { "#ifndef" ID\r
2169 { "#define" ID /* ignore if it smells like a gate */\r
2170 /* First #define after the first #ifndef (if any) is ignored */\r
2171 }\r
2172 }\r
2173 ( ( enum_def[$fname] )+\r
2174 | defines[$fname]\r
2175 )\r
2176 |\r
2177 ;\r
2178\r
2179/* rule defines */\r
2180\r
2181defines[char *fname]\r
2182 : <<int v; int maxt=(-1); char *t;>> /* MR3 */\r
2183 (\r
2184 "#define" ID\r
2185 <<t = mystrdup(LATEXT(1));>>\r
2186 INT\r
2187 <<\r
2188 v = atoi(LATEXT(1));\r
2189/* fprintf(stderr, "#token %s=%d\n", t, v);*/\r
2190\r
2191 /* MR2 Andreas Magnusson (Andreas.Magnusson@mailbox.swipnet.se) */\r
2192 /* MR2 Fix to bug introduced by 1.33MR1 for #tokdefs */\r
2193 /* MR2 Don't let #tokdefs be confused by */\r
2194 /* MR2 DLGminToken and DLGmaxToken */\r
2195\r
2196 if ( ! isDLGmaxToken(t)) { /* MR2 */\r
2197 TokenNum = v;\r
2198 if ( v>maxt ) maxt=v;\r
2199 if ( Tnum( t ) == 0 ) {\r
2200 addForcedTname( t, v );\r
2201 } else {\r
2202 warnFL(eMsg1("redefinition of token %s; ignored",t),$fname,zzline);\r
2203 };\r
2204 };\r
2205 >>\r
2206 )+\r
2207 <<TokenNum = maxt + 1;>>\r
2208 ;\r
2209\r
2210/* rule enum_def */\r
2211\r
2212enum_def[char *fname]\r
2213 : <<int v= 0; int maxt=(-1); char *t;>> /* MR3 */\r
2214 "enum" ID\r
2215 "\{"\r
2216 ID\r
2217 <<t = mystrdup(LATEXT(1));>>\r
2218 ( "=" INT <<v=atoi(LATEXT(1));>>\r
2219 | <<v++;>>\r
2220 )\r
2221 <<\r
2222/* fprintf(stderr, "#token %s=%d\n", t, v);*/\r
2223 TokenNum = v;\r
2224 if ( v>maxt ) maxt=v; /* MR3 */\r
2225 if ( Tnum( t ) == 0 ) addForcedTname( t, v );\r
2226 else {\r
2227 warnFL(eMsg1("redefinition of token %s; ignored",t),$fname,zzline);\r
2228 }\r
2229 >>\r
2230 ( ","\r
2231\r
2232 /* MR2 Andreas Magnusson (Andreas.Magnusson@mailbox.swipnet.se) */\r
2233 /* MR2 Fix to bug introduced by 1.33MR1 for #tokdefs */\r
2234 /* MR2 Don't let #tokdefs be confused by */\r
2235 /* MR2 DLGminToken and DLGmaxToken */\r
2236\r
2237 {\r
2238 <<isDLGmaxToken(LATEXT(1))>>? ID { "=" INT } /* MR2 */\r
2239 | ID /* MR2 */\r
2240 <<t = mystrdup(LATEXT(1));>>\r
2241 ( "=" INT <<v=atoi(LATEXT(1));>>\r
2242 | <<v++;>>\r
2243 )\r
2244 <<\r
2245/* fprintf(stderr, "#token %s=%d\n", t, v);*/\r
2246 TokenNum = v;\r
2247 if ( v>maxt ) maxt=v; /* MR3 */\r
2248 if ( Tnum( t ) == 0 ) addForcedTname( t, v );\r
2249 else {\r
2250 warnFL(eMsg1("redefinition of token %s; ignored",t),$fname,zzline);\r
2251 }\r
2252 >>\r
2253 }\r
2254 )*\r
2255 "\}"\r
2256 ";"\r
2257 <<TokenNum = maxt + 1;>> /* MR3 */\r
2258 ;\r
2259\r
2260#token INT "[0-9]+"\r
2261#token ID "[a-zA-Z_][_a-zA-Z0-9]*"\r
2262\r
2263#lexclass START\r
2264\r
2265/* MR14 Arpad Beszedes 26-May-98\r
2266 Add support for #line directives when antlr source is pre-processed\r
2267*/\r
2268\r
2269#lexaction\r
2270<<\r
2271\r
2272static char *\r
2273#ifdef __USE_PROTOS\r
2274getFileNameFromTheLineInfo(char *toStr, char *fromStr)\r
2275#else\r
2276getFileNameFromTheLineInfo(toStr, fromStr)\r
2277char *toStr, *fromStr;\r
2278#endif\r
2279{\r
2280 int i, j, k;\r
2281\r
2282 if (!fromStr || !toStr) return toStr;\r
2283\r
2284 /* find the first " */\r
2285\r
2286 for (i=0;\r
2287 (i<MaxFileName) &&\r
2288 (fromStr[i] != '\n') &&\r
2289 (fromStr[i] != '\r') &&\r
2290 (fromStr[i] != '\"');\r
2291 i++) /* nothing */ ;\r
2292\r
2293 if ( (i == MaxFileName) ||\r
2294 (fromStr[i] == '\n') ||\r
2295 (fromStr[i] == '\r') ) {\r
2296 return toStr;\r
2297 }\r
2298\r
2299 /* find the second " */\r
2300\r
2301 for (j=i+1;\r
2302 (j<MaxFileName) &&\r
2303 (fromStr[j] != '\n') &&\r
2304 (fromStr[j] != '\r') &&\r
2305 (fromStr[j] != '\"');\r
2306 j++) /* nothing */ ;\r
2307\r
2308 if ((j == MaxFileName) ||\r
2309 (fromStr[j] == '\n') ||\r
2310 (fromStr[j] == '\r') ) {\r
2311 return toStr;\r
2312 }\r
2313\r
2314 /* go back until the last / or \ */\r
2315\r
2316 for (k=j-1;\r
2317 (fromStr[k] != '\"') &&\r
2318 (fromStr[k] != '/') &&\r
2319 (fromStr[k] != '\\');\r
2320 k--) /* nothing */ ;\r
2321\r
2322 /* copy the string after " / or \ into toStr */\r
2323\r
2324 for (i=k+1; fromStr[i] != '\"'; i++) {\r
2325 toStr[i-k-1] = fromStr[i];\r
2326 }\r
2327\r
2328 toStr[i-k-1] = '\0';\r
2329\r
2330 return toStr;\r
2331}\r
2332\r
2333/* MR14 end of a block to support #line in antlr source code */\r
2334\r
2335>>\r
2336\r
2337<<\r
2338\r
2339/* MR2 Andreas Magnusson (Andreas.Magnusson@mailbox.swipnet.se) */\r
2340/* MR2 Fix to bug introduced by 1.33MR1 for #tokdefs */\r
2341/* MR2 Don't let #tokdefs be confused by */\r
2342/* MR2 DLGminToken and DLGmaxToken */\r
2343\r
2344/* semantic check on DLGminToken and DLGmaxmaxToken in #tokdefs */\r
2345\r
2346#ifdef __USE_PROTOS\r
2347static int isDLGmaxToken(char *Token)\r
2348#else\r
2349static int isDLGmaxToken(Token)\r
2350 char * Token;\r
2351#endif\r
2352{\r
2353 static char checkStr1[] = "DLGmaxToken";\r
2354 static char checkStr2[] = "DLGminToken";\r
2355\r
2356 if (strcmp(Token, checkStr1) == 0)\r
2357 return 1;\r
2358 else if (strcmp(Token, checkStr2) == 0)\r
2359 return 1;\r
2360 else\r
2361 return 0;\r
2362}\r
2363\r
2364/* semantics of #token */\r
2365static void\r
2366#ifdef __USE_PROTOS\r
2367chkToken(char *t, char *e, char *a, int tnum)\r
2368#else\r
2369chkToken(t,e,a,tnum)\r
2370char *t, *e, *a;\r
2371int tnum;\r
2372#endif\r
2373{\r
2374 TermEntry *p;\r
2375\r
2376 /* check to see that they don't try to redefine a token as a token class */\r
2377 if ( t!=NULL ) {\r
2378 p = (TermEntry *) hash_get(Tname, t);\r
2379 if ( p!=NULL && p->classname ) {\r
2380 err(eMsg1("redefinition of #tokclass '%s' to #token not allowed; ignored",t));\r
2381 if ( a!=NULL ) free((char *)a);\r
2382 return;\r
2383 }\r
2384 }\r
2385\r
2386 if ( t==NULL && e==NULL ) { /* none found */\r
2387 err("#token requires at least token name or rexpr");\r
2388 }\r
2389 else if ( t!=NULL && e!=NULL ) { /* both found */\r
2390 if ( UserDefdTokens ) { /* if #tokdefs, must not define new */\r
2391 p = (TermEntry *) hash_get(Tname, t);\r
2392 if ( p == NULL) {\r
2393err(eMsg1("new token definition '%s' not allowed - only #token with name already defined by #tokdefs file allowed",t));\r
2394 return;\r
2395 };\r
2396 }\r
2397 Tklink(t, e);\r
2398 if ( a!=NULL ) {\r
2399 if ( hasAction(e) ) {\r
2400 err(eMsg1("redefinition of action for %s; ignored",e));\r
2401 }\r
2402 else setHasAction(e, a);\r
2403 }\r
2404 }\r
2405 else if ( t!=NULL ) { /* only one found */\r
2406 if ( UserDefdTokens ) {\r
2407 p = (TermEntry *) hash_get(Tname, t);\r
2408 if (p == NULL) {\r
2409err(eMsg1("new token definition '%s' not allowed - only #token with name already defined by #tokdefs file allowed",t));\r
2410 };\r
2411 return;\r
2412 }\r
2413 if ( Tnum( t ) == 0 ) addTname( t );\r
2414 else {\r
2415 err(eMsg1("redefinition of token %s; ignored",t));\r
2416 }\r
2417 if ( a!=NULL ) {\r
2418 err(eMsg1("action cannot be attached to a token name (%s); ignored",t));\r
2419 free((char *)a);\r
2420 }\r
2421 }\r
2422 else if ( e!=NULL ) {\r
2423 if ( Tnum( e ) == 0 ) addTexpr( e );\r
2424 else {\r
2425 if ( hasAction(e) ) {\r
2426 err(eMsg1("redefinition of action for expr %s; ignored",e));\r
2427 }\r
2428 else if ( a==NULL ) {\r
2429 err(eMsg1("redefinition of expr %s; ignored",e));\r
2430 }\r
2431 }\r
2432 if ( a!=NULL ) setHasAction(e, a);\r
2433 }\r
2434\r
2435 /* if a token type number was specified, then add the token ID and 'tnum'\r
2436 * pair to the ForcedTokens list. (only applies if an id was given)\r
2437 */\r
2438 if ( t!=NULL && tnum>0 )\r
2439 {\r
2440 if ( set_el(tnum, reserved_positions) )\r
2441 {\r
2442 err(eMsgd("a token has already been forced to token number %d; ignored", tnum));\r
2443 }\r
2444 else\r
2445 {\r
2446 list_add(&ForcedTokens, newForcedToken(t,tnum));\r
2447 set_orel(tnum, &reserved_positions);\r
2448 }\r
2449 }\r
2450}\r
2451>>\r
2452\r
2453<<\r
2454static int\r
2455#ifdef __USE_PROTOS\r
2456match_token(char *s, char **nxt)\r
2457#else\r
2458match_token(s,nxt)\r
2459char *s;\r
2460char **nxt;\r
2461#endif\r
2462{\r
2463 if ( !(*s>='A' && *s<='Z') ) return 0;\r
2464 s++;\r
2465 while ( (*s>='a' && *s<='z') ||\r
2466 (*s>='A' && *s<='Z') ||\r
2467 (*s>='0' && *s<='9') ||\r
2468 *s=='_' )\r
2469 {\r
2470 s++;\r
2471 }\r
2472 if ( *s!=' ' && *s!='}' ) return 0;\r
2473 *nxt = s;\r
2474 return 1;\r
2475}\r
2476\r
2477static int\r
2478#ifdef __USE_PROTOS\r
2479match_rexpr(char *s, char **nxt)\r
2480#else\r
2481match_rexpr(s,nxt)\r
2482char *s;\r
2483char **nxt;\r
2484#endif\r
2485{\r
2486 if ( *s!='"' ) return 0;\r
2487 s++;\r
2488 while ( *s!='"' )\r
2489 {\r
2490 if ( *s=='\n' || *s=='\r' ) /* MR13 */\r
2491 warn("eoln found in regular expression");\r
2492 if ( *s=='\\' ) s++;\r
2493 s++;\r
2494 }\r
2495 *nxt = s+1;\r
2496 return 1;\r
2497}\r
2498\r
2499/*\r
2500 * Walk a string "{ A .. Z }" where A..Z is a space separated list\r
2501 * of token references (either labels or reg exprs). Return a\r
2502 * string "inlineX_set" for some unique integer X. Basically,\r
2503 * we pretend as if we had seen "#tokclass inlineX { A .. Z }"\r
2504 * on the input stream outside of an action.\r
2505 */\r
2506char *\r
2507#ifdef __USE_PROTOS\r
2508inline_set(char *s)\r
2509#else\r
2510inline_set(s)\r
2511char *s;\r
2512#endif\r
2513{\r
2514 char *nxt;\r
2515 fprintf(stderr, "found consumeUntil( {...} )\n");\r
2516 while ( *s==' ' || *s=='\t' || *s=='\n' || *s=='\r' ) {s++;}\r
2517 if ( *s!='{' )\r
2518 {\r
2519 err("malformed consumeUntil( {...} ); missing '{'");\r
2520 return "bad_set";\r
2521 }\r
2522 s++;\r
2523 while ( *s==' ' || *s=='\t' || *s=='\n' || *s=='\r' ) {s++;}\r
2524 while ( *s!='}' )\r
2525 {\r
2526 if ( match_token(s,&nxt) ) fprintf(stderr, "found token %s\n", s);\r
2527 else if ( match_rexpr(s,&nxt) ) fprintf(stderr, "found rexpr %s\n", s);\r
2528 else {\r
2529 err("invalid element in consumeUntil( {...} )");\r
2530 return "bad_set";\r
2531 }\r
2532 s = nxt;\r
2533 while ( *s==' ' || *s=='\t' || *s=='\n' || *s=='\r' ) {s++;}\r
2534 }\r
2535 return "inlineX_set";\r
2536}\r
2537>>\r
2538\r
2539<<\r
2540/* ANTLR-specific syntax error message generator\r
2541 * (define USER_ZZSYN when compiling so don't get 2 definitions)\r
2542 */\r
2543void\r
2544#ifdef __USE_PROTOS\r
2545zzsyn(char *text, int tok, char *egroup, SetWordType *eset, int etok,\r
2546int k, char *bad_text)\r
2547#else\r
2548zzsyn(text, tok, egroup, eset, etok, k, bad_text)\r
2549char *text, *egroup, *bad_text;\r
2550int tok;\r
2551int etok;\r
2552int k;\r
2553SetWordType *eset;\r
2554#endif\r
2555{\r
2556 fprintf(stderr, ErrHdr, FileStr[CurFile]!=NULL?FileStr[CurFile]:"stdin", zzline);\r
2557 fprintf(stderr, " syntax error at \"%s\"", (tok==zzEOF_TOKEN)?"EOF":text);\r
2558 if ( !etok && !eset ) {fprintf(stderr, "\n"); return;}\r
2559 if ( k==1 ) fprintf(stderr, " missing");\r
2560 else\r
2561 {\r
2562 fprintf(stderr, "; \"%s\" not", bad_text);\r
2563 if ( zzset_deg(eset)>1 ) fprintf(stderr, " in");\r
2564 }\r
2565 if ( zzset_deg(eset)>0 ) zzedecode(eset);\r
2566 else fprintf(stderr, " %s", zztokens[etok]);\r
2567 if ( strlen(egroup) > (size_t)0 ) fprintf(stderr, " in %s", egroup);\r
2568 fprintf(stderr, "\n");\r
2569}\r
2570>>\r
2571\r
2572#lexaction <<\r
2573#ifdef __USE_PROTOS\r
2574void mark_label_used_in_sem_pred(LabelEntry *le) /* MR10 */\r
2575#else\r
2576void mark_label_used_in_sem_pred(le) /* MR10 */\r
2577 LabelEntry *le;\r
2578#endif\r
2579{\r
2580 TokNode *tn;\r
2581 require (le->elem->ntype == nToken,"mark_label_used... ntype != nToken");\r
2582 tn=(TokNode *)le->elem;\r
2583 require (tn->label != 0,"mark_label_used... TokNode has no label");\r
2584 tn->label_used_in_semantic_pred=1;\r
2585}\r
2586>>\r