source: CIVL/grammar/CivlCParser.g@ 2975708a

1.23 2.0 acw/focus-triggers main test-branch
Last change on this file since 2975708a was 084b19e, checked in by Stephen Siegel <siegel@…>, 14 years ago

Fixing small things in grammar.

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@15 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 34.1 KB
Line 
1/* Grammar for programming CIVL-C.
2 * Based on C11 grammar.
3 *
4 * Author: Stephen F. Siegel
5 * Last modified:
6 *
7 * This grammar assumes the input token stream is the result of
8 * translation phase 7, as specified in the Standard.
9 * In particular, all the preprocessing has already been
10 * done.
11 *
12 * In addition to the Standard, I borrowed from the older
13 * C grammar included with the ANTLR distribution.
14 *
15 */
16parser grammar CivlCParser;
17
18options
19{
20 language=Java;
21 tokenVocab=PreprocessorParser;
22 output=AST;
23}
24
25tokens
26{
27 ABSENT; // represents missing syntactic element
28 GENERIC_ASSOC_LIST; // generic association list
29 GENERIC_ASSOCIATION; // a generic association
30 ENUMERATION_CONSTANT; // use of enumeration constant
31 COMPOUND_LITERAL; // literal for structs, etc.
32 CONTRACT; // procedure contracts
33 CALL; // function call
34 INDEX; // array subscript operator
35 ARGUMENT_LIST; // list of arguments to an operator
36 POST_INCREMENT;
37 POST_DECREMENT;
38 PRE_INCREMENT;
39 PRE_DECREMENT;
40 OPERATOR; // symbol indicating an operator
41 TYPE; // symbol indicating "type"
42 EXPR; // symbol indicating "expression"
43 PARENTHESIZED_EXPRESSION;
44 CAST; // type cast operator
45 DECLARATION; // a declaration
46 DECLARATION_SPECIFIERS; // list of declaration specifiers
47 INIT_DECLARATOR_LIST; // list of initializer-declarator pairs
48 INIT_DECLARATOR; // initializer-declaration pair
49 STRUCT_DECLARATION_LIST; // list of field declarations
50 STRUCT_DECLARATION; // a field declaration
51 SPECIFIER_QUALIFIER_LIST; // list of type specifiers and qualifiers
52 STRUCT_DECLARATOR_LIST; // list of struct/union declarators
53 STRUCT_DECLARATOR; // a struct/union declarator
54 ENUMERATOR_LIST; // list of enumerators in enum type definition
55 ENUMERATOR; // identifier and optional int constant
56 DECLARATOR; // a declarator
57 DIRECT_DECLARATOR; // declarator after removing leading *s
58 TYPE_QUALIFIER_LIST; // list of type qualifiers
59 ARRAY_SUFFIX; // [..] used in declarator
60 FUNCTION_SUFFIX; // (..) used in declarator
61 POINTER; // * used in declarator
62 PARAMETER_TYPE_LIST; // parameter list and optional "..."
63 PARAMETER_LIST; // list of parameter decls in function decl
64 PARAMETER_DECLARATION;// parameter declaration in function decl
65 IDENTIFIER_LIST; // list of parameter names only in function decl
66 TYPE_NAME; // type specification without identifier
67 ABSTRACT_DECLARATOR; // declarator without identifier
68 DIRECT_ABSTRACT_DECLARATOR; // direct declarator sans identifier
69 SCALAR_INITIALIZER; //
70 INITIALIZER_LIST;
71 DESIGNATED_INITIALIZER;
72 DESIGNATION;
73 ARRAY_ELEMENT_DESIGNATOR;
74 FIELD_DESIGNATOR;
75 IDENTIFIER_LABELED_STATEMENT;
76 CASE_LABELED_STATEMENT;
77 DEFAULT_LABELED_STATEMENT;
78 COMPOUND_STATEMENT;
79 BLOCK_ITEM_LIST;
80 EXPRESSION_STATEMENT;
81 TRANSLATION_UNIT;
82 DECLARATION_LIST;
83 FUNCTION_DEFINITION;
84 TYPEDEF_NAME;
85 TOKEN_LIST;
86}
87
88scope Symbols {
89 Set<String> types; // to keep track of typedefs
90 Set<String> enumerationConstants; // to keep track of enum constants
91 boolean isFunctionDefinition; // "function scope": entire function definition
92}
93
94scope DeclarationScope {
95 boolean isTypedef; // is the current declaration a typedef
96}
97
98@header
99{
100package edu.udel.cis.vsl.civl.civlc.parse.common;
101
102import java.util.Set;
103import java.util.HashSet;
104import edu.udel.cis.vsl.civl.civlc.parse.IF.RuntimeParseException;
105}
106
107@members {
108 @Override
109 public void displayRecognitionError(String[] tokenNames, RecognitionException e) {
110 String hdr = getErrorHeader(e);
111 String msg = getErrorMessage(e, tokenNames);
112
113 throw new RuntimeParseException(hdr+" "+msg, e.token);
114 }
115
116 @Override
117 public void emitErrorMessage(String msg) { // don't try to recover!
118 throw new RuntimeParseException(msg);
119 }
120
121 boolean isTypeName(String name) {
122 for (Object scope : Symbols_stack)
123 if (((Symbols_scope)scope).types.contains(name)) return true;
124 return false;
125 }
126
127 boolean isEnumerationConstant(String name) {
128 boolean answer = false;
129
130 // System.err.print("Is "+name+" an enumeration constant: ");
131 for (Object scope : Symbols_stack) {
132 if (((Symbols_scope)scope).enumerationConstants.contains(name)) {
133 answer=true;
134 break;
135 }
136 }
137 // System.err.println(answer);
138 // System.err.flush();
139 return answer;
140 }
141}
142
143
144/* ***** A.2.1: Expressions ***** */
145
146/* Constants from A.1.5 */
147
148constant
149 : enumerationConstant
150 | INTEGER_CONSTANT
151 | FLOATING_CONSTANT
152 | CHARACTER_CONSTANT
153 | SELF | TRUE | FALSE | RESULT
154 ;
155
156enumerationConstant
157 : {isEnumerationConstant(input.LT(1).getText())}? IDENTIFIER ->
158 ^(ENUMERATION_CONSTANT IDENTIFIER)
159 ;
160
161/* 6.5.1 */
162primaryExpression
163 : constant
164 | // {!isEnumerationConstant(input.LT(1).getText())}?
165 IDENTIFIER
166 | STRING_LITERAL
167 | LPAREN expression RPAREN
168 -> ^(PARENTHESIZED_EXPRESSION LPAREN expression RPAREN)
169 | genericSelection
170 ;
171
172/* 6.5.1.1 */
173
174genericSelection
175 : GENERIC LPAREN assignmentExpression COMMA genericAssocList
176 RPAREN
177 -> ^(GENERIC assignmentExpression genericAssocList)
178 ;
179
180/* 6.5.1.1 */
181genericAssocList
182 : genericAssociation (COMMA genericAssociation)*
183 -> ^(GENERIC_ASSOC_LIST genericAssociation+)
184 ;
185
186/* 6.5.1.1 */
187genericAssociation
188 : typeName COLON assignmentExpression
189 -> ^(GENERIC_ASSOCIATION typeName assignmentExpression)
190 | DEFAULT COLON assignmentExpression
191 -> ^(GENERIC_ASSOCIATION DEFAULT assignmentExpression)
192 ;
193
194/* 6.5.2 */
195postfixExpression
196 : (postfixExpressionRoot -> postfixExpressionRoot)
197 ( l=LSQUARE expression RSQUARE
198 -> ^(OPERATOR
199 INDEX[$l]
200 ^(ARGUMENT_LIST $postfixExpression expression)
201 RSQUARE)
202 | LPAREN argumentExpressionList RPAREN
203 -> ^(CALL LPAREN $postfixExpression argumentExpressionList RPAREN)
204 | DOT IDENTIFIER
205 -> ^(DOT $postfixExpression IDENTIFIER)
206 | ARROW IDENTIFIER
207 -> ^(ARROW $postfixExpression IDENTIFIER)
208 | p=PLUSPLUS
209 -> ^(OPERATOR POST_INCREMENT[$p]
210 ^(ARGUMENT_LIST $postfixExpression))
211 | AT IDENTIFIER
212 -> ^(AT $postfixExpression IDENTIFIER)
213 | m=MINUSMINUS
214 -> ^(OPERATOR POST_DECREMENT[$m]
215 ^(ARGUMENT_LIST $postfixExpression))
216 )*
217 ;
218
219/*
220 * The "(typename) {...}" is a "compound literal".
221 * See C11 Sec. 6.5.2.5. I don't know what
222 * it means when it ends with an extra COMMA.
223 * I assume it doesn't mean anything and is just
224 * allowed as a convenience for the poor C programmer
225 * (but why?).
226 *
227 * Ambiguity: need to distinguish the compound literal
228 * "(typename) {...}" from the primaryExpression
229 * "(expression)". Presence of '{' implies it must
230 * be the compound literal.
231 */
232postfixExpressionRoot
233 : (LPAREN typeName RPAREN LCURLY)=>
234 LPAREN typeName RPAREN LCURLY initializerList
235 ( RCURLY
236 | COMMA RCURLY
237 )
238 -> ^(COMPOUND_LITERAL LPAREN typeName initializerList RCURLY)
239 | primaryExpression
240 ;
241
242/* 6.5.2 */
243argumentExpressionList
244 : -> ^(ARGUMENT_LIST)
245 | assignmentExpression (COMMA assignmentExpression)*
246 -> ^(ARGUMENT_LIST assignmentExpression+)
247 ;
248
249/* 6.5.3 */
250unaryExpression
251 : postfixExpression
252 | p=PLUSPLUS unaryExpression
253 -> ^(OPERATOR PRE_INCREMENT[$p]
254 ^(ARGUMENT_LIST unaryExpression))
255 | m=MINUSMINUS unaryExpression
256 -> ^(OPERATOR PRE_DECREMENT[$m]
257 ^(ARGUMENT_LIST unaryExpression))
258 | unaryOperator castExpression
259 -> ^(OPERATOR unaryOperator ^(ARGUMENT_LIST castExpression))
260 | (SIZEOF LPAREN typeName)=> SIZEOF LPAREN typeName RPAREN
261 -> ^(SIZEOF TYPE typeName)
262 | SIZEOF unaryExpression
263 -> ^(SIZEOF EXPR unaryExpression)
264 | ALIGNOF LPAREN typeName RPAREN
265 -> ^(ALIGNOF typeName)
266 | spawnExpression
267 ;
268
269
270spawnExpression
271 : SPAWN postfixExpressionRoot LPAREN
272 argumentExpressionList RPAREN
273 -> ^(SPAWN postfixExpressionRoot argumentExpressionList)
274 ;
275
276
277/* 6.5.3 */
278unaryOperator
279 : AMPERSAND | STAR | PLUS | SUB | TILDE | NOT
280 ;
281
282/* 6.5.4 */
283// ambiguity: (expr) is a unary expression and looks
284// like (typeName).
285castExpression
286 : (LPAREN typeName RPAREN)=> l=LPAREN typeName RPAREN castExpression
287 -> ^(CAST typeName castExpression $l)
288 | unaryExpression
289 ;
290
291/* 6.5.5 */
292multiplicativeExpression
293 : (castExpression -> castExpression)
294 ( STAR y=castExpression
295 -> ^(OPERATOR STAR ^(ARGUMENT_LIST $multiplicativeExpression $y))
296 | DIV y=castExpression
297 -> ^(OPERATOR DIV ^(ARGUMENT_LIST $multiplicativeExpression $y))
298 | MOD y=castExpression
299 -> ^(OPERATOR MOD ^(ARGUMENT_LIST $multiplicativeExpression $y))
300 )*
301 ;
302
303/* 6.5.6 */
304additiveExpression
305 : (multiplicativeExpression -> multiplicativeExpression)
306 ( PLUS y=multiplicativeExpression
307 -> ^(OPERATOR PLUS ^(ARGUMENT_LIST $additiveExpression $y))
308 | SUB y=multiplicativeExpression
309 -> ^(OPERATOR SUB ^(ARGUMENT_LIST $additiveExpression $y))
310 )*
311 ;
312
313/* 6.5.7 */
314shiftExpression
315 : (additiveExpression -> additiveExpression)
316 ( SHIFTLEFT y=additiveExpression
317 -> ^(OPERATOR SHIFTLEFT ^(ARGUMENT_LIST $shiftExpression $y))
318 | SHIFTRIGHT y=additiveExpression
319 -> ^(OPERATOR SHIFTRIGHT ^(ARGUMENT_LIST $shiftExpression $y))
320 )*
321 ;
322
323/* 6.5.8 */
324relationalExpression
325 : ( shiftExpression -> shiftExpression )
326 ( relationalOperator y=shiftExpression
327 -> ^(OPERATOR relationalOperator ^(ARGUMENT_LIST $relationalExpression $y))
328 )*
329 ;
330
331relationalOperator
332 : LT | GT | LTE | GTE
333 ;
334
335/* 6.5.9 */
336equalityExpression
337 : ( relationalExpression -> relationalExpression )
338 ( equalityOperator y=relationalExpression
339 -> ^(OPERATOR equalityOperator ^(ARGUMENT_LIST $equalityExpression $y))
340 )*
341 ;
342
343equalityOperator
344 : EQUALS | NEQ
345 ;
346
347/* 6.5.10 */
348andExpression
349 : ( equalityExpression -> equalityExpression )
350 ( AMPERSAND y=equalityExpression
351 -> ^(OPERATOR AMPERSAND ^(ARGUMENT_LIST $andExpression $y))
352 )*
353 ;
354
355/* 6.5.11 */
356exclusiveOrExpression
357 : ( andExpression -> andExpression )
358 ( BITXOR y=andExpression
359 -> ^(OPERATOR BITXOR ^(ARGUMENT_LIST $exclusiveOrExpression $y))
360 )*
361 ;
362
363/* 6.5.12 */
364inclusiveOrExpression
365 : ( exclusiveOrExpression -> exclusiveOrExpression )
366 ( BITOR y=exclusiveOrExpression
367 -> ^(OPERATOR BITOR ^(ARGUMENT_LIST $inclusiveOrExpression $y))
368 )*
369 ;
370
371/* 6.5.13 */
372logicalAndExpression
373 : ( inclusiveOrExpression -> inclusiveOrExpression )
374 ( AND y=inclusiveOrExpression
375 -> ^(OPERATOR AND ^(ARGUMENT_LIST $logicalAndExpression $y))
376 )*
377 ;
378
379/* 6.5.14 */
380logicalOrExpression
381 : ( logicalAndExpression -> logicalAndExpression )
382 ( OR y=logicalAndExpression
383 -> ^(OPERATOR OR ^(ARGUMENT_LIST $logicalOrExpression $y))
384 )*
385 ;
386
387
388/* 6.5.15 */
389conditionalExpression
390 : logicalOrExpression
391 ( -> logicalOrExpression
392 | QMARK expression COLON conditionalExpression
393 -> ^(OPERATOR QMARK
394 ^(ARGUMENT_LIST
395 logicalOrExpression
396 expression
397 conditionalExpression))
398 )
399 ;
400
401/* 6.5.16
402 * conditionalExpression or
403 * Root: OPERATOR
404 * Child 0: assignmentOperator
405 * Child 1: ARGUMENT_LIST
406 * Child 1.0: unaryExpression
407 * Child 1.1: assignmentExpression
408 */
409assignmentExpression
410 : (unaryExpression assignmentOperator)=>
411 unaryExpression assignmentOperator assignmentExpression
412 -> ^(OPERATOR assignmentOperator
413 ^(ARGUMENT_LIST unaryExpression assignmentExpression))
414 | conditionalExpression
415 ;
416
417/* 6.5.16 */
418assignmentOperator
419 : ASSIGN | STAREQ | DIVEQ | MODEQ | PLUSEQ | SUBEQ
420 | SHIFTLEFTEQ | SHIFTRIGHTEQ | BITANDEQ | BITXOREQ | BITOREQ
421 ;
422
423/* 6.5.17
424 * assignmentExpression or
425 * Root: OPERATOR
426 * Child 0: COMMA
427 * Child 1: ARGUMENT_LIST
428 * Child 1.0: arg0
429 * Child 1.1: arg1
430 */
431commaExpression
432 : ( x=assignmentExpression -> assignmentExpression)
433 ( COMMA y=assignmentExpression
434 -> ^(OPERATOR COMMA ^(ARGUMENT_LIST $x $y))
435 )*
436 ;
437
438expression
439 : COLLECTIVE LPAREN proc=commaExpression
440 COMMA int=commaExpression RPAREN body=commaExpression
441 -> ^(COLLECTIVE $proc $int $body)
442 | commaExpression
443 ;
444
445/* 6.6 */
446constantExpression
447 : conditionalExpression
448 ;
449
450/* ***** A.2.2: Declarations ***** */
451
452/* 6.7.
453 *
454 * This rule will construct either a DECLARATION or
455 * STATICASSERT tree:
456
457 * Root: DECLARATION
458 * Child 0: declarationSpecifiers
459 * Child 1: initDeclaratorList or ABSENT
460 *
461 * Root: STATICASSERT
462 * Child 0: constantExpression
463 * Child 1: stringLiteral
464 *
465 * The declarationSpecifiers rule returns a bit telling whether
466 * "typedef" occurred among the specifiers. This bit is passed
467 * to the initDeclaratorList rule, and down the call chain,
468 * where eventually an IDENTIFIER should be reached. At that point,
469 * if the bit is true, the IDENTIFIER is added to the set of typedef
470 * names.
471 *
472 */
473declaration
474scope DeclarationScope;
475@init {
476 $DeclarationScope::isTypedef = false;
477}
478 : d=declarationSpecifiers
479 (
480 i=initDeclaratorList contract_opt SEMI
481 -> ^(DECLARATION $d $i contract_opt)
482 | SEMI
483 -> ^(DECLARATION $d ABSENT)
484 )
485 | staticAssertDeclaration
486 ;
487
488/* 6.7
489 * Root: DECLARATION_SPECIFIERS
490 * Children: declarationSpecifier (any number)
491 */
492declarationSpecifiers
493 : l=declarationSpecifierList
494 -> ^(DECLARATION_SPECIFIERS declarationSpecifierList)
495 ;
496
497/* Tree: flat list of declarationSpecifier
498 */
499declarationSpecifierList
500 : (
501 {!$DeclarationScope::isTypedef || input.LT(2).getType() != SEMI }?
502 s=declarationSpecifier
503 )+
504 ;
505
506declarationSpecifier
507 : s=storageClassSpecifier
508 | typeSpecifierOrQualifier
509 | functionSpecifier
510 | alignmentSpecifier
511 ;
512
513/*
514 * I factored this out of the declarationSpecifiers rule
515 * to deal with the ambiguity of "ATOMIC" in one place.
516 * "ATOMIC ( typeName )" matches atomicTypeSpecifier, which
517 * is a typeSpecifier. "ATOMIC" matches typeQualifier.
518 * When you see "ATOMIC" all you have to do is look at the
519 * next token. If it's '(', typeSpecifier is it.
520 */
521typeSpecifierOrQualifier
522 : (typeSpecifier)=> typeSpecifier
523 | typeQualifier
524 ;
525
526/* 6.7
527 * Root: INIT_DECLARATOR_LIST
528 * Children: initDeclarator
529 */
530initDeclaratorList
531 : i+=initDeclarator (COMMA i+=initDeclarator)*
532 -> ^(INIT_DECLARATOR_LIST $i+)
533 ;
534
535/* 6.7
536 * Root: INIT_DECLARATOR
537 * Child 0: declarator
538 * Child 1: initializer or ABSENT
539 */
540initDeclarator
541 : d=declarator
542 ( -> ^(INIT_DECLARATOR $d ABSENT)
543 | (ASSIGN i=initializer) -> ^(INIT_DECLARATOR $d $i)
544 )
545 ;
546
547/* 6.7.1 */
548storageClassSpecifier
549 : TYPEDEF {$DeclarationScope::isTypedef = true;}
550 | (EXTERN | STATIC | THREADLOCAL | AUTO | REGISTER)
551 ;
552
553/* 6.7.2 */
554typeSpecifier
555 : VOID | CHAR | SHORT | INT | LONG | FLOAT | DOUBLE
556 | SIGNED | UNSIGNED | BOOL | COMPLEX
557 | PROC
558 | atomicTypeSpecifier
559 | structOrUnionSpecifier
560 | enumSpecifier
561 | typedefName
562 ;
563
564/* 6.7.2.1
565 * Root: STRUCT or UNION
566 * Child 0: IDENTIFIER (the tag) or ABSENT
567 * Child 1: structDeclarationList or ABSENT
568 */
569structOrUnionSpecifier
570 : structOrUnion
571 ( IDENTIFIER LCURLY structDeclarationList RCURLY
572 -> ^(structOrUnion IDENTIFIER structDeclarationList RCURLY)
573 | LCURLY structDeclarationList RCURLY
574 -> ^(structOrUnion ABSENT structDeclarationList RCURLY)
575 | IDENTIFIER
576 -> ^(structOrUnion IDENTIFIER ABSENT)
577 )
578 ;
579
580/* 6.7.2.1 */
581structOrUnion
582 : STRUCT | UNION
583 ;
584
585/* 6.7.2.1
586 * Root: STRUCT_DECLARATION_LIST
587 * Children: structDeclaration
588 */
589structDeclarationList
590 : structDeclaration+
591 -> ^(STRUCT_DECLARATION_LIST structDeclaration+)
592 ;
593
594/* 6.7.2.1
595 * Two possible trees:
596 *
597 * Root: STRUCT_DECLARATION
598 * Child 0: specifierQualifierList
599 * Child 1: structDeclaratorList or ABSENT
600 *
601 * or
602 *
603 * staticAssertDeclaration (root: STATICASSERT)
604 */
605structDeclaration
606scope DeclarationScope;
607@init {
608 $DeclarationScope::isTypedef = false;
609}
610 : s=specifierQualifierList
611 ( -> ^(STRUCT_DECLARATION $s ABSENT)
612 | structDeclaratorList
613 -> ^(STRUCT_DECLARATION $s structDeclaratorList)
614 )
615 SEMI
616 | staticAssertDeclaration
617 ;
618
619/* 6.7.2.1
620 * Root: SPECIFIER_QUALIFIER_LIST
621 * Children: typeSpecifierOrQualifier
622 */
623specifierQualifierList
624 : typeSpecifierOrQualifier+
625 -> ^(SPECIFIER_QUALIFIER_LIST typeSpecifierOrQualifier+)
626 ;
627
628/* 6.7.2.1
629 * Root: STRUCT_DECLARATOR_LIST
630 * Children: structDeclarator (at least 1)
631 */
632structDeclaratorList
633 : s+=structDeclarator (COMMA s+=structDeclarator)*
634 -> ^(STRUCT_DECLARATOR_LIST $s+)
635 ;
636
637/* 6.7.2.1
638 * Root: STRUCT_DECLARATOR
639 * Child 0: declarator or ABSENT
640 * Child 1: constantExpression or ABSENT
641 */
642structDeclarator
643 : declarator
644 ( -> ^(STRUCT_DECLARATOR declarator ABSENT)
645 | COLON constantExpression
646 -> ^(STRUCT_DECLARATOR declarator constantExpression)
647 )
648 | COLON constantExpression
649 -> ^(STRUCT_DECLARATOR ABSENT constantExpression)
650 ;
651
652/* 6.7.2.2
653 * Root: ENUM
654 * Child 0: IDENTIFIER (tag) or ABSENT
655 * Child 1: enumeratorList
656 */
657enumSpecifier
658 : ENUM
659 ( IDENTIFIER
660 -> ^(ENUM IDENTIFIER ABSENT)
661 | IDENTIFIER LCURLY enumeratorList COMMA? RCURLY
662 -> ^(ENUM IDENTIFIER enumeratorList)
663 | LCURLY enumeratorList COMMA? RCURLY
664 -> ^(ENUM ABSENT enumeratorList)
665 )
666 ;
667
668/* 6.7.2.2
669 * Root: ENUMERATOR_LIST
670 * Children: enumerator
671 */
672enumeratorList
673 : enumerator (COMMA enumerator)*
674 -> ^(ENUMERATOR_LIST enumerator+)
675 ;
676
677/* 6.7.2.2
678 * Root: ENUMERATOR
679 * Child 0: IDENTIFIER
680 * Child 1: constantExpression or ABSENT
681 */
682enumerator
683 : IDENTIFIER
684 {
685 $Symbols::enumerationConstants.add($IDENTIFIER.text);
686 // System.err.println("define enum constant "+$IDENTIFIER.text);
687 }
688 ( -> ^(ENUMERATOR IDENTIFIER ABSENT)
689 | (ASSIGN constantExpression)
690 -> ^(ENUMERATOR IDENTIFIER constantExpression)
691 )
692 ;
693
694/* 6.7.2.4 */
695atomicTypeSpecifier
696 : ATOMIC LPAREN typeName RPAREN
697 -> ^(ATOMIC typeName)
698 ;
699
700/* 6.7.3 */
701typeQualifier
702 : CONST | RESTRICT | VOLATILE | ATOMIC
703 | INPUT | OUTPUT
704 ;
705
706/* 6.7.4 */
707functionSpecifier
708 : INLINE | NORETURN
709 ;
710
711/* 6.7.5
712 * Root: ALIGNAS
713 * Child 0: TYPE or EXPR
714 * Child 1: typeName (if Child 0 is TYPE) or constantExpression
715 * (if Child 0 is EXPR)
716 */
717alignmentSpecifier
718 : ALIGNAS LPAREN
719 ( typeName RPAREN
720 -> ^(ALIGNAS TYPE typeName)
721 | constantExpression RPAREN
722 -> ^(ALIGNAS EXPR constantExpression)
723 )
724 ;
725
726/* 6.7.6
727 * Root: DECLARATOR
728 * Child 0: pointer or ABSENT
729 * Child 1: directDeclarator
730 */
731declarator
732 : d=directDeclarator
733 -> ^(DECLARATOR ABSENT $d)
734 | pointer d=directDeclarator
735 -> ^(DECLARATOR pointer $d)
736 ;
737
738/* 6.7.6
739 * Root: DIRECT_DECLARATOR
740 * Child 0: directDeclaratorPrefix
741 * Children 1..: list of directDeclaratorSuffix (may be empty)
742 */
743directDeclarator
744 : p=directDeclaratorPrefix
745 ( -> ^(DIRECT_DECLARATOR $p)
746 | s+=directDeclaratorSuffix+ ->^(DIRECT_DECLARATOR $p $s+)
747 )
748 ;
749
750/*
751 * Tree: either an IDENTIFIER or a declarator.
752 */
753directDeclaratorPrefix
754 : IDENTIFIER
755 {
756 if ($DeclarationScope::isTypedef) {
757 $Symbols::types.add($IDENTIFIER.text);
758 //System.err.println("define type "+$IDENTIFIER.text);
759 }
760 }
761 | LPAREN! declarator RPAREN!
762 ;
763
764
765directDeclaratorSuffix
766 : directDeclaratorArraySuffix
767 | directDeclaratorFunctionSuffix
768 ;
769
770/*
771 * Root: ARRAY_SUFFIX
772 * child 0: LSQUARE (for source information)
773 * child 1: STATIC or ABSENT
774 * child 2: TYPE_QUALIFIER_LIST
775 * child 3: expression (array extent),
776 * "*" (unspecified variable length), or ABSENT
777 * child 4: RSQUARE (for source information)
778 */
779directDeclaratorArraySuffix
780 : LSQUARE
781 ( typeQualifierList_opt assignmentExpression_opt RSQUARE
782 -> ^(ARRAY_SUFFIX LSQUARE ABSENT typeQualifierList_opt
783 assignmentExpression_opt RSQUARE)
784 | STATIC typeQualifierList_opt assignmentExpression RSQUARE
785 -> ^(ARRAY_SUFFIX LSQUARE STATIC typeQualifierList_opt
786 assignmentExpression RSQUARE)
787 | typeQualifierList STATIC assignmentExpression RSQUARE
788 -> ^(ARRAY_SUFFIX LSQUARE STATIC typeQualifierList
789 assignmentExpression RSQUARE)
790 | typeQualifierList_opt STAR RSQUARE
791 -> ^(ARRAY_SUFFIX LSQUARE ABSENT typeQualifierList_opt
792 STAR RSQUARE)
793 )
794 ;
795
796/*
797 * Root: FUNCTION_SUFFIX
798 * child 0: LPAREN (for source information)
799 * child 1: either parameterTypeList or identifierList or ABSENT
800 * child 2: RPAREN (for source information)
801 */
802directDeclaratorFunctionSuffix
803 : LPAREN
804 ( parameterTypeList RPAREN
805 -> ^(FUNCTION_SUFFIX LPAREN parameterTypeList RPAREN)
806 | identifierList RPAREN
807 -> ^(FUNCTION_SUFFIX LPAREN identifierList RPAREN)
808 | RPAREN -> ^(FUNCTION_SUFFIX LPAREN ABSENT RPAREN)
809 )
810 ;
811
812/*
813 * Root: TYPE_QUALIFIER_LIST
814 * Children: typeQualifier
815 */
816typeQualifierList_opt
817 : typeQualifier* -> ^(TYPE_QUALIFIER_LIST typeQualifier*)
818 ;
819
820/*
821 * Tree: assignmentExpression or ABSENT
822 */
823assignmentExpression_opt
824 : -> ABSENT
825 | assignmentExpression
826 ;
827
828/* 6.7.6
829 * Root: POINTER
830 * chilren: STAR
831 */
832pointer
833 : pointer_part+ -> ^(POINTER pointer_part+)
834 ;
835
836/*
837 * Root: STAR
838 * child 0: TYPE_QUALIFIER_LIST
839 */
840pointer_part
841 : STAR typeQualifierList_opt -> ^(STAR typeQualifierList_opt)
842 ;
843
844/* 6.7.6
845 * Root: TYPE_QUALIFIER_LIST
846 * children: typeQualifier
847 */
848typeQualifierList
849 : typeQualifier+ -> ^(TYPE_QUALIFIER_LIST typeQualifier+)
850 ;
851
852/* 6.7.6
853 * Root: PARAMETER_TYPE_LIST
854 * child 0: parameterList (at least 1 parameter declaration)
855 * child 1: ELLIPSIS or ABSENT
856 *
857 * If the parameterTypeList occurs in a function prototype
858 * (that is not part of a function definition), it defines
859 * a new scope (a "function prototype scope"). If it occurs
860 * in a function definition, it does not define a new scope.
861 */
862
863parameterTypeList
864 : {$Symbols::isFunctionDefinition}? parameterTypeListWithoutScope
865 | parameterTypeListWithScope
866 ;
867
868parameterTypeListWithScope
869scope Symbols;
870@init {
871 $Symbols::types = new HashSet<String>();
872 $Symbols::enumerationConstants = new HashSet<String>();
873 $Symbols::isFunctionDefinition = false;
874}
875 : parameterTypeListWithoutScope
876 ;
877
878parameterTypeListWithoutScope
879 : parameterList
880 ( -> ^(PARAMETER_TYPE_LIST parameterList ABSENT)
881 | COMMA ELLIPSIS
882 -> ^(PARAMETER_TYPE_LIST parameterList ELLIPSIS)
883 )
884 ;
885
886/* 6.7.6
887 * Root: PARAMETER_LIST
888 * children: parameterDeclaration
889 */
890parameterList
891 : parameterDeclaration (COMMA parameterDeclaration)*
892 -> ^(PARAMETER_LIST parameterDeclaration+)
893 ;
894
895/* 6.7.6
896 * Root: PARAMETER_DECLARATION
897 * Child 0: declarationSpecifiers
898 * Child 1: declarator, or abstractDeclarator, or ABSENT
899 */
900parameterDeclaration
901scope DeclarationScope;
902@init {
903 $DeclarationScope::isTypedef = false;
904}
905 : declarationSpecifiers
906 ( -> ^(PARAMETER_DECLARATION declarationSpecifiers ABSENT)
907 | declaratorOrAbstractDeclarator
908 -> ^(PARAMETER_DECLARATION
909 declarationSpecifiers declaratorOrAbstractDeclarator)
910 )
911 ;
912
913
914// this has non-LL* decision due to recursive rule invocations
915// reachable from alts 1,2... E.g., both can start with pointer.
916
917declaratorOrAbstractDeclarator
918 : (declarator)=> declarator
919 | abstractDeclarator
920 ;
921
922
923/* 6.7.6
924 * Root: IDENTIFIER_LIST
925 * children: IDENTIFIER (at least 1)
926 */
927identifierList
928 : IDENTIFIER ( COMMA IDENTIFIER )*
929 -> ^(IDENTIFIER_LIST IDENTIFIER+)
930 ;
931
932/* 6.7.6. This is how a type is described without attaching
933 * it to an identifier.
934 * Root: TYPE_NAME
935 * child 0: specifierQualifierList
936 * child 1: abstractDeclarator or ABSENT
937 */
938typeName
939 : specifierQualifierList
940 ( -> ^(TYPE_NAME specifierQualifierList ABSENT)
941 | abstractDeclarator
942 -> ^(TYPE_NAME specifierQualifierList abstractDeclarator)
943 )
944 ;
945
946/* 6.7.7. Abstract declarators are like declarators without
947 * the IDENTIFIER.
948 *
949 * Root: ABSTRACT_DECLARATOR
950 * Child 0. pointer (may be ABSENT). Some number of *s with possible
951 * type qualifiers.
952 * Child 1. directAbstractDeclarator (may be ABSENT).
953 */
954abstractDeclarator
955 : pointer
956 -> ^(ABSTRACT_DECLARATOR pointer ABSENT)
957 | directAbstractDeclarator
958 -> ^(ABSTRACT_DECLARATOR ABSENT directAbstractDeclarator)
959 | pointer directAbstractDeclarator
960 -> ^(ABSTRACT_DECLARATOR pointer directAbstractDeclarator)
961 ;
962
963/* 6.7.7
964 *
965 * Root: DIRECT_ABSTRACT_DECLARATOR
966 * Child 0. abstract declarator or ABSENT.
967 * Children 1..: any number of direct abstract declarator suffixes
968 *
969 * Note that the difference between this and a directDeclarator
970 * is that Child 0 of a direct declarator would be either
971 * an IDENTIFIER or a declarator, but never ABSENT.
972 */
973directAbstractDeclarator
974 : LPAREN abstractDeclarator RPAREN directAbstractDeclaratorSuffix*
975 -> ^(DIRECT_ABSTRACT_DECLARATOR abstractDeclarator
976 directAbstractDeclaratorSuffix*)
977 | directAbstractDeclaratorSuffix+
978 -> ^(DIRECT_ABSTRACT_DECLARATOR ABSENT directAbstractDeclaratorSuffix+)
979 ;
980
981
982/* 6.7.8
983 * Root: TYPEDEF_NAME
984 * Child 0: IDENTIFIER
985 *
986 * Ambiguity: example:
987 * typedef int foo;
988 * typedef int foo;
989 *
990 * This is perfectly legal: you can define a typedef twice
991 * as long as both definitions are equivalent. However,
992 * the first definition causes foo to be entered into the type name
993 * table, so when parsing the second definition, foo is
994 * interpreted as a typedefName (a type specifier), and the
995 * declaration would have empty declarator. This is not
996 * what you want, so you have to forbid it somehow. I do this
997 * by requiring that if you are "in" a typedef, a typedef name
998 * cannot be immediately followed by a semicolon. This is sound
999 * because the C11 Standard requires at least one declarator
1000 * to be present in a typedef.
1001 */
1002typedefName
1003 : {isTypeName(input.LT(1).getText())}? IDENTIFIER
1004 -> ^(TYPEDEF_NAME IDENTIFIER)
1005 ;
1006
1007/* 6.7.7
1008 * Two possibilities:
1009 *
1010 * Root: ARRAY_SUFFIX
1011 * Child 0: STATIC or ABSENT
1012 * Child 1: typeQualifierList or ABSENT
1013 * Child 2: expression or STAR or ABSENT
1014 *
1015 * Root: FUNCTION_SUFFIX
1016 * Child 0: parameterTypeList or ABSENT
1017 */
1018directAbstractDeclaratorSuffix
1019 : LSQUARE
1020 ( typeQualifierList_opt assignmentExpression_opt RSQUARE
1021 -> ^(ARRAY_SUFFIX ABSENT typeQualifierList_opt
1022 assignmentExpression_opt)
1023 | STATIC typeQualifierList_opt assignmentExpression RSQUARE
1024 -> ^(ARRAY_SUFFIX STATIC typeQualifierList_opt
1025 assignmentExpression)
1026 | typeQualifierList STATIC assignmentExpression RSQUARE
1027 -> ^(ARRAY_SUFFIX STATIC typeQualifierList assignmentExpression)
1028 | STAR RSQUARE
1029 -> ^(ARRAY_SUFFIX ABSENT ABSENT STAR)
1030 )
1031 | LPAREN
1032 ( parameterTypeList RPAREN
1033 -> ^(FUNCTION_SUFFIX parameterTypeList)
1034 | RPAREN
1035 -> ^(FUNCTION_SUFFIX ABSENT)
1036 )
1037 ;
1038
1039/* 6.7.9 */
1040initializer
1041 : assignmentExpression -> ^(SCALAR_INITIALIZER assignmentExpression)
1042 | LCURLY initializerList
1043 ( RCURLY
1044 | COMMA RCURLY
1045 )
1046 -> initializerList
1047 ;
1048
1049/* 6.7.9 */
1050initializerList
1051 : designatedInitializer (COMMA designatedInitializer)*
1052 -> ^(INITIALIZER_LIST designatedInitializer+)
1053 ;
1054
1055designatedInitializer
1056 : initializer
1057 -> ^(DESIGNATED_INITIALIZER ABSENT initializer)
1058 | designation initializer
1059 -> ^(DESIGNATED_INITIALIZER designation initializer)
1060 ;
1061
1062/* 6.7.9 */
1063designation
1064 : designatorList ASSIGN -> ^(DESIGNATION designatorList)
1065 ;
1066
1067/* 6.7.9 */
1068designatorList
1069 : designator+
1070 ;
1071
1072/* 6.7.9 */
1073designator
1074 : LSQUARE constantExpression RSQUARE
1075 -> ^(ARRAY_ELEMENT_DESIGNATOR constantExpression)
1076 | DOT IDENTIFIER
1077 -> ^(FIELD_DESIGNATOR IDENTIFIER)
1078 ;
1079
1080/* 6.7.10 */
1081staticAssertDeclaration
1082 : STATICASSERT LPAREN constantExpression COMMA STRING_LITERAL
1083 RPAREN SEMI
1084 -> ^(STATICASSERT constantExpression STRING_LITERAL)
1085 ;
1086
1087
1088/* ***** A.2.3: Statements ***** */
1089
1090/* 6.8 */
1091statement
1092 : labeledStatement
1093 | compoundStatement
1094 | expressionStatement
1095 | selectionStatement
1096 | iterationStatement
1097 | jumpStatement
1098 | pragma
1099 | assertStatement
1100 | assumeStatement
1101 | waitStatement
1102 | whenStatement
1103 | chooseStatement
1104 ;
1105
1106statementWithScope
1107scope Symbols;
1108@init {
1109 $Symbols::types = new HashSet<String>();
1110 $Symbols::enumerationConstants = new HashSet<String>();
1111 $Symbols::isFunctionDefinition = false;
1112}
1113 : statement
1114 ;
1115
1116/* 6.8.1
1117 * Three possible trees:
1118 *
1119 * Root: IDENTIFIER_LABELED_STATEMENT
1120 * Child 0: IDENTIFIER
1121 * Child 1: statement
1122 *
1123 * Root: CASE_LABELED_STATEMENT
1124 * Child 0: CASE
1125 * Child 1: constantExpression
1126 * Child 2: statement
1127 *
1128 * Root: DEFAULT_LABELED_STATEMENT
1129 * Child 0: DEFAULT
1130 * Child 1: statement
1131 */
1132labeledStatement
1133 : IDENTIFIER COLON statement
1134 -> ^(IDENTIFIER_LABELED_STATEMENT IDENTIFIER statement)
1135 | CASE constantExpression COLON statement
1136 -> ^(CASE_LABELED_STATEMENT CASE constantExpression statement)
1137 | DEFAULT COLON statement
1138 -> ^(DEFAULT_LABELED_STATEMENT DEFAULT statement)
1139 ;
1140
1141/* 6.8.2
1142 * Root: BLOCK
1143 * Child 0: LCURLY (for source information)
1144 * Child 1: blockItemList or ABSENT
1145 * Child 2: RCURLY (for source information)
1146 */
1147compoundStatement
1148scope Symbols;
1149@init {
1150 $Symbols::types = new HashSet<String>();
1151 $Symbols::enumerationConstants = new HashSet<String>();
1152 $Symbols::isFunctionDefinition = false;
1153}
1154 : LCURLY
1155 ( RCURLY
1156 -> ^(COMPOUND_STATEMENT LCURLY ABSENT RCURLY)
1157 | blockItemList RCURLY
1158 -> ^(COMPOUND_STATEMENT LCURLY blockItemList RCURLY)
1159 )
1160 ;
1161
1162/* 6.8.2 */
1163blockItemList
1164 : blockItem+ -> ^(BLOCK_ITEM_LIST blockItem+)
1165 ;
1166
1167/* 6.8.2 */
1168blockItem
1169 : (declarationSpecifiers declarator declarationList_opt LCURLY)=>
1170 functionDefinition
1171 | declaration
1172 | statement
1173 ;
1174
1175/* 6.8.3
1176 * Root: EXPRESSION_STATEMENT
1177 * Child 0: expression or ABSENT
1178 * Child 1: SEMI (for source information)
1179 */
1180expressionStatement
1181 : expression SEMI -> ^(EXPRESSION_STATEMENT expression SEMI)
1182 | SEMI -> ^(EXPRESSION_STATEMENT ABSENT SEMI)
1183 ;
1184
1185/* 6.8.4
1186 * Two possible trees:
1187 *
1188 * Root: IF
1189 * Child 0: expression
1190 * Child 1: statement (true branch)
1191 * Child 2: statement or ABSENT (false branch)
1192 *
1193 * Root: SWITCH
1194 * Child 0: expression
1195 * Child 1: statement
1196 */
1197selectionStatement
1198scope Symbols;
1199@init {
1200 $Symbols::types = new HashSet<String>();
1201 $Symbols::enumerationConstants = new HashSet<String>();
1202 $Symbols::isFunctionDefinition = false;
1203}
1204 : IF LPAREN expression RPAREN s1=statementWithScope
1205 ( (ELSE)=> ELSE s2=statementWithScope
1206 -> ^(IF expression $s1 $s2)
1207 | -> ^(IF expression $s1 ABSENT)
1208 )
1209 | SWITCH LPAREN expression RPAREN s=statementWithScope
1210 -> ^(SWITCH expression $s)
1211 ;
1212
1213/* 6.8.5
1214 * Three possible trees:
1215 *
1216 * Root: WHILE
1217 * Child 0: expression
1218 * Child 1: statement
1219 *
1220 * Root: DO
1221 * Child 0: statement
1222 * Child 1: expression
1223 *
1224 * Root: FOR
1225 * Child 0: clause-1: declaration, expression, or ABSENT
1226 * (for loop initializer)
1227 * Child 1: expression or ABSENT (condition)
1228 * Child 2: expression or ABSENT (incrementer)
1229 * Child 3: statement (body)
1230 *
1231 */
1232iterationStatement
1233scope Symbols;
1234@init {
1235 $Symbols::types = new HashSet<String>();
1236 $Symbols::enumerationConstants = new HashSet<String>();
1237 $Symbols::isFunctionDefinition = false;
1238}
1239 : WHILE LPAREN expression RPAREN invariant_opt
1240 s=statementWithScope
1241 -> ^(WHILE expression $s invariant_opt)
1242 | DO s=statementWithScope WHILE LPAREN expression RPAREN
1243 invariant_opt SEMI
1244 -> ^(DO $s expression invariant_opt)
1245 | FOR LPAREN
1246 ( d=declaration e1=expression_opt SEMI e2=expression_opt
1247 RPAREN i=invariant_opt s=statementWithScope
1248 -> ^(FOR $d $e1 $e2 $s $i)
1249 | e0=expression_opt SEMI e1=expression_opt SEMI
1250 e2=expression_opt RPAREN s=statementWithScope
1251 -> ^(FOR $e0 $e1 $e2 $s $i)
1252 )
1253 ;
1254
1255expression_opt
1256 : expression
1257 | -> ABSENT
1258 ;
1259
1260invariant_opt
1261 : -> ABSENT
1262 | INVARIANT LPAREN expression RPAREN
1263 -> ^(INVARIANT expression)
1264 ;
1265
1266
1267/* 6.8.6
1268 * Four possible trees:
1269 *
1270 * Root: GOTO
1271 * Child 0: IDENTIFIER
1272 * Child 1: SEMI (for source information)
1273 *
1274 * Root: CONTINUE
1275 * Child 0: SEMI (for source information)
1276 *
1277 * Root: BREAK
1278 * Child 0: SEMI (for source information)
1279 *
1280 * Root: RETURN
1281 * Child 0: expression or ABSENT
1282 * Child 1: SEMI (for source information)
1283 */
1284jumpStatement
1285 : GOTO IDENTIFIER SEMI -> ^(GOTO IDENTIFIER SEMI)
1286 | CONTINUE SEMI -> ^(CONTINUE SEMI)
1287 | BREAK SEMI -> ^(BREAK SEMI)
1288 | RETURN expression_opt SEMI -> ^(RETURN expression_opt SEMI)
1289 ;
1290
1291/*
1292 * Root: PRAGMA
1293 * child 0: IDENTIFIER (first token following # pragma)
1294 * child 1: TOKEN_LIST (chilren are list of tokens following identifier)
1295 * child 2: NEWLINE (character which ends the pragma)
1296 */
1297pragma : PRAGMA IDENTIFIER pragmaBody NEWLINE
1298 -> ^(PRAGMA IDENTIFIER ^(TOKEN_LIST pragmaBody) NEWLINE)
1299 ;
1300
1301pragmaBody
1302 : (~ NEWLINE)*
1303 ;
1304
1305assertStatement
1306 : ASSERT expression SEMI -> ^(ASSERT expression)
1307 ;
1308
1309assumeStatement
1310 : ASSUME expression SEMI -> ^(ASSUME expression)
1311 ;
1312
1313waitStatement
1314 : WAIT expression SEMI -> ^(WAIT expression)
1315 ;
1316
1317whenStatement
1318 : WHEN LPAREN expression RPAREN statement
1319 -> ^(WHEN expression statement)
1320 ;
1321
1322chooseStatement
1323 : CHOOSE LCURLY statement+ RCURLY
1324 -> ^(CHOOSE statement+)
1325 ;
1326
1327/* ***** A.2.4: External Definitions ***** */
1328
1329/* 6.9
1330 * Root: TRANSLATION_UNIT
1331 * Children: externalDeclaration
1332 */
1333translationUnit
1334scope Symbols; // the global scope
1335scope DeclarationScope; // just to have an outermost one with isTypedef false
1336@init {
1337 $Symbols::types = new HashSet<String>();
1338 $Symbols::enumerationConstants = new HashSet<String>();
1339 $Symbols::isFunctionDefinition = false;
1340 $DeclarationScope::isTypedef = false;
1341}
1342 : externalDeclaration* EOF
1343 -> ^(TRANSLATION_UNIT externalDeclaration*)
1344 ;
1345
1346/* 6.9
1347 * Need to look ahead to distinguish function definition from
1348 * a declaration. As soon as you see the "{", you know you
1349 * are in a function definition.
1350 */
1351externalDeclaration
1352 : (declarationSpecifiers declarator
1353 contract_opt declarationList_opt LCURLY)=>
1354 functionDefinition
1355 | declaration
1356 | pragma
1357 ;
1358
1359/* 6.9.1 */
1360functionDefinition
1361scope Symbols; // "function scope"
1362@init {
1363 $Symbols::types = new HashSet<String>();
1364 $Symbols::enumerationConstants = new HashSet<String>();
1365 $Symbols::isFunctionDefinition = true;
1366}
1367 : declarationSpecifiers declarator contract_opt
1368 declarationList_opt compoundStatement
1369 -> ^(FUNCTION_DEFINITION declarationSpecifiers declarator
1370 declarationList_opt compoundStatement contract_opt)
1371 ;
1372
1373
1374/* 6.9.1
1375 * Root: DECLARATION_LIST
1376 * Children: declaration (any number)
1377 */
1378declarationList_opt
1379 : declaration* -> ^(DECLARATION_LIST declaration*)
1380 ;
1381
1382contractItem
1383 : REQUIRES expression SEMI -> ^(REQUIRES expression)
1384 | ENSURES expression SEMI -> ^(ENSURES expression)
1385 ;
1386
1387contract_opt
1388 : contractItem* -> ^(CONTRACT contractItem*)
1389 ;
Note: See TracBrowser for help on using the repository browser.