source: CIVL/grammar/CivlCParser.g@ 366d0b2

1.23 2.0 acw/focus-triggers main test-branch
Last change on this file since 366d0b2 was 59b5362, checked in by Stephen Siegel <siegel@…>, 14 years ago

Updated CIVL-C grammar to use all \ and contracts.

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@12 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 commaExpression RPAREN commaExpression
440 -> ^(COLLECTIVE commaExpression commaExpression)
441 | commaExpression
442 ;
443
444/* 6.6 */
445constantExpression
446 : conditionalExpression
447 ;
448
449/* ***** A.2.2: Declarations ***** */
450
451/* 6.7.
452 *
453 * This rule will construct either a DECLARATION or
454 * STATICASSERT tree:
455
456 * Root: DECLARATION
457 * Child 0: declarationSpecifiers
458 * Child 1: initDeclaratorList or ABSENT
459 *
460 * Root: STATICASSERT
461 * Child 0: constantExpression
462 * Child 1: stringLiteral
463 *
464 * The declarationSpecifiers rule returns a bit telling whether
465 * "typedef" occurred among the specifiers. This bit is passed
466 * to the initDeclaratorList rule, and down the call chain,
467 * where eventually an IDENTIFIER should be reached. At that point,
468 * if the bit is true, the IDENTIFIER is added to the set of typedef
469 * names.
470 *
471 */
472declaration
473scope DeclarationScope;
474@init {
475 $DeclarationScope::isTypedef = false;
476}
477 : d=declarationSpecifiers
478 (
479 i=initDeclaratorList contract_opt SEMI
480 -> ^(DECLARATION $d $i contract_opt)
481 | SEMI
482 -> ^(DECLARATION $d ABSENT)
483 )
484 | staticAssertDeclaration
485 ;
486
487/* 6.7
488 * Root: DECLARATION_SPECIFIERS
489 * Children: declarationSpecifier (any number)
490 */
491declarationSpecifiers
492 : l=declarationSpecifierList
493 -> ^(DECLARATION_SPECIFIERS declarationSpecifierList)
494 ;
495
496/* Tree: flat list of declarationSpecifier
497 */
498declarationSpecifierList
499 : (
500 {!$DeclarationScope::isTypedef || input.LT(2).getType() != SEMI }?
501 s=declarationSpecifier
502 )+
503 ;
504
505declarationSpecifier
506 : s=storageClassSpecifier
507 | typeSpecifierOrQualifier
508 | functionSpecifier
509 | alignmentSpecifier
510 ;
511
512/*
513 * I factored this out of the declarationSpecifiers rule
514 * to deal with the ambiguity of "ATOMIC" in one place.
515 * "ATOMIC ( typeName )" matches atomicTypeSpecifier, which
516 * is a typeSpecifier. "ATOMIC" matches typeQualifier.
517 * When you see "ATOMIC" all you have to do is look at the
518 * next token. If it's '(', typeSpecifier is it.
519 */
520typeSpecifierOrQualifier
521 : (typeSpecifier)=> typeSpecifier
522 | typeQualifier
523 ;
524
525/* 6.7
526 * Root: INIT_DECLARATOR_LIST
527 * Children: initDeclarator
528 */
529initDeclaratorList
530 : i+=initDeclarator (COMMA i+=initDeclarator)*
531 -> ^(INIT_DECLARATOR_LIST $i+)
532 ;
533
534/* 6.7
535 * Root: INIT_DECLARATOR
536 * Child 0: declarator
537 * Child 1: initializer or ABSENT
538 */
539initDeclarator
540 : d=declarator
541 ( -> ^(INIT_DECLARATOR $d ABSENT)
542 | (ASSIGN i=initializer) -> ^(INIT_DECLARATOR $d $i)
543 )
544 ;
545
546/* 6.7.1 */
547storageClassSpecifier
548 : TYPEDEF {$DeclarationScope::isTypedef = true;}
549 | (EXTERN | STATIC | THREADLOCAL | AUTO | REGISTER)
550 ;
551
552/* 6.7.2 */
553typeSpecifier
554 : VOID | CHAR | SHORT | INT | LONG | FLOAT | DOUBLE
555 | SIGNED | UNSIGNED | BOOL | COMPLEX
556 | PROC
557 | atomicTypeSpecifier
558 | structOrUnionSpecifier
559 | enumSpecifier
560 | typedefName
561 ;
562
563/* 6.7.2.1
564 * Root: STRUCT or UNION
565 * Child 0: IDENTIFIER (the tag) or ABSENT
566 * Child 1: structDeclarationList or ABSENT
567 */
568structOrUnionSpecifier
569 : structOrUnion
570 ( IDENTIFIER LCURLY structDeclarationList RCURLY
571 -> ^(structOrUnion IDENTIFIER structDeclarationList RCURLY)
572 | LCURLY structDeclarationList RCURLY
573 -> ^(structOrUnion ABSENT structDeclarationList RCURLY)
574 | IDENTIFIER
575 -> ^(structOrUnion IDENTIFIER ABSENT)
576 )
577 ;
578
579/* 6.7.2.1 */
580structOrUnion
581 : STRUCT | UNION
582 ;
583
584/* 6.7.2.1
585 * Root: STRUCT_DECLARATION_LIST
586 * Children: structDeclaration
587 */
588structDeclarationList
589 : structDeclaration+
590 -> ^(STRUCT_DECLARATION_LIST structDeclaration+)
591 ;
592
593/* 6.7.2.1
594 * Two possible trees:
595 *
596 * Root: STRUCT_DECLARATION
597 * Child 0: specifierQualifierList
598 * Child 1: structDeclaratorList or ABSENT
599 *
600 * or
601 *
602 * staticAssertDeclaration (root: STATICASSERT)
603 */
604structDeclaration
605scope DeclarationScope;
606@init {
607 $DeclarationScope::isTypedef = false;
608}
609 : s=specifierQualifierList
610 ( -> ^(STRUCT_DECLARATION $s ABSENT)
611 | structDeclaratorList
612 -> ^(STRUCT_DECLARATION $s structDeclaratorList)
613 )
614 SEMI
615 | staticAssertDeclaration
616 ;
617
618/* 6.7.2.1
619 * Root: SPECIFIER_QUALIFIER_LIST
620 * Children: typeSpecifierOrQualifier
621 */
622specifierQualifierList
623 : typeSpecifierOrQualifier+
624 -> ^(SPECIFIER_QUALIFIER_LIST typeSpecifierOrQualifier+)
625 ;
626
627/* 6.7.2.1
628 * Root: STRUCT_DECLARATOR_LIST
629 * Children: structDeclarator (at least 1)
630 */
631structDeclaratorList
632 : s+=structDeclarator (COMMA s+=structDeclarator)*
633 -> ^(STRUCT_DECLARATOR_LIST $s+)
634 ;
635
636/* 6.7.2.1
637 * Root: STRUCT_DECLARATOR
638 * Child 0: declarator or ABSENT
639 * Child 1: constantExpression or ABSENT
640 */
641structDeclarator
642 : declarator
643 ( -> ^(STRUCT_DECLARATOR declarator ABSENT)
644 | COLON constantExpression
645 -> ^(STRUCT_DECLARATOR declarator constantExpression)
646 )
647 | COLON constantExpression
648 -> ^(STRUCT_DECLARATOR ABSENT constantExpression)
649 ;
650
651/* 6.7.2.2
652 * Root: ENUM
653 * Child 0: IDENTIFIER (tag) or ABSENT
654 * Child 1: enumeratorList
655 */
656enumSpecifier
657 : ENUM
658 ( IDENTIFIER
659 -> ^(ENUM IDENTIFIER ABSENT)
660 | IDENTIFIER LCURLY enumeratorList COMMA? RCURLY
661 -> ^(ENUM IDENTIFIER enumeratorList)
662 | LCURLY enumeratorList COMMA? RCURLY
663 -> ^(ENUM ABSENT enumeratorList)
664 )
665 ;
666
667/* 6.7.2.2
668 * Root: ENUMERATOR_LIST
669 * Children: enumerator
670 */
671enumeratorList
672 : enumerator (COMMA enumerator)*
673 -> ^(ENUMERATOR_LIST enumerator+)
674 ;
675
676/* 6.7.2.2
677 * Root: ENUMERATOR
678 * Child 0: IDENTIFIER
679 * Child 1: constantExpression or ABSENT
680 */
681enumerator
682 : IDENTIFIER
683 {
684 $Symbols::enumerationConstants.add($IDENTIFIER.text);
685 // System.err.println("define enum constant "+$IDENTIFIER.text);
686 }
687 ( -> ^(ENUMERATOR IDENTIFIER ABSENT)
688 | (ASSIGN constantExpression)
689 -> ^(ENUMERATOR IDENTIFIER constantExpression)
690 )
691 ;
692
693/* 6.7.2.4 */
694atomicTypeSpecifier
695 : ATOMIC LPAREN typeName RPAREN
696 -> ^(ATOMIC typeName)
697 ;
698
699/* 6.7.3 */
700typeQualifier
701 : CONST | RESTRICT | VOLATILE | ATOMIC
702 | INPUT | OUTPUT
703 ;
704
705/* 6.7.4 */
706functionSpecifier
707 : INLINE | NORETURN
708 ;
709
710/* 6.7.5
711 * Root: ALIGNAS
712 * Child 0: TYPE or EXPR
713 * Child 1: typeName (if Child 0 is TYPE) or constantExpression
714 * (if Child 0 is EXPR)
715 */
716alignmentSpecifier
717 : ALIGNAS LPAREN
718 ( typeName RPAREN
719 -> ^(ALIGNAS TYPE typeName)
720 | constantExpression RPAREN
721 -> ^(ALIGNAS EXPR constantExpression)
722 )
723 ;
724
725/* 6.7.6
726 * Root: DECLARATOR
727 * Child 0: pointer or ABSENT
728 * Child 1: directDeclarator
729 */
730declarator
731 : d=directDeclarator
732 -> ^(DECLARATOR ABSENT $d)
733 | pointer d=directDeclarator
734 -> ^(DECLARATOR pointer $d)
735 ;
736
737/* 6.7.6
738 * Root: DIRECT_DECLARATOR
739 * Child 0: directDeclaratorPrefix
740 * Children 1..: list of directDeclaratorSuffix (may be empty)
741 */
742directDeclarator
743 : p=directDeclaratorPrefix
744 ( -> ^(DIRECT_DECLARATOR $p)
745 | s+=directDeclaratorSuffix+ ->^(DIRECT_DECLARATOR $p $s+)
746 )
747 ;
748
749/*
750 * Tree: either an IDENTIFIER or a declarator.
751 */
752directDeclaratorPrefix
753 : IDENTIFIER
754 {
755 if ($DeclarationScope::isTypedef) {
756 $Symbols::types.add($IDENTIFIER.text);
757 //System.err.println("define type "+$IDENTIFIER.text);
758 }
759 }
760 | LPAREN! declarator RPAREN!
761 ;
762
763
764directDeclaratorSuffix
765 : directDeclaratorArraySuffix
766 | directDeclaratorFunctionSuffix
767 ;
768
769/*
770 * Root: ARRAY_SUFFIX
771 * child 0: LSQUARE (for source information)
772 * child 1: STATIC or ABSENT
773 * child 2: TYPE_QUALIFIER_LIST
774 * child 3: expression (array extent),
775 * "*" (unspecified variable length), or ABSENT
776 * child 4: RSQUARE (for source information)
777 */
778directDeclaratorArraySuffix
779 : LSQUARE
780 ( typeQualifierList_opt assignmentExpression_opt RSQUARE
781 -> ^(ARRAY_SUFFIX LSQUARE ABSENT typeQualifierList_opt
782 assignmentExpression_opt RSQUARE)
783 | STATIC typeQualifierList_opt assignmentExpression RSQUARE
784 -> ^(ARRAY_SUFFIX LSQUARE STATIC typeQualifierList_opt
785 assignmentExpression RSQUARE)
786 | typeQualifierList STATIC assignmentExpression RSQUARE
787 -> ^(ARRAY_SUFFIX LSQUARE STATIC typeQualifierList
788 assignmentExpression RSQUARE)
789 | typeQualifierList_opt STAR RSQUARE
790 -> ^(ARRAY_SUFFIX LSQUARE ABSENT typeQualifierList_opt
791 STAR RSQUARE)
792 )
793 ;
794
795/*
796 * Root: FUNCTION_SUFFIX
797 * child 0: LPAREN (for source information)
798 * child 1: either parameterTypeList or identifierList or ABSENT
799 * child 2: RPAREN (for source information)
800 */
801directDeclaratorFunctionSuffix
802 : LPAREN
803 ( parameterTypeList RPAREN
804 -> ^(FUNCTION_SUFFIX LPAREN parameterTypeList RPAREN)
805 | identifierList RPAREN
806 -> ^(FUNCTION_SUFFIX LPAREN identifierList RPAREN)
807 | RPAREN -> ^(FUNCTION_SUFFIX LPAREN ABSENT RPAREN)
808 )
809 ;
810
811/*
812 * Root: TYPE_QUALIFIER_LIST
813 * Children: typeQualifier
814 */
815typeQualifierList_opt
816 : typeQualifier* -> ^(TYPE_QUALIFIER_LIST typeQualifier*)
817 ;
818
819/*
820 * Tree: assignmentExpression or ABSENT
821 */
822assignmentExpression_opt
823 : -> ABSENT
824 | assignmentExpression
825 ;
826
827/* 6.7.6
828 * Root: POINTER
829 * chilren: STAR
830 */
831pointer
832 : pointer_part+ -> ^(POINTER pointer_part+)
833 ;
834
835/*
836 * Root: STAR
837 * child 0: TYPE_QUALIFIER_LIST
838 */
839pointer_part
840 : STAR typeQualifierList_opt -> ^(STAR typeQualifierList_opt)
841 ;
842
843/* 6.7.6
844 * Root: TYPE_QUALIFIER_LIST
845 * children: typeQualifier
846 */
847typeQualifierList
848 : typeQualifier+ -> ^(TYPE_QUALIFIER_LIST typeQualifier+)
849 ;
850
851/* 6.7.6
852 * Root: PARAMETER_TYPE_LIST
853 * child 0: parameterList (at least 1 parameter declaration)
854 * child 1: ELLIPSIS or ABSENT
855 *
856 * If the parameterTypeList occurs in a function prototype
857 * (that is not part of a function definition), it defines
858 * a new scope (a "function prototype scope"). If it occurs
859 * in a function definition, it does not define a new scope.
860 */
861
862parameterTypeList
863 : {$Symbols::isFunctionDefinition}? parameterTypeListWithoutScope
864 | parameterTypeListWithScope
865 ;
866
867parameterTypeListWithScope
868scope Symbols;
869@init {
870 $Symbols::types = new HashSet<String>();
871 $Symbols::enumerationConstants = new HashSet<String>();
872 $Symbols::isFunctionDefinition = false;
873}
874 : parameterTypeListWithoutScope
875 ;
876
877parameterTypeListWithoutScope
878 : parameterList
879 ( -> ^(PARAMETER_TYPE_LIST parameterList ABSENT)
880 | COMMA ELLIPSIS
881 -> ^(PARAMETER_TYPE_LIST parameterList ELLIPSIS)
882 )
883 ;
884
885/* 6.7.6
886 * Root: PARAMETER_LIST
887 * children: parameterDeclaration
888 */
889parameterList
890 : parameterDeclaration (COMMA parameterDeclaration)*
891 -> ^(PARAMETER_LIST parameterDeclaration+)
892 ;
893
894/* 6.7.6
895 * Root: PARAMETER_DECLARATION
896 * Child 0: declarationSpecifiers
897 * Child 1: declarator, or abstractDeclarator, or ABSENT
898 */
899parameterDeclaration
900scope DeclarationScope;
901@init {
902 $DeclarationScope::isTypedef = false;
903}
904 : declarationSpecifiers
905 ( -> ^(PARAMETER_DECLARATION declarationSpecifiers ABSENT)
906 | declaratorOrAbstractDeclarator
907 -> ^(PARAMETER_DECLARATION
908 declarationSpecifiers declaratorOrAbstractDeclarator)
909 )
910 ;
911
912
913// this has non-LL* decision due to recursive rule invocations
914// reachable from alts 1,2... E.g., both can start with pointer.
915
916declaratorOrAbstractDeclarator
917 : (declarator)=> declarator
918 | abstractDeclarator
919 ;
920
921
922/* 6.7.6
923 * Root: IDENTIFIER_LIST
924 * children: IDENTIFIER (at least 1)
925 */
926identifierList
927 : IDENTIFIER ( COMMA IDENTIFIER )*
928 -> ^(IDENTIFIER_LIST IDENTIFIER+)
929 ;
930
931/* 6.7.6. This is how a type is described without attaching
932 * it to an identifier.
933 * Root: TYPE_NAME
934 * child 0: specifierQualifierList
935 * child 1: abstractDeclarator or ABSENT
936 */
937typeName
938 : specifierQualifierList
939 ( -> ^(TYPE_NAME specifierQualifierList ABSENT)
940 | abstractDeclarator
941 -> ^(TYPE_NAME specifierQualifierList abstractDeclarator)
942 )
943 ;
944
945/* 6.7.7. Abstract declarators are like declarators without
946 * the IDENTIFIER.
947 *
948 * Root: ABSTRACT_DECLARATOR
949 * Child 0. pointer (may be ABSENT). Some number of *s with possible
950 * type qualifiers.
951 * Child 1. directAbstractDeclarator (may be ABSENT).
952 */
953abstractDeclarator
954 : pointer
955 -> ^(ABSTRACT_DECLARATOR pointer ABSENT)
956 | directAbstractDeclarator
957 -> ^(ABSTRACT_DECLARATOR ABSENT directAbstractDeclarator)
958 | pointer directAbstractDeclarator
959 -> ^(ABSTRACT_DECLARATOR pointer directAbstractDeclarator)
960 ;
961
962/* 6.7.7
963 *
964 * Root: DIRECT_ABSTRACT_DECLARATOR
965 * Child 0. abstract declarator or ABSENT.
966 * Children 1..: any number of direct abstract declarator suffixes
967 *
968 * Note that the difference between this and a directDeclarator
969 * is that Child 0 of a direct declarator would be either
970 * an IDENTIFIER or a declarator, but never ABSENT.
971 */
972directAbstractDeclarator
973 : LPAREN abstractDeclarator RPAREN directAbstractDeclaratorSuffix*
974 -> ^(DIRECT_ABSTRACT_DECLARATOR abstractDeclarator
975 directAbstractDeclaratorSuffix*)
976 | directAbstractDeclaratorSuffix+
977 -> ^(DIRECT_ABSTRACT_DECLARATOR ABSENT directAbstractDeclaratorSuffix+)
978 ;
979
980
981/* 6.7.8
982 * Root: TYPEDEF_NAME
983 * Child 0: IDENTIFIER
984 *
985 * Ambiguity: example:
986 * typedef int foo;
987 * typedef int foo;
988 *
989 * This is perfectly legal: you can define a typedef twice
990 * as long as both definitions are equivalent. However,
991 * the first definition causes foo to be entered into the type name
992 * table, so when parsing the second definition, foo is
993 * interpreted as a typedefName (a type specifier), and the
994 * declaration would have empty declarator. This is not
995 * what you want, so you have to forbid it somehow. I do this
996 * by requiring that if you are "in" a typedef, a typedef name
997 * cannot be immediately followed by a semicolon. This is sound
998 * because the C11 Standard requires at least one declarator
999 * to be present in a typedef.
1000 */
1001typedefName
1002 : {isTypeName(input.LT(1).getText())}? IDENTIFIER
1003 -> ^(TYPEDEF_NAME IDENTIFIER)
1004 ;
1005
1006/* 6.7.7
1007 * Two possibilities:
1008 *
1009 * Root: ARRAY_SUFFIX
1010 * Child 0: STATIC or ABSENT
1011 * Child 1: typeQualifierList or ABSENT
1012 * Child 2: expression or STAR or ABSENT
1013 *
1014 * Root: FUNCTION_SUFFIX
1015 * Child 0: parameterTypeList or ABSENT
1016 */
1017directAbstractDeclaratorSuffix
1018 : LSQUARE
1019 ( typeQualifierList_opt assignmentExpression_opt RSQUARE
1020 -> ^(ARRAY_SUFFIX ABSENT typeQualifierList_opt
1021 assignmentExpression_opt)
1022 | STATIC typeQualifierList_opt assignmentExpression RSQUARE
1023 -> ^(ARRAY_SUFFIX STATIC typeQualifierList_opt
1024 assignmentExpression)
1025 | typeQualifierList STATIC assignmentExpression RSQUARE
1026 -> ^(ARRAY_SUFFIX STATIC typeQualifierList assignmentExpression)
1027 | STAR RSQUARE
1028 -> ^(ARRAY_SUFFIX ABSENT ABSENT STAR)
1029 )
1030 | LPAREN
1031 ( parameterTypeList RPAREN
1032 -> ^(FUNCTION_SUFFIX parameterTypeList)
1033 | RPAREN
1034 -> ^(FUNCTION_SUFFIX ABSENT)
1035 )
1036 ;
1037
1038/* 6.7.9 */
1039initializer
1040 : assignmentExpression -> ^(SCALAR_INITIALIZER assignmentExpression)
1041 | LCURLY initializerList
1042 ( RCURLY
1043 | COMMA RCURLY
1044 )
1045 -> initializerList
1046 ;
1047
1048/* 6.7.9 */
1049initializerList
1050 : designatedInitializer (COMMA designatedInitializer)*
1051 -> ^(INITIALIZER_LIST designatedInitializer+)
1052 ;
1053
1054designatedInitializer
1055 : initializer
1056 -> ^(DESIGNATED_INITIALIZER ABSENT initializer)
1057 | designation initializer
1058 -> ^(DESIGNATED_INITIALIZER designation initializer)
1059 ;
1060
1061/* 6.7.9 */
1062designation
1063 : designatorList ASSIGN -> ^(DESIGNATION designatorList)
1064 ;
1065
1066/* 6.7.9 */
1067designatorList
1068 : designator+
1069 ;
1070
1071/* 6.7.9 */
1072designator
1073 : LSQUARE constantExpression RSQUARE
1074 -> ^(ARRAY_ELEMENT_DESIGNATOR constantExpression)
1075 | DOT IDENTIFIER
1076 -> ^(FIELD_DESIGNATOR IDENTIFIER)
1077 ;
1078
1079/* 6.7.10 */
1080staticAssertDeclaration
1081 : STATICASSERT LPAREN constantExpression COMMA STRING_LITERAL
1082 RPAREN SEMI
1083 -> ^(STATICASSERT constantExpression STRING_LITERAL)
1084 ;
1085
1086
1087/* ***** A.2.3: Statements ***** */
1088
1089/* 6.8 */
1090statement
1091 : labeledStatement
1092 | compoundStatement
1093 | expressionStatement
1094 | selectionStatement
1095 | iterationStatement
1096 | jumpStatement
1097 | pragma
1098 | assertStatement
1099 | assumeStatement
1100 | waitStatement
1101 | whenStatement
1102 | chooseStatement
1103 ;
1104
1105statementWithScope
1106scope Symbols;
1107@init {
1108 $Symbols::types = new HashSet<String>();
1109 $Symbols::enumerationConstants = new HashSet<String>();
1110 $Symbols::isFunctionDefinition = false;
1111}
1112 : statement
1113 ;
1114
1115/* 6.8.1
1116 * Three possible trees:
1117 *
1118 * Root: IDENTIFIER_LABELED_STATEMENT
1119 * Child 0: IDENTIFIER
1120 * Child 1: statement
1121 *
1122 * Root: CASE_LABELED_STATEMENT
1123 * Child 0: CASE
1124 * Child 1: constantExpression
1125 * Child 2: statement
1126 *
1127 * Root: DEFAULT_LABELED_STATEMENT
1128 * Child 0: DEFAULT
1129 * Child 1: statement
1130 */
1131labeledStatement
1132 : IDENTIFIER COLON statement
1133 -> ^(IDENTIFIER_LABELED_STATEMENT IDENTIFIER statement)
1134 | CASE constantExpression COLON statement
1135 -> ^(CASE_LABELED_STATEMENT CASE constantExpression statement)
1136 | DEFAULT COLON statement
1137 -> ^(DEFAULT_LABELED_STATEMENT DEFAULT statement)
1138 ;
1139
1140/* 6.8.2
1141 * Root: BLOCK
1142 * Child 0: LCURLY (for source information)
1143 * Child 1: blockItemList or ABSENT
1144 * Child 2: RCURLY (for source information)
1145 */
1146compoundStatement
1147scope Symbols;
1148@init {
1149 $Symbols::types = new HashSet<String>();
1150 $Symbols::enumerationConstants = new HashSet<String>();
1151 $Symbols::isFunctionDefinition = false;
1152}
1153 : LCURLY
1154 ( RCURLY
1155 -> ^(COMPOUND_STATEMENT LCURLY ABSENT RCURLY)
1156 | blockItemList RCURLY
1157 -> ^(COMPOUND_STATEMENT LCURLY blockItemList RCURLY)
1158 )
1159 ;
1160
1161/* 6.8.2 */
1162blockItemList
1163 : blockItem+ -> ^(BLOCK_ITEM_LIST blockItem+)
1164 ;
1165
1166/* 6.8.2 */
1167blockItem
1168 : (declarationSpecifiers declarator declarationList_opt LCURLY)=>
1169 functionDefinition
1170 | declaration
1171 | statement
1172 ;
1173
1174/* 6.8.3
1175 * Root: EXPRESSION_STATEMENT
1176 * Child 0: expression or ABSENT
1177 * Child 1: SEMI (for source information)
1178 */
1179expressionStatement
1180 : expression SEMI -> ^(EXPRESSION_STATEMENT expression SEMI)
1181 | SEMI -> ^(EXPRESSION_STATEMENT ABSENT SEMI)
1182 ;
1183
1184/* 6.8.4
1185 * Two possible trees:
1186 *
1187 * Root: IF
1188 * Child 0: expression
1189 * Child 1: statement (true branch)
1190 * Child 2: statement or ABSENT (false branch)
1191 *
1192 * Root: SWITCH
1193 * Child 0: expression
1194 * Child 1: statement
1195 */
1196selectionStatement
1197scope Symbols;
1198@init {
1199 $Symbols::types = new HashSet<String>();
1200 $Symbols::enumerationConstants = new HashSet<String>();
1201 $Symbols::isFunctionDefinition = false;
1202}
1203 : IF LPAREN expression RPAREN s1=statementWithScope
1204 ( (ELSE)=> ELSE s2=statementWithScope
1205 -> ^(IF expression $s1 $s2)
1206 | -> ^(IF expression $s1 ABSENT)
1207 )
1208 | SWITCH LPAREN expression RPAREN s=statementWithScope
1209 -> ^(SWITCH expression $s)
1210 ;
1211
1212/* 6.8.5
1213 * Three possible trees:
1214 *
1215 * Root: WHILE
1216 * Child 0: expression
1217 * Child 1: statement
1218 *
1219 * Root: DO
1220 * Child 0: statement
1221 * Child 1: expression
1222 *
1223 * Root: FOR
1224 * Child 0: clause-1: declaration, expression, or ABSENT
1225 * (for loop initializer)
1226 * Child 1: expression or ABSENT (condition)
1227 * Child 2: expression or ABSENT (incrementer)
1228 * Child 3: statement (body)
1229 *
1230 */
1231iterationStatement
1232scope Symbols;
1233@init {
1234 $Symbols::types = new HashSet<String>();
1235 $Symbols::enumerationConstants = new HashSet<String>();
1236 $Symbols::isFunctionDefinition = false;
1237}
1238 : WHILE LPAREN expression RPAREN invariant_opt
1239 s=statementWithScope
1240 -> ^(WHILE expression $s invariant_opt)
1241 | DO s=statementWithScope WHILE LPAREN expression RPAREN
1242 invariant_opt SEMI
1243 -> ^(DO $s expression invariant_opt)
1244 | FOR LPAREN
1245 ( d=declaration e1=expression_opt SEMI e2=expression_opt
1246 RPAREN i=invariant_opt s=statementWithScope
1247 -> ^(FOR $d $e1 $e2 $s $i)
1248 | e0=expression_opt SEMI e1=expression_opt SEMI
1249 e2=expression_opt RPAREN s=statementWithScope
1250 -> ^(FOR $e0 $e1 $e2 $s $i)
1251 )
1252 ;
1253
1254expression_opt
1255 : expression
1256 | -> ABSENT
1257 ;
1258
1259invariant_opt
1260 : -> ABSENT
1261 | INVARIANT LPAREN expression RPAREN
1262 -> ^(INVARIANT expression)
1263 ;
1264
1265
1266/* 6.8.6
1267 * Four possible trees:
1268 *
1269 * Root: GOTO
1270 * Child 0: IDENTIFIER
1271 * Child 1: SEMI (for source information)
1272 *
1273 * Root: CONTINUE
1274 * Child 0: SEMI (for source information)
1275 *
1276 * Root: BREAK
1277 * Child 0: SEMI (for source information)
1278 *
1279 * Root: RETURN
1280 * Child 0: expression or ABSENT
1281 * Child 1: SEMI (for source information)
1282 */
1283jumpStatement
1284 : GOTO IDENTIFIER SEMI -> ^(GOTO IDENTIFIER SEMI)
1285 | CONTINUE SEMI -> ^(CONTINUE SEMI)
1286 | BREAK SEMI -> ^(BREAK SEMI)
1287 | RETURN expression_opt SEMI -> ^(RETURN expression_opt SEMI)
1288 ;
1289
1290/*
1291 * Root: PRAGMA
1292 * child 0: IDENTIFIER (first token following # pragma)
1293 * child 1: TOKEN_LIST (chilren are list of tokens following identifier)
1294 * child 2: NEWLINE (character which ends the pragma)
1295 */
1296pragma : PRAGMA IDENTIFIER pragmaBody NEWLINE
1297 -> ^(PRAGMA IDENTIFIER ^(TOKEN_LIST pragmaBody) NEWLINE)
1298 ;
1299
1300pragmaBody
1301 : (~ NEWLINE)*
1302 ;
1303
1304assertStatement
1305 : ASSERT expression SEMI -> ^(ASSERT expression)
1306 ;
1307
1308assumeStatement
1309 : ASSUME expression SEMI -> ^(ASSUME expression)
1310 ;
1311
1312waitStatement
1313 : WAIT expression SEMI -> ^(WAIT expression)
1314 ;
1315
1316whenStatement
1317 : WHEN LPAREN expression RPAREN statement
1318 -> ^(WHEN expression statement)
1319 ;
1320
1321chooseStatement
1322 : CHOOSE LCURLY statement+ RCURLY
1323 -> ^(CHOOSE statement+)
1324 ;
1325
1326/* ***** A.2.4: External Definitions ***** */
1327
1328/* 6.9
1329 * Root: TRANSLATION_UNIT
1330 * Children: externalDeclaration
1331 */
1332translationUnit
1333scope Symbols; // the global scope
1334scope DeclarationScope; // just to have an outermost one with isTypedef false
1335@init {
1336 $Symbols::types = new HashSet<String>();
1337 $Symbols::enumerationConstants = new HashSet<String>();
1338 $Symbols::isFunctionDefinition = false;
1339 $DeclarationScope::isTypedef = false;
1340}
1341 : externalDeclaration* EOF
1342 -> ^(TRANSLATION_UNIT externalDeclaration*)
1343 ;
1344
1345/* 6.9
1346 * Need to look ahead to distinguish function definition from
1347 * a declaration. As soon as you see the "{", you know you
1348 * are in a function definition.
1349 */
1350externalDeclaration
1351 : (declarationSpecifiers declarator
1352 contract_opt declarationList_opt LCURLY)=>
1353 functionDefinition
1354 | declaration
1355 | pragma
1356 ;
1357
1358/* 6.9.1 */
1359functionDefinition
1360scope Symbols; // "function scope"
1361@init {
1362 $Symbols::types = new HashSet<String>();
1363 $Symbols::enumerationConstants = new HashSet<String>();
1364 $Symbols::isFunctionDefinition = true;
1365}
1366 : declarationSpecifiers declarator contract_opt
1367 declarationList_opt compoundStatement
1368 -> ^(FUNCTION_DEFINITION declarationSpecifiers declarator
1369 declarationList_opt compoundStatement contract_opt)
1370 ;
1371
1372
1373/* 6.9.1
1374 * Root: DECLARATION_LIST
1375 * Children: declaration (any number)
1376 */
1377declarationList_opt
1378 : declaration* -> ^(DECLARATION_LIST declaration*)
1379 ;
1380
1381contractItem
1382 : REQUIRES expression SEMI -> ^(REQUIRES expression)
1383 | ENSURES expression SEMI -> ^(ENSURES expression)
1384 ;
1385
1386contract_opt
1387 : contractItem* -> ^(CONTRACT contractItem*)
1388 ;
Note: See TracBrowser for help on using the repository browser.