Commit | Line | Data |
---|---|---|
866e5b51 FC |
1 | parser grammar CTFParser; |
2 | ||
3 | options { | |
4 | language = Java; | |
5 | output = AST; | |
6 | ASTLabelType = CommonTree; | |
7 | tokenVocab = CTFLexer; | |
8 | } | |
9 | ||
10 | tokens { | |
11 | ROOT; | |
12 | ||
13 | EVENT; | |
14 | STREAM; | |
15 | TRACE; | |
16 | ENV; | |
17 | CLOCK; | |
4c9d2941 | 18 | CALLSITE; |
866e5b51 FC |
19 | |
20 | DECLARATION; | |
21 | SV_DECLARATION; | |
22 | TYPE_SPECIFIER_LIST; | |
23 | TYPE_DECLARATOR_LIST; | |
24 | TYPE_DECLARATOR; | |
25 | ||
26 | STRUCT; | |
27 | STRUCT_NAME; | |
28 | STRUCT_BODY; | |
29 | ALIGN; | |
30 | ||
31 | CTF_EXPRESSION_TYPE; | |
32 | CTF_EXPRESSION_VAL; | |
33 | CTF_LEFT; | |
34 | CTF_RIGHT; | |
35 | ||
36 | UNARY_EXPRESSION_STRING; | |
37 | UNARY_EXPRESSION_STRING_QUOTES; | |
38 | UNARY_EXPRESSION_DEC; | |
39 | UNARY_EXPRESSION_HEX; | |
40 | UNARY_EXPRESSION_OCT; | |
41 | LENGTH; | |
42 | ||
43 | TYPEDEF; | |
44 | ||
45 | TYPEALIAS; | |
46 | TYPEALIAS_TARGET; | |
47 | TYPEALIAS_ALIAS; | |
48 | ||
49 | INTEGER; | |
50 | STRING; | |
51 | FLOATING_POINT; | |
52 | ||
53 | ENUM; | |
54 | ENUM_CONTAINER_TYPE; | |
55 | ENUM_ENUMERATOR; | |
56 | ENUM_NAME; | |
57 | ENUM_VALUE; | |
58 | ENUM_VALUE_RANGE; | |
59 | ENUM_BODY; | |
60 | ||
61 | VARIANT; | |
62 | VARIANT_NAME; | |
63 | VARIANT_TAG; | |
64 | VARIANT_BODY; | |
65 | ||
66 | DECLARATOR; | |
67 | LENGTH; | |
68 | } | |
69 | ||
70 | /* | |
71 | * Scope for the tracking of types. | |
72 | * For now we just track the names (it's a simple Set), but | |
73 | * later we will have to track the info about the target type. | |
74 | */ | |
75 | scope Symbols { | |
76 | Set<String> types; | |
77 | } | |
78 | ||
79 | @header { | |
80 | package org.eclipse.linuxtools.ctf.parser; | |
81 | import java.util.Set; | |
82 | import java.util.HashSet; | |
83 | } | |
84 | ||
85 | @members { | |
86 | public CTFParser(TokenStream input, boolean verbose) { | |
87 | this(input); | |
88 | this.verbose = verbose; | |
89 | } | |
90 | ||
91 | /* To disable automatic error recovery. When we have a mismatched token, simply throw an exception. */ | |
92 | @Override | |
93 | protected Object recoverFromMismatchedToken(IntStream input, int ttype, BitSet follow) throws RecognitionException | |
94 | { | |
95 | throw new MismatchedTokenException(ttype, input); | |
96 | } | |
97 | ||
98 | /** | |
99 | * Checks if a given name has been defined has a type. | |
100 | * From: http://www.antlr.org/grammar/1153358328744/C.g | |
101 | * | |
102 | * @param name The name to check. | |
103 | * @return True if is is a type, false otherwise. | |
104 | */ | |
105 | boolean isTypeName(String name) { | |
106 | for (int i = Symbols_stack.size() - 1; i >= 0; i--) { | |
107 | Symbols_scope scope = (Symbols_scope)Symbols_stack.get(i); | |
108 | if (scope.types.contains(name)) { | |
109 | return true; | |
110 | } | |
111 | } | |
112 | return false; | |
113 | } | |
114 | ||
115 | void addTypeName(String name) { | |
116 | $Symbols::types.add(name); | |
117 | if (verbose) { | |
118 | debug_print("New type: " + name); | |
119 | } | |
120 | } | |
121 | ||
122 | boolean _inTypedef = false; | |
123 | ||
124 | void typedefOn() { | |
125 | debug_print("typedefOn"); | |
126 | _inTypedef = true; | |
127 | } | |
128 | ||
129 | void typedefOff() { | |
130 | debug_print("typedefOff"); | |
131 | _inTypedef = false; | |
132 | } | |
133 | ||
134 | boolean inTypedef() { | |
135 | return _inTypedef; | |
136 | } | |
137 | ||
138 | boolean _inTypealiasAlias = false; | |
139 | ||
140 | void typealiasAliasOn() { | |
141 | debug_print("typealiasAliasOn"); | |
142 | _inTypealiasAlias = true; | |
143 | } | |
144 | ||
145 | void typealiasAliasOff() { | |
146 | debug_print("typealiasAliasOff"); | |
147 | _inTypealiasAlias = false; | |
148 | } | |
149 | ||
150 | boolean inTypealiasAlias() { | |
151 | return _inTypealiasAlias; | |
152 | } | |
153 | ||
154 | void print_tabs(int n) { | |
155 | for (int i = 0; i < n; i++) { | |
156 | System.out.print(" "); | |
157 | } | |
158 | } | |
159 | ||
160 | void enter(String name) { | |
161 | if (verbose) { | |
162 | if (state.backtracking == 0) { | |
163 | print_tabs(depth); | |
164 | debug_print("+ " + name); | |
165 | depth++; | |
166 | } | |
167 | } | |
168 | } | |
169 | ||
170 | void exit(String name) { | |
171 | if (verbose) { | |
172 | depth--; | |
173 | print_tabs(depth); | |
174 | debug_print("- " + name); | |
175 | } | |
176 | } | |
177 | ||
178 | void debug_print(String str) { | |
179 | if (verbose) { | |
180 | System.out.println(str); | |
181 | } | |
182 | } | |
183 | ||
184 | int depth = 0; | |
185 | ||
186 | /* Prints rule entry and exit while parsing */ | |
187 | boolean verbose = false; | |
188 | } | |
189 | ||
190 | /* To disable automatic error recovery. By default, the catch block of every rule simple rethrows the error. */ | |
191 | @rulecatch { | |
192 | catch (RecognitionException e) | |
193 | { | |
194 | throw e; | |
195 | } | |
196 | } | |
197 | ||
198 | /* The top-level rule. */ | |
199 | parse | |
200 | scope Symbols; | |
201 | @init { | |
202 | enter("parse"); | |
203 | debug_print("Scope push " + Symbols_stack.size()); | |
204 | $Symbols::types = new HashSet<String>(); | |
205 | } | |
206 | @after { | |
207 | debug_print("Scope pop " + Symbols_stack.size()); | |
208 | exit("parse"); | |
209 | ||
210 | debug_print("Final depth, should be 0: " + depth); | |
211 | } | |
212 | : | |
213 | declaration+ EOF -> ^(ROOT declaration+) | |
214 | ; | |
215 | ||
216 | numberLiteral | |
217 | @init { | |
218 | enter("numberLiteral"); | |
219 | } | |
220 | @after { | |
221 | debug_print($numberLiteral.text); | |
222 | exit("numberLiteral"); | |
223 | } | |
224 | : | |
225 | SIGN* (HEX_LITERAL -> ^(UNARY_EXPRESSION_HEX HEX_LITERAL SIGN*) | |
226 | | DECIMAL_LITERAL -> ^(UNARY_EXPRESSION_DEC DECIMAL_LITERAL SIGN*) | |
227 | | OCTAL_LITERAL -> ^(UNARY_EXPRESSION_OCT OCTAL_LITERAL SIGN*)) | |
228 | ; | |
229 | ||
230 | constant | |
231 | @init { | |
232 | enter("constant"); | |
233 | } | |
234 | @after { | |
235 | exit("constant"); | |
236 | } | |
237 | : | |
238 | numberLiteral | |
239 | | enumConstant | |
240 | | CHARACTER_LITERAL | |
241 | ; | |
242 | ||
243 | primaryExpression | |
244 | @init { | |
245 | enter("primaryExpression"); | |
246 | } | |
247 | @after { | |
248 | exit("primaryExpression"); | |
249 | } | |
250 | : | |
251 | (IDENTIFIER) => IDENTIFIER { debug_print("IDENTIFIER: " + $IDENTIFIER.text);} -> ^(UNARY_EXPRESSION_STRING IDENTIFIER) | |
252 | | (ctfKeyword) => ctfKeyword -> ^(UNARY_EXPRESSION_STRING ctfKeyword) | |
253 | | (STRING_LITERAL) => STRING_LITERAL { debug_print("STRING_LITERAL: " + $STRING_LITERAL.text);} -> ^(UNARY_EXPRESSION_STRING_QUOTES STRING_LITERAL) | |
254 | /*| (LPAREN unaryExpression RPAREN)*/ // Not supported yet | |
255 | | constant | |
256 | ; | |
257 | ||
258 | reference | |
259 | @init { | |
260 | enter("reference"); | |
261 | } | |
262 | @after { | |
263 | debug_print($reference.text); | |
264 | exit("reference"); | |
265 | } | |
266 | : | |
267 | (ref=DOT | ref=ARROW) IDENTIFIER -> ^($ref ^(UNARY_EXPRESSION_STRING IDENTIFIER)) | |
268 | ; | |
269 | ||
270 | postfixExpressionSuffix | |
271 | @init { | |
272 | enter("postfixExpressionSuffix"); | |
273 | } | |
274 | @after { | |
275 | exit("postfixExpressionSuffix"); | |
276 | } | |
277 | : | |
278 | (OPENBRAC unaryExpression CLOSEBRAC!) | |
279 | | reference | |
280 | ; | |
281 | ||
282 | postfixExpression | |
283 | @init { | |
284 | enter("postfixExpression"); | |
285 | } | |
286 | @after { | |
287 | exit("postfixExpression"); | |
288 | } | |
289 | : | |
290 | (primaryExpression) (postfixExpressionSuffix)*| | |
291 | ((ctfSpecifierHead) (postfixExpressionSuffix)+)// added for ctfV1.8 | |
292 | ; | |
293 | ||
294 | unaryExpression | |
295 | @init { | |
296 | enter("unaryExpression"); | |
297 | } | |
298 | @after { | |
299 | exit("unaryExpression"); | |
300 | } | |
301 | : | |
302 | /*((SIGN postfixExpression[true]) | |
303 | | postfixExpression[false])*/ | |
304 | postfixExpression | |
305 | ; | |
306 | ||
307 | enumConstant | |
308 | @init { | |
309 | enter("enumConstant"); | |
310 | } | |
311 | @after { | |
312 | debug_print($enumConstant.text); | |
313 | exit("enumConstant"); | |
314 | } | |
315 | : | |
316 | STRING_LITERAL -> ^(UNARY_EXPRESSION_STRING_QUOTES STRING_LITERAL) | |
317 | | IDENTIFIER -> ^(UNARY_EXPRESSION_STRING IDENTIFIER) | |
318 | | ctfKeyword -> ^(UNARY_EXPRESSION_STRING ctfKeyword) | |
319 | ; | |
320 | // 2.2 | |
321 | ||
322 | declaration | |
323 | @init { | |
324 | enter("declaration"); | |
325 | } | |
326 | @after { | |
327 | exit("declaration"); | |
328 | if (inTypedef()) | |
329 | typedefOff(); | |
330 | } | |
331 | : | |
332 | (declarationSpecifiers declaratorList? TERM) | |
333 | ||
334 | // When the declaration is completely parsed and was a typedef, we add the declarators to the symbol table. | |
335 | -> {inTypedef()}? ^(DECLARATION ^(TYPEDEF declaratorList declarationSpecifiers)) | |
336 | -> ^(DECLARATION declarationSpecifiers declaratorList?) | |
337 | ||
338 | | (ctfSpecifier TERM!) | |
339 | ; | |
340 | ||
341 | declarationSpecifiers | |
342 | @init { | |
343 | enter("declarationSpecifiers"); | |
344 | } | |
345 | @after { | |
346 | debug_print($declarationSpecifiers.text); | |
347 | exit("declarationSpecifiers"); | |
348 | } | |
349 | : | |
350 | ( | |
351 | // We don't want to keep the typedef keyword in the specifier list. | |
352 | // Instead, we keep track that we encountered a typedef in the declaration. | |
353 | storageClassSpecifier | |
354 | | typeQualifier | |
355 | | typeSpecifier | |
356 | )+ -> ^(TYPE_SPECIFIER_LIST typeQualifier* typeSpecifier*) | |
357 | ; | |
358 | ||
359 | declaratorList | |
360 | @init { | |
361 | enter("declaratorList"); | |
362 | } | |
363 | @after { | |
364 | exit("declaratorList"); | |
365 | } | |
366 | : | |
367 | declarator (SEPARATOR declarator)* -> ^(TYPE_DECLARATOR_LIST declarator+) | |
368 | ; | |
369 | ||
370 | abstractDeclaratorList | |
371 | @init { | |
372 | enter("abstractDeclaratorList"); | |
373 | } | |
374 | @after { | |
375 | exit("abstractDeclaratorList"); | |
376 | } | |
377 | : | |
378 | abstractDeclarator (SEPARATOR abstractDeclarator)* -> ^(TYPE_DECLARATOR_LIST abstractDeclarator+) | |
379 | ; | |
380 | ||
381 | storageClassSpecifier : | |
382 | TYPEDEFTOK {typedefOn();} | |
383 | ; | |
384 | ||
385 | typeSpecifier | |
386 | @init { | |
387 | enter("typeSpecifier"); | |
388 | } | |
389 | @after { | |
390 | debug_print($typeSpecifier.text); | |
391 | exit("typeSpecifier"); | |
392 | } | |
393 | : | |
394 | FLOATTOK | |
395 | | INTTOK | |
396 | | LONGTOK | |
397 | | SHORTTOK | |
398 | | SIGNEDTOK | |
399 | | UNSIGNEDTOK | |
400 | | CHARTOK | |
401 | | DOUBLETOK | |
402 | | VOIDTOK | |
403 | | BOOLTOK | |
404 | | COMPLEXTOK | |
405 | | IMAGINARYTOK | |
406 | | structSpecifier | |
407 | | variantSpecifier | |
408 | | enumSpecifier | |
409 | | ctfTypeSpecifier | |
410 | | {inTypealiasAlias() || isTypeName(input.LT(1).getText())}? => typedefName | |
411 | ; | |
412 | ||
413 | typeQualifier | |
414 | @init { | |
415 | enter("typeQualifier"); | |
416 | } | |
417 | @after { | |
418 | debug_print($typeQualifier.text); | |
419 | exit("typeQualifier"); | |
420 | } | |
421 | : | |
422 | CONSTTOK | |
423 | ; | |
424 | ||
425 | alignAttribute : | |
426 | ALIGNTOK LPAREN unaryExpression RPAREN -> ^(ALIGN unaryExpression) | |
427 | ; | |
428 | ||
429 | // you can have an empty struct but not an empty variant | |
430 | structBody | |
431 | scope Symbols; | |
432 | @init { | |
433 | enter("structBody"); | |
434 | debug_print("Scope push " + Symbols_stack.size()); | |
435 | $Symbols::types = new HashSet<String>(); | |
436 | } | |
437 | @after { | |
438 | debug_print("Scope pop " + Symbols_stack.size()); | |
439 | exit("structBody"); | |
440 | } | |
441 | : | |
442 | LCURL structOrVariantDeclarationList? RCURL -> ^(STRUCT_BODY structOrVariantDeclarationList?) | |
443 | ; | |
444 | ||
445 | ||
446 | ||
447 | structSpecifier | |
448 | @init { | |
449 | enter("structSpecifier"); | |
450 | } | |
451 | @after { | |
452 | exit("structSpecifier"); | |
453 | } | |
454 | : | |
455 | STRUCTTOK | |
456 | ( | |
457 | // We have an IDENTIFIER after 'struct' | |
458 | ( | |
459 | structName | |
460 | ( | |
461 | alignAttribute | |
462 | | | |
463 | ( | |
464 | structBody | |
465 | ( /* structBody can return an empty tree, so we need those ? */ | |
466 | alignAttribute | |
467 | | | |
468 | /* empty */ | |
469 | ) | |
470 | ) | |
471 | | | |
472 | /* empty */ | |
473 | ) | |
474 | ) | |
475 | | | |
476 | // We have a body after 'struct' | |
477 | ( | |
478 | structBody | |
479 | ( | |
480 | alignAttribute | |
481 | | | |
482 | /* empty */ | |
483 | ) | |
484 | ) | |
485 | ) -> ^(STRUCT structName? structBody? alignAttribute?) | |
486 | ; | |
487 | ||
488 | structName | |
489 | @init { | |
490 | enter("structName"); | |
491 | } | |
492 | @after { | |
493 | debug_print($structName.text); | |
494 | exit("structName"); | |
495 | } | |
496 | : | |
497 | IDENTIFIER -> ^(STRUCT_NAME IDENTIFIER) | |
498 | ; | |
499 | ||
500 | structOrVariantDeclarationList | |
501 | @init { | |
502 | enter("structOrVariantDeclarationList"); | |
503 | } | |
504 | @after { | |
505 | exit("structOrVariantDeclarationList"); | |
506 | } | |
507 | : | |
508 | structOrVariantDeclaration+ | |
509 | ; | |
510 | ||
511 | structOrVariantDeclaration | |
512 | @init { | |
513 | enter("structOrVariantDeclaration"); | |
514 | } | |
515 | @after { | |
516 | exit("structOrVariantDeclaration"); | |
517 | } | |
518 | : | |
519 | ( | |
520 | ( | |
521 | declarationSpecifiers | |
522 | ( | |
523 | /* If we met a "typedef" */ | |
524 | {inTypedef()}? => declaratorList {typedefOff();} | |
525 | -> ^(TYPEDEF declaratorList declarationSpecifiers) | |
526 | | structOrVariantDeclaratorList | |
527 | -> ^(SV_DECLARATION declarationSpecifiers structOrVariantDeclaratorList) | |
528 | ) | |
529 | ) | |
530 | | | |
531 | // Lines 3 and 4 | |
532 | typealiasDecl -> typealiasDecl | |
533 | ) | |
534 | TERM | |
535 | ; | |
536 | ||
537 | specifierQualifierList | |
538 | @init { | |
539 | enter("specifierQualifierList"); | |
540 | } | |
541 | @after { | |
542 | exit("specifierQualifierList"); | |
543 | } | |
544 | : | |
545 | (typeQualifier | typeSpecifier)+ -> ^(TYPE_SPECIFIER_LIST typeQualifier* typeSpecifier*) | |
546 | ; | |
547 | ||
548 | structOrVariantDeclaratorList | |
549 | @init { | |
550 | enter("structOrVariantDeclaratorList"); | |
551 | } | |
552 | @after { | |
553 | exit("structOrVariantDeclaratorList"); | |
554 | } | |
555 | : | |
556 | structOrVariantDeclarator (SEPARATOR structOrVariantDeclarator)* -> ^(TYPE_DECLARATOR_LIST structOrVariantDeclarator+) | |
557 | ; | |
558 | ||
559 | structOrVariantDeclarator | |
560 | @init { | |
561 | enter("structOrVariantDeclarator"); | |
562 | } | |
563 | @after { | |
564 | exit("structOrVariantDeclarator"); | |
565 | } | |
566 | : | |
567 | /* Bitfields not supported yet */ | |
568 | (declarator (COLON numberLiteral)?) -> declarator | |
569 | /*| (COLON numberLiteral)*/ | |
570 | ; | |
571 | ||
572 | variantSpecifier | |
573 | @init { | |
574 | enter("variantSpecifier"); | |
575 | } | |
576 | @after { | |
577 | exit("variantSpecifier"); | |
578 | } | |
579 | : | |
580 | VARIANTTOK | |
581 | ( | |
582 | ( | |
583 | variantName | |
584 | ( | |
585 | ( | |
586 | variantTag | |
587 | ( | |
588 | variantBody | |
589 | | | |
590 | /* empty */ | |
591 | ) | |
592 | ) | |
593 | | | |
594 | variantBody | |
595 | ) | |
596 | ) | |
597 | | | |
598 | (variantTag variantBody) | |
599 | | | |
600 | variantBody | |
601 | ) -> ^(VARIANT variantName? variantTag? variantBody?) | |
602 | ; | |
603 | ||
604 | variantName | |
605 | @init { | |
606 | enter("variantName"); | |
607 | } | |
608 | @after { | |
609 | debug_print($variantName.text); | |
610 | exit("variantName"); | |
611 | } | |
612 | : | |
613 | IDENTIFIER -> ^(VARIANT_NAME IDENTIFIER) | |
614 | ; | |
615 | ||
616 | variantBody | |
617 | scope Symbols; | |
618 | @init { | |
619 | enter("variantBody"); | |
620 | debug_print("Scope push " + Symbols_stack.size()); | |
621 | $Symbols::types = new HashSet<String>(); | |
622 | } | |
623 | @after { | |
624 | debug_print("Scope pop " + Symbols_stack.size()); | |
625 | exit("variantBody"); | |
626 | } | |
627 | : | |
628 | LCURL structOrVariantDeclarationList RCURL -> ^(VARIANT_BODY structOrVariantDeclarationList) | |
629 | ; | |
630 | ||
631 | variantTag | |
632 | @init { | |
633 | enter("variantTag"); | |
634 | } | |
635 | @after { | |
636 | debug_print($variantTag.text); | |
637 | exit("variantTag"); | |
638 | } | |
639 | : | |
640 | LT IDENTIFIER GT -> ^(VARIANT_TAG IDENTIFIER) | |
641 | ; | |
642 | ||
643 | enumSpecifier | |
644 | @init { | |
645 | enter("enumSpecifier"); | |
646 | } | |
647 | @after { | |
648 | exit("enumSpecifier"); | |
649 | } | |
650 | : | |
651 | ENUMTOK | |
652 | ( | |
653 | // Lines 1 to 5, when we have "ENUMTOK IDENTIFIER". | |
654 | ( | |
655 | enumName | |
656 | ( | |
657 | enumContainerType enumBody | |
658 | | | |
659 | enumBody | |
660 | | | |
661 | // no enumDeclarator or enumBodym | |
662 | ) | |
663 | ) | |
664 | | | |
665 | // Lines 1, 2, 4, 5, when we have no IDENTIFIER. | |
666 | ( | |
667 | enumContainerType enumBody | |
668 | | | |
669 | enumBody | |
670 | ) | |
671 | ) -> ^(ENUM enumName? enumContainerType? enumBody?) | |
672 | ; | |
673 | ||
674 | enumName | |
675 | @init { | |
676 | enter("enumName"); | |
677 | } | |
678 | @after { | |
679 | debug_print($enumName.text); | |
680 | exit("enumName"); | |
681 | } | |
682 | : | |
683 | IDENTIFIER -> ^(ENUM_NAME IDENTIFIER) | |
684 | ; | |
685 | ||
686 | enumBody | |
687 | @init { | |
688 | enter("enumBody"); | |
689 | } | |
690 | @after { | |
691 | exit("enumBody"); | |
692 | } | |
693 | : | |
694 | LCURL enumeratorList (SEPARATOR RCURL | RCURL) -> ^(ENUM_BODY enumeratorList) | |
695 | ; | |
696 | ||
697 | enumContainerType | |
698 | @init { | |
699 | enter("enumContainerType"); | |
700 | } | |
701 | @after { | |
702 | exit("enumContainerType"); | |
703 | } | |
704 | : | |
705 | COLON declarationSpecifiers -> ^(ENUM_CONTAINER_TYPE declarationSpecifiers) | |
706 | ; | |
707 | ||
708 | enumeratorList | |
709 | @init { | |
710 | enter("enumeratorList"); | |
711 | } | |
712 | @after { | |
713 | exit("enumeratorList"); | |
714 | } | |
715 | : | |
716 | enumerator (SEPARATOR enumerator)* -> (^(ENUM_ENUMERATOR enumerator))+ | |
717 | ; | |
718 | ||
719 | enumerator | |
720 | @init { | |
721 | enter("enumerator"); | |
722 | } | |
723 | @after { | |
724 | exit("enumerator"); | |
725 | } | |
726 | : | |
727 | enumConstant enumeratorValue? | |
728 | ; | |
729 | ||
730 | enumeratorValue | |
731 | @init { | |
732 | enter("enumeratorValue"); | |
733 | } | |
734 | @after { | |
735 | exit("enumeratorValue"); | |
736 | } | |
737 | : | |
738 | ASSIGNMENT e1=unaryExpression | |
739 | ( | |
740 | -> ^(ENUM_VALUE $e1) | |
741 | | ELIPSES e2=unaryExpression -> ^(ENUM_VALUE_RANGE $e1 $e2) | |
742 | ) | |
743 | ; | |
744 | ||
745 | ||
746 | declarator | |
747 | @init { | |
748 | enter("declarator"); | |
749 | } | |
750 | @after { | |
751 | exit("declarator"); | |
752 | } | |
753 | : | |
754 | pointer* directDeclarator -> ^(TYPE_DECLARATOR pointer* directDeclarator) | |
755 | ; | |
756 | ||
757 | directDeclarator | |
758 | @init { | |
759 | enter("directDeclarator"); | |
760 | } | |
761 | @after { | |
762 | exit("directDeclarator"); | |
763 | } | |
764 | : | |
765 | ( | |
766 | IDENTIFIER { if (inTypedef()) addTypeName($IDENTIFIER.text); } {debug_print($IDENTIFIER.text);} | |
767 | /*| LPAREN declarator RPAREN*/ /* Not supported yet */ | |
768 | ) | |
769 | directDeclaratorSuffix* | |
770 | ; | |
771 | ||
772 | directDeclaratorSuffix: | |
773 | OPENBRAC directDeclaratorLength CLOSEBRAC -> ^(LENGTH directDeclaratorLength) | |
774 | ; | |
775 | ||
776 | directDeclaratorLength : | |
777 | unaryExpression | |
778 | ; | |
779 | ||
780 | ||
781 | abstractDeclarator | |
782 | @init { | |
783 | enter("abstractDeclarator"); | |
784 | } | |
785 | @after { | |
786 | exit("abstractDeclarator"); | |
787 | } | |
788 | : | |
789 | (pointer+ directAbstractDeclarator?) -> ^(TYPE_DECLARATOR pointer+ directAbstractDeclarator?) | |
790 | | directAbstractDeclarator -> ^(TYPE_DECLARATOR directAbstractDeclarator) | |
791 | ; | |
792 | ||
793 | /* | |
794 | In the CTF grammar, direct-abstract-declarator can be empty (because of identifier-opt). | |
795 | We take care of that by appending a '?' to each use of "abstractDeclaratorList". | |
796 | */ | |
797 | directAbstractDeclarator | |
798 | @init { | |
799 | enter("directAbstractDeclarator"); | |
800 | } | |
801 | @after { | |
802 | debug_print($directAbstractDeclarator.text); | |
803 | exit("directAbstractDeclarator"); | |
804 | } | |
805 | : | |
806 | ( | |
807 | IDENTIFIER | |
808 | | (LPAREN abstractDeclarator RPAREN) | |
809 | ) | |
810 | ( | |
811 | OPENBRAC unaryExpression? CLOSEBRAC | |
812 | )? | |
813 | ; | |
814 | ||
815 | pointer | |
816 | @init { | |
817 | enter("pointer"); | |
818 | } | |
819 | @after { | |
820 | debug_print($pointer.text); | |
821 | exit("pointer"); | |
822 | } | |
823 | : | |
824 | POINTER typeQualifierList? -> ^(POINTER typeQualifierList?) | |
825 | ; | |
826 | ||
827 | typeQualifierList : | |
828 | typeQualifier+ | |
829 | ; | |
830 | ||
831 | typedefName | |
832 | @init { | |
833 | enter("typedefName"); | |
834 | } | |
835 | @after { | |
836 | debug_print("typedefName: " + $typedefName.text); | |
837 | exit("typedefName"); | |
838 | } | |
839 | : | |
840 | {inTypealiasAlias() || isTypeName(input.LT(1).getText())}? IDENTIFIER { if ((inTypedef() || inTypealiasAlias()) && !isTypeName($IDENTIFIER.text)) { addTypeName($IDENTIFIER.text); } } | |
841 | ; | |
842 | ||
843 | /** | |
844 | * What goes in the target part of a typealias. | |
845 | * | |
846 | * For example, the integer part in: | |
847 | * typealias integer {...} := my_new_integer; | |
848 | */ | |
849 | typealiasTarget | |
850 | @init { | |
851 | enter("typealiasTarget"); | |
852 | } | |
853 | @after { | |
854 | exit("typealiasTarget"); | |
855 | } | |
856 | : | |
857 | declarationSpecifiers abstractDeclaratorList? | |
858 | ; | |
859 | ||
860 | /** | |
861 | * What goes in the alias part of a typealias. | |
862 | * | |
863 | * For example, the my_new_integer part in: | |
864 | * typealias integer {...} := my_new_integer; | |
865 | */ | |
866 | typealiasAlias | |
867 | @init { | |
868 | enter("typealiasAlias"); | |
869 | typealiasAliasOn(); | |
870 | } | |
871 | @after { | |
872 | exit("typealiasAlias"); | |
873 | typealiasAliasOff(); | |
874 | } | |
875 | : | |
876 | ( | |
877 | abstractDeclaratorList | |
878 | | | |
879 | (declarationSpecifiers abstractDeclaratorList?) | |
880 | ) | |
881 | ; | |
882 | ||
883 | typealiasDecl | |
884 | @init { | |
885 | enter("typealiasDecl"); | |
886 | } | |
887 | @after { | |
888 | exit("typealiasDecl"); | |
889 | } | |
890 | : | |
891 | TYPEALIASTOK typealiasTarget TYPE_ASSIGNMENT typealiasAlias | |
892 | -> ^(TYPEALIAS ^(TYPEALIAS_TARGET typealiasTarget) ^(TYPEALIAS_ALIAS typealiasAlias)) | |
893 | ; | |
894 | ||
895 | // 2.3 CTF stuff | |
896 | ||
897 | // TODO: Ajouter ceux qui manquent | |
898 | ctfKeyword | |
899 | @init { | |
900 | enter("ctfKeyword"); | |
901 | } | |
902 | @after { | |
903 | debug_print($ctfKeyword.text); | |
904 | exit("ctfKeyword"); | |
905 | } | |
906 | : | |
907 | ALIGNTOK | |
908 | | EVENTTOK | |
909 | | SIGNEDTOK | |
910 | | STRINGTOK | |
911 | ; | |
912 | ||
913 | ctfSpecifier | |
914 | @init { | |
915 | enter("ctfSpecifier"); | |
916 | } | |
917 | @after { | |
918 | exit("ctfSpecifier"); | |
919 | } | |
920 | : | |
921 | // event {...}, stream {...}, trace {...} | |
922 | ctfSpecifierHead ctfBody -> ^(ctfSpecifierHead ctfBody) | |
923 | | | |
924 | // typealias | |
925 | typealiasDecl -> ^(DECLARATION typealiasDecl) | |
926 | ; | |
927 | ||
928 | ctfSpecifierHead | |
929 | @init { | |
930 | enter("ctfSpecifierHead"); | |
931 | } | |
932 | @after { | |
933 | debug_print($ctfSpecifierHead.text); | |
934 | exit("ctfSpecifierHead"); | |
935 | } | |
936 | : | |
937 | EVENTTOK -> EVENT | |
938 | | STREAMTOK -> STREAM | |
939 | | TRACETOK -> TRACE | |
940 | | ENVTOK -> ENV | |
941 | | CLOCKTOK -> CLOCK | |
4c9d2941 | 942 | | CALLSITETOK -> CALLSITE |
866e5b51 FC |
943 | ; |
944 | ||
945 | ctfTypeSpecifier | |
946 | @init { | |
947 | enter("ctfTypeSpecifier"); | |
948 | } | |
949 | @after { | |
950 | exit("ctfTypeSpecifier"); | |
951 | } | |
952 | : | |
953 | /* ctfBody can return an empty tree if the body is empty */ | |
954 | FLOATINGPOINTTOK ctfBody -> ^(FLOATING_POINT ctfBody?) | |
955 | | INTEGERTOK ctfBody -> ^(INTEGER ctfBody?) | |
956 | | STRINGTOK ctfBody? -> ^(STRING ctfBody?) | |
957 | ; | |
958 | ||
959 | ctfBody | |
960 | scope Symbols; | |
961 | @init { | |
962 | enter("ctfBody"); | |
963 | debug_print("Scope push " + + Symbols_stack.size()); | |
964 | $Symbols::types = new HashSet<String>(); | |
965 | } | |
966 | @after { | |
967 | debug_print("Scope pop " + + Symbols_stack.size()); | |
968 | exit("ctfBody"); | |
969 | } | |
970 | : | |
971 | LCURL ctfAssignmentExpressionList? RCURL -> ctfAssignmentExpressionList? | |
972 | ; | |
973 | ||
974 | ctfAssignmentExpressionList : | |
975 | (ctfAssignmentExpression TERM!)+ | |
976 | ; | |
977 | ||
978 | ||
979 | ctfAssignmentExpression | |
980 | @init { | |
981 | enter("ctfAssignmentExpression"); | |
982 | } | |
983 | @after { | |
984 | if (inTypedef()) { | |
985 | typedefOff(); | |
986 | } | |
987 | exit("ctfAssignmentExpression"); | |
988 | } | |
989 | : | |
990 | ( | |
991 | left=unaryExpression | |
992 | ( | |
993 | (assignment=ASSIGNMENT right1=unaryExpression) -> ^(CTF_EXPRESSION_VAL ^(CTF_LEFT $left) ^(CTF_RIGHT $right1)) | |
994 | | (type_assignment=TYPE_ASSIGNMENT right2=typeSpecifier) -> ^(CTF_EXPRESSION_TYPE ^(CTF_LEFT $left) ^(CTF_RIGHT ^(TYPE_SPECIFIER_LIST $right2))) | |
995 | ) | |
996 | ) | |
997 | ||
998 | | | |
999 | ||
1000 | (declarationSpecifiers {inTypedef()}? declaratorList) | |
1001 | -> ^(TYPEDEF declaratorList declarationSpecifiers) | |
1002 | | | |
1003 | ||
1004 | typealiasDecl | |
1005 | ; |