source: CIVL/grammar/CivlCParser.g@ 9ae277d

1.23 2.0 acw/focus-triggers main test-branch
Last change on this file since 9ae277d was 34760dc, checked in by Stephen Siegel <siegel@…>, 14 years ago

Debugged parser, added examples, for CIVLC.

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

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