source: src/Parser/cfa.y @ e15b0a0a

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decaygc_noraiijacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newstringwith_gc
Last change on this file since e15b0a0a was e15b0a0a, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

allow arbitrary ordering of storage/type qualifiers for new function decl/defn

  • Property mode set to 100644
File size: 101.5 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// cfa.y --
8//
9// Author           : Peter A. Buhr
10// Created On       : Sat Sep  1 20:22:55 2001
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Tue May 26 22:38:42 2015
13// Update Count     : 995
14//
15
16// This grammar is based on the ANSI99/11 C grammar, specifically parts of EXPRESSION and STATEMENTS, and on
17// the C grammar by James A. Roskind, specifically parts of DECLARATIONS and EXTERNAL DEFINITIONS.  While
18// parts have been copied, important changes have been made in all sections; these changes are sufficient to
19// constitute a new grammar.  In particular, this grammar attempts to be more syntactically precise, i.e., it
20// parses less incorrect language syntax that must be subsequently rejected by semantic checks.  Nevertheless,
21// there are still several semantic checks required and many are noted in the grammar. Finally, the grammar is
22// extended with GCC and CFA language extensions.
23
24// Acknowledgments to Richard Bilson, Glen Ditchfield, and Rodolfo Gabriel Esteves who all helped when I got
25// stuck with the grammar.
26
27// The root language for this grammar is ANSI99/11 C. All of ANSI99/11 is parsed, except for:
28//
29// 1. designation with '=' (use ':' instead)
30//
31// Most of the syntactic extensions from ANSI90 to ANSI11 C are marked with the comment "C99/C11". This
32// grammar also has two levels of extensions. The first extensions cover most of the GCC C extensions, except for:
33//
34// 1. nested functions
35// 2. generalized lvalues
36// 3. designation with and without '=' (use ':' instead)
37// 4. attributes not allowed in parenthesis of declarator
38//
39// All of the syntactic extensions for GCC C are marked with the comment "GCC". The second extensions are for
40// Cforall (CFA), which fixes several of C's outstanding problems and extends C with many modern language
41// concepts. All of the syntactic extensions for CFA C are marked with the comment "CFA". As noted above,
42// there is one unreconcileable parsing problem between C99 and CFA with respect to designators; this is
43// discussed in detail before the "designation" grammar rule.
44
45%{
46#define YYDEBUG_LEXER_TEXT (yylval)                                             // lexer loads this up each time
47#define YYDEBUG 1                                                                               // get the pretty debugging code to compile
48
49#undef __GNUC_MINOR__
50
51#include <cstdio>
52#include <stack>
53#include "TypedefTable.h"
54#include "lex.h"
55#include "ParseNode.h"
56#include "LinkageSpec.h"
57
58DeclarationNode *theTree = 0;                                                   // the resulting parse tree
59LinkageSpec::Type linkage = LinkageSpec::Cforall;
60std::stack< LinkageSpec::Type > linkageStack;
61TypedefTable typedefTable;
62%}
63
64//************************* TERMINAL TOKENS ********************************
65
66// keywords
67%token TYPEDEF
68%token AUTO EXTERN REGISTER STATIC
69%token INLINE                                                                                   // C99
70%token FORTRAN                                                                                  // C99, extension ISO/IEC 9899:1999 Section J.5.9(1)
71%token CONST VOLATILE
72%token RESTRICT                                                                                 // C99
73%token FORALL LVALUE                                                                    // CFA
74%token VOID CHAR SHORT INT LONG FLOAT DOUBLE SIGNED UNSIGNED
75%token BOOL COMPLEX IMAGINARY                                                   // C99
76%token TYPEOF LABEL                                                                             // GCC
77%token ENUM STRUCT UNION
78%token TYPE FTYPE DTYPE CONTEXT                                                 // CFA
79%token SIZEOF
80%token ATTRIBUTE EXTENSION                                                              // GCC
81%token IF ELSE SWITCH CASE DEFAULT DO WHILE FOR BREAK CONTINUE GOTO RETURN
82%token CHOOSE FALLTHRU TRY CATCH FINALLY THROW                  // CFA
83%token ASM                                                                                              // C99, extension ISO/IEC 9899:1999 Section J.5.10(1)
84%token ALIGNAS ALIGNOF ATOMIC GENERIC NORETURN STATICASSERT THREADLOCAL // C11
85
86// names and constants: lexer differentiates between identifier and typedef names
87%token<tok> IDENTIFIER                  QUOTED_IDENTIFIER               TYPEDEFname                             TYPEGENname
88%token<tok> ATTR_IDENTIFIER             ATTR_TYPEDEFname                ATTR_TYPEGENname
89%token<tok> INTEGERconstant             FLOATINGconstant                CHARACTERconstant               STRINGliteral
90%token<tok> ZERO                                ONE                                             // CFA
91
92// multi-character operators
93%token ARROW                                                                                    // ->
94%token ICR DECR                                                                                 // ++   --
95%token LS RS                                                                                    // <<   >>
96%token LE GE EQ NE                                                                              // <=   >=      ==      !=
97%token ANDAND OROR                                                                              // &&   ||
98%token ELLIPSIS                                                                                 // ...
99
100%token MULTassign       DIVassign       MODassign                               // *=   /=      %=/
101%token PLUSassign       MINUSassign                                                     // +=   -=
102%token LSassign         RSassign                                                        // <<=  >>=
103%token ANDassign        ERassign        ORassign                                // &=   ^=      |=
104
105// Types declaration
106%union
107{
108        Token tok;
109        ParseNode *pn;
110        ExpressionNode *en;
111        DeclarationNode *decl;
112        DeclarationNode::TyCon aggKey;
113        DeclarationNode::TypeClass tclass;
114        StatementNode *sn;
115        ConstantNode *constant;
116        InitializerNode *in;
117}
118
119%type<tok> zero_one  identifier  no_attr_identifier  no_01_identifier
120%type<tok> identifier_or_typedef_name  no_attr_identifier_or_typedef_name  no_01_identifier_or_typedef_name
121%type<constant> string_literal_list
122
123// expressions
124%type<constant> constant
125%type<en> tuple                                                 tuple_expression_list
126%type<en> unary_operator                                assignment_operator
127%type<en> primary_expression                    postfix_expression                      unary_expression
128%type<en> cast_expression                               multiplicative_expression       additive_expression                     shift_expression
129%type<en> relational_expression                 equality_expression                     AND_expression                          exclusive_OR_expression
130%type<en> inclusive_OR_expression               logical_AND_expression          logical_OR_expression           conditional_expression
131%type<en> constant_expression                   assignment_expression           assignment_expression_opt
132%type<en> comma_expression                              comma_expression_opt
133%type<en> argument_expression_list              argument_expression                     for_control_expression          assignment_opt
134%type<en> subrange
135
136// statements
137%type<sn> labeled_statement                             compound_statement                      expression_statement            selection_statement
138%type<sn> iteration_statement                   jump_statement                          exception_statement                     asm_statement
139%type<sn> fall_through_opt                              fall_through
140%type<sn> statement                                             statement_list
141%type<sn> block_item_list                               block_item
142%type<sn> case_clause
143%type<en> case_value                                    case_value_list
144%type<sn> case_label                                    case_label_list
145%type<sn> switch_clause_list_opt                switch_clause_list                      choose_clause_list_opt          choose_clause_list
146%type<pn> handler_list                                  handler_clause                          finally_clause
147
148// declarations
149%type<decl> abstract_array abstract_declarator abstract_function abstract_parameter_array
150%type<decl> abstract_parameter_declaration abstract_parameter_declarator abstract_parameter_function
151%type<decl> abstract_parameter_ptr abstract_ptr
152
153%type<aggKey> aggregate_key
154%type<decl>  aggregate_name
155
156%type<decl> array_dimension array_parameter_1st_dimension array_parameter_dimension multi_array_dimension
157
158%type<decl> assertion assertion_list_opt
159
160%type<en>   bit_subrange_size_opt bit_subrange_size
161
162%type<decl> basic_declaration_specifier basic_type_name basic_type_specifier direct_type_name indirect_type_name
163
164%type<decl> context_declaration context_declaration_list context_declaring_list context_specifier
165
166%type<decl> declaration declaration_list declaration_list_opt declaration_qualifier_list
167%type<decl> declaration_specifier declarator declaring_list
168
169%type<decl> elaborated_type_name
170
171%type<decl> enumerator_list enum_name
172%type<en> enumerator_value_opt
173
174%type<decl> exception_declaration external_definition external_definition_list external_definition_list_opt
175
176%type<decl> field_declaration field_declaration_list field_declarator field_declaring_list
177%type<en> field field_list
178
179%type<decl> function_array function_declarator function_definition function_no_ptr function_ptr
180
181%type<decl> identifier_parameter_array identifier_parameter_declarator identifier_parameter_function
182%type<decl> identifier_parameter_ptr identifier_list
183
184%type<decl> new_abstract_array new_abstract_declarator_no_tuple new_abstract_declarator_tuple
185%type<decl> new_abstract_function new_abstract_parameter_declaration new_abstract_parameter_list
186%type<decl> new_abstract_ptr new_abstract_tuple
187
188%type<decl> new_array_parameter_1st_dimension
189
190%type<decl> new_context_declaring_list new_declaration new_field_declaring_list
191%type<decl> new_function_declaration new_function_return new_function_specifier
192
193%type<decl> new_identifier_parameter_array new_identifier_parameter_declarator_no_tuple
194%type<decl> new_identifier_parameter_declarator_tuple new_identifier_parameter_ptr
195
196%type<decl> new_parameter_declaration new_parameter_list new_parameter_type_list new_parameter_type_list_opt
197
198%type<decl> new_typedef_declaration new_variable_declaration new_variable_specifier
199
200%type<decl> old_declaration old_declaration_list old_declaration_list_opt old_function_array
201%type<decl> old_function_declarator old_function_no_ptr old_function_ptr
202
203%type<decl> parameter_declaration parameter_list parameter_type_list
204%type<decl> parameter_type_list_opt
205
206%type<decl> paren_identifier paren_typedef
207
208%type<decl> storage_class storage_class_name storage_class_list
209
210%type<decl> sue_declaration_specifier sue_type_specifier
211
212%type<tclass> type_class
213%type<decl> type_declarator type_declarator_name type_declaring_list
214
215%type<decl> typedef typedef_array typedef_declaration typedef_declaration_specifier typedef_expression
216%type<decl> typedef_function typedef_parameter_array typedef_parameter_function typedef_parameter_ptr
217%type<decl> typedef_parameter_redeclarator typedef_ptr typedef_redeclarator typedef_type_specifier
218%type<decl> typegen_declaration_specifier typegen_type_specifier
219
220%type<decl> type_name type_name_no_function
221%type<decl> type_parameter type_parameter_list
222
223%type<en> type_name_list
224
225%type<decl> type_qualifier type_qualifier_name type_qualifier_list type_qualifier_list_opt type_specifier
226
227%type<decl> variable_abstract_array variable_abstract_declarator variable_abstract_function
228%type<decl> variable_abstract_ptr variable_array variable_declarator variable_function variable_ptr
229
230// initializers
231%type<in>  initializer initializer_list initializer_opt
232
233// designators
234%type<en>  designator designator_list designation
235
236
237// Handle single shift/reduce conflict for dangling else by shifting the ELSE token. For example, this string
238// is ambiguous:
239// .---------.                          matches IF '(' comma_expression ')' statement
240// if ( C ) S1 else S2
241// `-----------------'          matches IF '(' comma_expression ')' statement ELSE statement */
242
243%nonassoc THEN  // rule precedence for IF '(' comma_expression ')' statement
244%nonassoc ELSE  // token precedence for start of else clause in IF statement
245
246%start translation_unit                                                                 // parse-tree root
247
248%%
249//************************* Namespace Management ********************************
250
251// The grammar in the ANSI C standard is not strictly context-free, since it relies upon the distinct terminal
252// symbols "identifier" and "TYPEDEFname" that are lexically identical.  While it is possible to write a
253// purely context-free grammar, such a grammar would obscure the relationship between syntactic and semantic
254// constructs.  Hence, this grammar uses the ANSI style.
255//
256// Cforall compounds this problem by introducing type names local to the scope of a declaration (for instance,
257// those introduced through "forall" qualifiers), and by introducing "type generators" -- parametrized types.
258// This latter type name creates a third class of identifiers that must be distinguished by the scanner.
259//
260// Since the scanner cannot distinguish among the different classes of identifiers without some context
261// information, it accesses a data structure (the TypedefTable) to allow classification of an identifier that
262// it has just read.  Semantic actions during the parser update this data structure when the class of
263// identifiers change.
264//
265// Because the Cforall language is block-scoped, there is the possibility that an identifier can change its
266// class in a local scope; it must revert to its original class at the end of the block.  Since type names can
267// be local to a particular declaration, each declaration is itself a scope.  This requires distinguishing
268// between type names that are local to the current declaration scope and those that persist past the end of
269// the declaration (i.e., names defined in "typedef" or "type" declarations).
270//
271// The non-terminals "push" and "pop" derive the empty string; their only use is to denote the opening and
272// closing of scopes.  Every push must have a matching pop, although it is regrettable the matching pairs do
273// not always occur within the same rule.  These non-terminals may appear in more contexts than strictly
274// necessary from a semantic point of view.  Unfortunately, these extra rules are necessary to prevent parsing
275// conflicts -- the parser may not have enough context and look-ahead information to decide whether a new
276// scope is necessary, so the effect of these extra rules is to open a new scope unconditionally.  As the
277// grammar evolves, it may be neccesary to add or move around "push" and "pop" nonterminals to resolve
278// conflicts of this sort.
279
280push:
281                                {
282                                        typedefTable.enterScope();
283                                }
284                ;
285
286pop:
287                                {
288                                        typedefTable.leaveScope();
289                                }
290                ;
291
292//************************* CONSTANTS ********************************
293
294constant:
295                                // ENUMERATIONconstant is not included here; it is treated as a variable with type
296                                // "enumeration constant".
297                INTEGERconstant                                                                 { $$ = new ConstantNode(ConstantNode::Integer, $1); }
298                | FLOATINGconstant                                                              { $$ = new ConstantNode(ConstantNode::Float, $1); }
299                | CHARACTERconstant                                                             { $$ = new ConstantNode(ConstantNode::Character, $1); }
300                ;
301
302identifier:
303                IDENTIFIER
304                | ATTR_IDENTIFIER                                                               // CFA
305                | zero_one                                                                              // CFA
306                ;
307
308no_01_identifier:
309                IDENTIFIER
310                | ATTR_IDENTIFIER                                                               // CFA
311                ;
312
313no_attr_identifier:
314                IDENTIFIER
315                ;
316
317zero_one:                                                                                               // CFA
318                ZERO
319                | ONE
320                ;
321
322string_literal_list:                                                                    // juxtaposed strings are concatenated
323                STRINGliteral                                                                   { $$ = new ConstantNode(ConstantNode::String, $1); }
324                | string_literal_list STRINGliteral                             { $$ = $1->append( $2 ); }
325                ;
326
327//************************* EXPRESSIONS ********************************
328
329primary_expression:
330                IDENTIFIER                                                                              // typedef name cannot be used as a variable name
331                                { $$ = new VarRefNode($1); }
332                | zero_one
333                                { $$ = new VarRefNode($1); }
334                | constant
335                                { $$ = $1; }
336                | string_literal_list
337                                { $$ = $1; }
338                | '(' comma_expression ')'
339                                { $$ = $2; }
340                | '(' compound_statement ')'                                    // GCC, lambda expression
341                                { $$ = new ValofExprNode($2); }
342                ;
343
344postfix_expression:
345                primary_expression
346                | postfix_expression '[' push assignment_expression pop ']'
347                                // CFA, comma_expression disallowed in the context because it results in a commom user error:
348                                // subscripting a matrix with x[i,j] instead of x[i][j]. While this change is not backwards
349                                // compatible, there seems to be little advantage to this feature and many disadvantages. It
350                                // is possible to write x[(i,j)] in CFA, which is equivalent to the old x[i,j].
351                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Index), $1, $4); }
352                | postfix_expression '(' argument_expression_list ')'
353                                { $$ = new CompositeExprNode($1, $3); }
354                | postfix_expression '.' no_attr_identifier
355                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::FieldSel), $1, new VarRefNode($3)); }
356                | postfix_expression '.' '[' push field_list pop ']' // CFA, tuple field selector
357                | postfix_expression ARROW no_attr_identifier
358                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::PFieldSel), $1, new VarRefNode($3)); }
359                | postfix_expression ARROW '[' push field_list pop ']' // CFA, tuple field selector
360                | postfix_expression ICR
361                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::IncrPost), $1); }
362                | postfix_expression DECR
363                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::DecrPost), $1); }
364                                // GCC has priority: cast_expression
365                | '(' type_name_no_function ')' '{' initializer_list comma_opt '}' // C99
366                                { $$ = 0; }
367                ;
368
369argument_expression_list:
370                argument_expression
371                | argument_expression_list ',' argument_expression
372                                { $$ = (ExpressionNode *)($1->set_link($3)); }
373                ;
374
375argument_expression:
376                // empty
377                                { $$ = 0; }                                                             // use default argument
378                | assignment_expression
379                | no_attr_identifier ':' assignment_expression
380                                { $$ = $3->set_asArgName($1); }
381                                // Only a list of no_attr_identifier_or_typedef_name is allowed in this context. However,
382                                // there is insufficient look ahead to distinguish between this list of parameter names and a
383                                // tuple, so the tuple form must be used with an appropriate semantic check.
384                | '[' push assignment_expression pop ']' ':' assignment_expression
385                                { $$ = $7->set_asArgName($3); }
386                | '[' push assignment_expression ',' tuple_expression_list pop ']' ':' assignment_expression
387                                { $$ = $9->set_asArgName(new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ), (ExpressionNode *)$3->set_link( flattenCommas( $5 )))); }
388                ;
389
390field_list:                                                                                             // CFA, tuple field selector
391                field
392                | field_list ',' field                                                  { $$ = (ExpressionNode *)$1->set_link( $3 ); }
393                ;
394
395field:                                                                                                  // CFA, tuple field selector
396                no_attr_identifier
397                                { $$ = new VarRefNode( $1 ); }
398                | no_attr_identifier '.' field
399                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::FieldSel), new VarRefNode( $1 ), $3); }
400                | no_attr_identifier '.' '[' push field_list pop ']'
401                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::FieldSel), new VarRefNode( $1 ), $5); }
402                | no_attr_identifier ARROW field
403                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::PFieldSel), new VarRefNode( $1 ), $3); }
404                | no_attr_identifier ARROW '[' push field_list pop ']'
405                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::PFieldSel), new VarRefNode( $1 ), $5); }
406                ;
407
408unary_expression:
409                postfix_expression
410                | ICR unary_expression
411                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Incr), $2); }
412                | DECR unary_expression
413                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Decr), $2); }
414                | EXTENSION cast_expression                                             // GCC
415                                { $$ = $2; }
416                | unary_operator cast_expression
417                                { $$ = new CompositeExprNode($1, $2); }
418                | '!' cast_expression
419                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Neg), $2); }
420                | '*' cast_expression                                                   // CFA
421                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::PointTo), $2); }
422                                // '*' is is separated from unary_operator because of shift/reduce conflict in:
423                                //              { * X; } // dereference X
424                                //              { * int X; } // CFA declaration of pointer to int
425                                // '&' must be moved here if C++ reference variables are supported.
426                | SIZEOF unary_expression
427                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::SizeOf), $2); }
428                | SIZEOF '(' type_name_no_function ')'
429                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::SizeOf), new TypeValueNode($3)); }
430                | ATTR_IDENTIFIER
431                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Attr), new VarRefNode($1)); }
432                | ATTR_IDENTIFIER '(' type_name ')'
433                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Attr), new VarRefNode($1), new TypeValueNode($3)); }
434                | ATTR_IDENTIFIER '(' argument_expression ')'
435                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Attr), new VarRefNode($1), $3); }
436                | ALIGNOF unary_expression                                              // GCC, variable alignment
437                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::AlignOf), $2); }
438                | ALIGNOF '(' type_name_no_function ')'                 // GCC, type alignment
439                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::AlignOf), new TypeValueNode($3)); }
440                | ANDAND no_attr_identifier                                             // GCC, address of label
441                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::LabelAddress), new VarRefNode($2, true)); }
442                ;
443
444unary_operator:
445                '&'                                                                                             { $$ = new OperatorNode(OperatorNode::AddressOf); }
446                | '+'                                                                                   { $$ = new OperatorNode(OperatorNode::UnPlus); }
447                | '-'                                                                                   { $$ = new OperatorNode(OperatorNode::UnMinus); }
448                | '~'                                                                                   { $$ = new OperatorNode(OperatorNode::BitNeg); }
449                ;
450
451cast_expression:
452                unary_expression
453                | '(' type_name_no_function ')' cast_expression
454                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Cast), new TypeValueNode($2), $4); }
455                | '(' type_name_no_function ')' tuple
456                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Cast), new TypeValueNode($2), $4); }
457                ;
458
459multiplicative_expression:
460                cast_expression
461                | multiplicative_expression '*' cast_expression
462                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Mul),$1,$3); }
463                | multiplicative_expression '/' cast_expression
464                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Div),$1,$3); }
465                | multiplicative_expression '%' cast_expression
466                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Mod),$1,$3); }
467                ;
468
469additive_expression:
470                multiplicative_expression
471                | additive_expression '+' multiplicative_expression
472                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Plus),$1,$3); }
473                | additive_expression '-' multiplicative_expression
474                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Minus),$1,$3); }
475                ;
476
477shift_expression:
478                additive_expression
479                | shift_expression LS additive_expression
480                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::LShift),$1,$3); }
481                | shift_expression RS additive_expression
482                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::RShift),$1,$3); }
483                ;
484
485relational_expression:
486                shift_expression
487                | relational_expression '<' shift_expression
488                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::LThan),$1,$3); }
489                | relational_expression '>' shift_expression
490                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::GThan),$1,$3); }
491                | relational_expression LE shift_expression
492                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::LEThan),$1,$3); }
493                | relational_expression GE shift_expression
494                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::GEThan),$1,$3); }
495                ;
496
497equality_expression:
498                relational_expression
499                | equality_expression EQ relational_expression
500                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Eq), $1, $3); }
501                | equality_expression NE relational_expression
502                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Neq), $1, $3); }
503                ;
504
505AND_expression:
506                equality_expression
507                | AND_expression '&' equality_expression
508                                { $$ =new CompositeExprNode(new OperatorNode(OperatorNode::BitAnd), $1, $3); }
509                ;
510
511exclusive_OR_expression:
512                AND_expression
513                | exclusive_OR_expression '^' AND_expression
514                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Xor), $1, $3); }
515                ;
516
517inclusive_OR_expression:
518                exclusive_OR_expression
519                | inclusive_OR_expression '|' exclusive_OR_expression
520                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::BitOr), $1, $3); }
521                ;
522
523logical_AND_expression:
524                inclusive_OR_expression
525                | logical_AND_expression ANDAND inclusive_OR_expression
526                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::And), $1, $3); }
527                ;
528
529logical_OR_expression:
530                logical_AND_expression
531                | logical_OR_expression OROR logical_AND_expression
532                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Or), $1, $3); }
533                ;
534
535conditional_expression:
536                logical_OR_expression
537                | logical_OR_expression '?' comma_expression ':' conditional_expression
538                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Cond), (ExpressionNode *)mkList((*$1,*$3,*$5))); }
539                | logical_OR_expression '?' /* empty */ ':' conditional_expression // GCC, omitted first operand
540                                { $$=new CompositeExprNode(new OperatorNode(OperatorNode::NCond),$1,$4); }
541                | logical_OR_expression '?' comma_expression ':' tuple // CFA, tuple expression
542                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Cond), (ExpressionNode *)mkList(( *$1, *$3, *$5 ))); }
543                ;
544
545constant_expression:
546                conditional_expression
547                ;
548
549assignment_expression:
550                                // CFA, assignment is separated from assignment_operator to ensure no assignment operations
551                                // for tuples
552                conditional_expression
553                | unary_expression '=' assignment_expression
554                                { $$ =new CompositeExprNode(new OperatorNode(OperatorNode::Assign), $1, $3); }
555                | unary_expression assignment_operator assignment_expression
556                                { $$ =new CompositeExprNode($2, $1, $3); }
557                | tuple assignment_opt                                                  // CFA, tuple expression
558                                { $$ = ($2 == 0) ? $1 : new CompositeExprNode( new OperatorNode( OperatorNode::Assign ), $1, $2 ); }
559                ;
560
561assignment_expression_opt:
562                // empty
563                                { $$ = new NullExprNode; }
564                | assignment_expression
565                ;
566
567tuple:                                                                                                  // CFA, tuple
568                                // CFA, one assignment_expression is factored out of comma_expression to eliminate a
569                                // shift/reduce conflict with comma_expression in new_identifier_parameter_array and
570                                // new_abstract_array
571                '[' push pop ']'
572                                { $$ = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ) ); }
573                | '[' push assignment_expression pop ']'
574                                { $$ = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ), $3 ); }
575                | '[' push ',' tuple_expression_list pop ']'
576                                { $$ = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ), (ExpressionNode *)(new NullExprNode)->set_link( $4 ) ); }
577                | '[' push assignment_expression ',' tuple_expression_list pop ']'
578                                { $$ = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ), (ExpressionNode *)$3->set_link( flattenCommas( $5 ) ) ); }
579                ;
580
581tuple_expression_list:
582                assignment_expression_opt
583                | tuple_expression_list ',' assignment_expression_opt
584                                { $$ = (ExpressionNode *)$1->set_link( $3 ); }
585                ;
586
587assignment_operator:
588                MULTassign                                                                              { $$ = new OperatorNode(OperatorNode::MulAssn); }
589                | DIVassign                                                                             { $$ = new OperatorNode(OperatorNode::DivAssn); }
590                | MODassign                                                                             { $$ = new OperatorNode(OperatorNode::ModAssn); }
591                | PLUSassign                                                                    { $$ = new OperatorNode(OperatorNode::PlusAssn); }
592                | MINUSassign                                                                   { $$ = new OperatorNode(OperatorNode::MinusAssn); }
593                | LSassign                                                                              { $$ = new OperatorNode(OperatorNode::LSAssn); }
594                | RSassign                                                                              { $$ = new OperatorNode(OperatorNode::RSAssn); }
595                | ANDassign                                                                             { $$ = new OperatorNode(OperatorNode::AndAssn); }
596                | ERassign                                                                              { $$ = new OperatorNode(OperatorNode::ERAssn); }
597                | ORassign                                                                              { $$ = new OperatorNode(OperatorNode::OrAssn); }
598                ;
599
600comma_expression:
601                assignment_expression
602                | comma_expression ',' assignment_expression    // { $$ = (ExpressionNode *)$1->add_to_list($3); }
603                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Comma),$1,$3); }
604                ;
605
606comma_expression_opt:
607                // empty
608                                { $$ = 0; }
609                | comma_expression
610                ;
611
612//*************************** STATEMENTS *******************************
613
614statement:
615                labeled_statement
616                | compound_statement
617                | expression_statement                                                  { $$ = $1; }
618                | selection_statement
619                | iteration_statement
620                | jump_statement
621                | exception_statement
622                | asm_statement
623                ;
624
625labeled_statement:
626                no_attr_identifier ':' attribute_list_opt statement
627                                { $$ = $4->add_label($1);}
628                ;
629
630compound_statement:
631                '{' '}'
632                                { $$ = new CompoundStmtNode( (StatementNode *)0 ); }
633                | '{'
634                                // Two scopes are necessary because the block itself has a scope, but every declaration within
635                                // the block also requires its own scope
636                  push push
637                  label_declaration_opt                                                 // GCC, local labels
638                  block_item_list pop '}'                                               // C99, intermix declarations and statements
639                                { $$ = new CompoundStmtNode( $5 ); }
640                ;
641
642block_item_list:                                                                                // C99
643                block_item
644                | block_item_list push block_item
645                                { if ($1 != 0) { $1->set_link($3); $$ = $1; } }
646                ;
647
648block_item:
649                declaration                                                                             // CFA, new & old style declarations
650                                { $$ = new StatementNode( $1 ); }
651                | EXTENSION declaration                                                 // GCC
652                                { $$ = new StatementNode( $2 ); }
653                | statement pop
654                ;
655
656statement_list:
657                statement
658                | statement_list statement
659                                { if ($1 != 0) { $1->set_link($2); $$ = $1; } }
660                ;
661
662expression_statement:
663                comma_expression_opt ';'
664                                { $$ = new StatementNode(StatementNode::Exp, $1, 0); }
665                ;
666
667selection_statement:
668                IF '(' comma_expression ')' statement                           %prec THEN
669                                // explicitly deal with the shift/reduce conflict on if/else
670                                { $$ = new StatementNode(StatementNode::If, $3, $5); }
671                | IF '(' comma_expression ')' statement ELSE statement
672                                { $$ = new StatementNode(StatementNode::If, $3, (StatementNode *)mkList((*$5, *$7)) ); }
673                | SWITCH '(' comma_expression ')' case_clause   // CFA
674                                { $$ = new StatementNode(StatementNode::Switch, $3, $5); }
675                | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt '}' // CFA
676                                { $$ = new StatementNode(StatementNode::Switch, $3, $8); /* xxx */ }
677                                // The semantics of the declaration list is changed to include any associated initialization,
678                                // which is performed *before* the transfer to the appropriate case clause.  Statements after
679                                // the initial declaration list can never be executed, and therefore, are removed from the
680                                // grammar even though C allows it.
681                | CHOOSE '(' comma_expression ')' case_clause   // CFA
682                                { $$ = new StatementNode(StatementNode::Choose, $3, $5); }
683                | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt choose_clause_list_opt '}' // CFA
684                                { $$ = new StatementNode(StatementNode::Choose, $3, $8); }
685                ;
686
687// CASE and DEFAULT clauses are only allowed in the SWITCH statement, precluding Duff's device. In addition, a
688// case clause allows a list of values and subranges.
689
690case_value:                                                                                             // CFA
691                constant_expression                                                             { $$ = $1; }
692                | constant_expression ELLIPSIS constant_expression // GCC, subrange
693                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Range),$1,$3); }
694                | subrange                                                                              // CFA, subrange
695                ;
696
697case_value_list:                                                                                // CFA
698                case_value
699                | case_value_list ',' case_value
700                                { $$ = new CompositeExprNode(new OperatorNode( OperatorNode::TupleC ), (ExpressionNode *)(tupleContents($1))->set_link($3) ); }
701                ;
702
703case_label:                                                                                             // CFA
704                CASE case_value_list ':'                                                { $$ = new StatementNode(StatementNode::Case, $2, 0); }
705                | DEFAULT ':'                                                               { $$ = new StatementNode(StatementNode::Default); }
706                                // A semantic check is required to ensure only one default clause per switch/choose statement.
707                ;
708
709case_label_list:                                                                                // CFA
710                case_label
711                | case_label_list case_label                                    { $$ = (StatementNode *)($1->set_link($2)); }
712                ;
713
714case_clause:                                                                                    // CFA
715                case_label_list statement                                               { $$ = $1->append_last_case($2); }
716                ;
717
718switch_clause_list_opt:                                                                 // CFA
719                // empty
720                                { $$ = 0; }
721                | switch_clause_list
722                ;
723
724switch_clause_list:                                                                             // CFA
725                case_label_list statement_list
726                                { $$ = $1->append_last_case($2); }
727                | switch_clause_list case_label_list statement_list
728                                { $$ = (StatementNode *)($1->set_link($2->append_last_case($3))); }
729                ;
730
731choose_clause_list_opt:                                                                 // CFA
732                // empty
733                                { $$ = 0; }
734                | choose_clause_list
735                ;
736
737choose_clause_list:                                                                             // CFA
738                case_label_list fall_through
739                                { $$ = $1->append_last_case($2); }
740                | case_label_list statement_list fall_through_opt
741                                { $$ = $1->append_last_case((StatementNode *)mkList((*$2,*$3))); }
742                | choose_clause_list case_label_list fall_through
743                                { $$ = (StatementNode *)($1->set_link($2->append_last_case($3))); }
744                | choose_clause_list case_label_list statement_list fall_through_opt
745                                { $$ = (StatementNode *)($1->set_link($2->append_last_case((StatementNode *)mkList((*$3,*$4))))); }
746                ;
747
748fall_through_opt:                                                                               // CFA
749                // empty
750                                { $$ = 0; }
751                | fall_through
752                ;
753
754fall_through:                                                                                   // CFA
755                FALLTHRU                                                                                { $$ = new StatementNode(StatementNode::Fallthru, 0, 0); }
756                | FALLTHRU ';'                                                                  { $$ = new StatementNode(StatementNode::Fallthru, 0, 0); }
757                ;
758
759iteration_statement:
760                WHILE '(' comma_expression ')' statement
761                                { $$ = new StatementNode(StatementNode::While, $3, $5); }
762                | DO statement WHILE '(' comma_expression ')' ';'
763                                { $$ = new StatementNode(StatementNode::Do, $5, $2); }
764                | FOR '(' push for_control_expression ')' statement
765                                { $$ = new StatementNode(StatementNode::For, $4, $6); }
766                ;
767
768for_control_expression:
769                comma_expression_opt pop ';' comma_expression_opt ';' comma_expression_opt
770                                { $$ = new ForCtlExprNode($1, $4, $6); }
771                | declaration comma_expression_opt ';' comma_expression_opt // C99
772                                // Like C++, the loop index can be declared local to the loop.
773                                { $$ = new ForCtlExprNode($1, $2, $4); }
774                ;
775
776jump_statement:
777                GOTO no_attr_identifier ';'
778                                { $$ = new StatementNode(StatementNode::Goto, $2); }
779                | GOTO '*' comma_expression ';'                         // GCC, computed goto
780                                // The syntax for the GCC computed goto violates normal expression precedence, e.g., goto
781                                // *i+3; => goto *(i+3); whereas normal operator precedence yields goto (*i)+3;
782                                { $$ = new StatementNode(StatementNode::Goto, $3); }
783                | CONTINUE ';'
784                                // A semantic check is required to ensure this statement appears only in the body of an
785                                // iteration statement.
786                                { $$ = new StatementNode(StatementNode::Continue, 0, 0); }
787                | CONTINUE no_attr_identifier ';'               // CFA, multi-level continue
788                                // A semantic check is required to ensure this statement appears only in the body of an
789                                // iteration statement, and the target of the transfer appears only at the start of an
790                                // iteration statement.
791                                { $$ = new StatementNode(StatementNode::Continue, $2); }
792                | BREAK ';'
793                                // A semantic check is required to ensure this statement appears only in the body of an
794                                // iteration statement.
795                                { $$ = new StatementNode(StatementNode::Break, 0, 0); }
796                | BREAK no_attr_identifier ';'                          // CFA, multi-level exit
797                                // A semantic check is required to ensure this statement appears only in the body of an
798                                // iteration statement, and the target of the transfer appears only at the start of an
799                                // iteration statement.
800                                { $$ = new StatementNode(StatementNode::Break, $2 ); }
801                | RETURN comma_expression_opt ';'
802                                { $$ = new StatementNode(StatementNode::Return, $2, 0); }
803                | THROW assignment_expression ';'
804                                { $$ = new StatementNode(StatementNode::Throw, $2, 0); }
805                | THROW ';'
806                                { $$ = new StatementNode(StatementNode::Throw, 0, 0); }
807                ;
808
809exception_statement:
810                TRY compound_statement handler_list
811                                { $$ = new StatementNode(StatementNode::Try, 0,(StatementNode *)(mkList((*$2,*$3)))); }
812                | TRY compound_statement finally_clause
813                                { $$ = new StatementNode(StatementNode::Try, 0,(StatementNode *)(mkList((*$2,*$3)))); }
814                | TRY compound_statement handler_list finally_clause
815                                {
816                                        $3->set_link($4);
817                                        $$ = new StatementNode(StatementNode::Try, 0,(StatementNode *)(mkList((*$2,*$3))));
818                                }
819                ;
820
821handler_list:
822                                // There must be at least one catch clause
823                handler_clause
824                                // ISO/IEC 9899:1999 Section 15.3(6) If present, a "..." handler shall be the last handler for
825                                // its try block.
826                | CATCH '(' ELLIPSIS ')' compound_statement
827                                { $$ = StatementNode::newCatchStmt( 0, $5, true ); }
828                | handler_clause CATCH '(' ELLIPSIS ')' compound_statement
829                                { $$ = $1->set_link( StatementNode::newCatchStmt( 0, $6, true ) ); }
830                ;
831
832handler_clause:
833                CATCH '(' push push exception_declaration pop ')' compound_statement pop
834                                { $$ = StatementNode::newCatchStmt($5, $8); }
835                | handler_clause CATCH '(' push push exception_declaration pop ')' compound_statement pop
836                                { $$ = $1->set_link( StatementNode::newCatchStmt($6, $9) ); }
837                ;
838
839finally_clause:
840                FINALLY compound_statement
841                                { $$ = new StatementNode(StatementNode::Finally, 0, $2);
842                                        std::cout << "Just created a finally node" << std::endl;
843                                }
844                ;
845
846exception_declaration:
847                                // A semantic check is required to ensure type_specifier does not create a new type, e.g.:
848                                //
849                                //              catch ( struct { int i; } x ) ...
850                                //
851                                // This new type cannot catch any thrown type because of name equivalence among types.
852                type_specifier
853                | type_specifier declarator
854                                {
855                                        typedefTable.addToEnclosingScope( TypedefTable::ID );
856                                        $$ = $2->addType( $1 );
857                                }
858                | type_specifier variable_abstract_declarator
859                                { $$ = $2->addType( $1 ); }
860                | new_abstract_declarator_tuple no_attr_identifier // CFA
861                                {
862                                        typedefTable.addToEnclosingScope( TypedefTable::ID );
863                                        $$ = $1->addName( $2 );
864                                }
865                | new_abstract_declarator_tuple                                 // CFA
866                ;
867
868asm_statement:
869                ASM type_qualifier_list_opt '(' constant_expression ')' ';'
870                                { $$ = new StatementNode(StatementNode::Asm, 0, 0); }
871                | ASM type_qualifier_list_opt '(' constant_expression ':' asm_operands_opt ')' ';' // remaining GCC
872                                { $$ = new StatementNode(StatementNode::Asm, 0, 0); }
873                | ASM type_qualifier_list_opt '(' constant_expression ':' asm_operands_opt ':' asm_operands_opt ')' ';'
874                                { $$ = new StatementNode(StatementNode::Asm, 0, 0); }
875                | ASM type_qualifier_list_opt '(' constant_expression ':' asm_operands_opt ':' asm_operands_opt ':'
876                                                asm_clobbers_list ')' ';'
877                                { $$ = new StatementNode(StatementNode::Asm, 0, 0); }
878                ;
879
880asm_operands_opt:                                                                               // GCC
881                // empty
882                | asm_operands_list
883                ;
884
885asm_operands_list:                                                                              // GCC
886                asm_operand
887                | asm_operands_list ',' asm_operand
888                ;
889
890asm_operand:                                                                                    // GCC
891                STRINGliteral '(' constant_expression ')'               {}
892                ;
893
894asm_clobbers_list:                                                                              // GCC
895                STRINGliteral                                                                   {}
896                | asm_clobbers_list ',' STRINGliteral
897                ;
898
899//******************************* DECLARATIONS *********************************
900
901declaration_list_opt:                                                                   // used at beginning of switch statement
902                pop
903                                { $$ = 0; }
904                | declaration_list
905                ;
906
907declaration_list:
908                declaration
909                | declaration_list push declaration
910                                { $$ = $1->appendList( $3 ); }
911                ;
912
913old_declaration_list_opt:                                                               // used to declare parameter types in K&R style functions
914                pop
915                                { $$ = 0; }
916                | old_declaration_list
917                ;
918
919old_declaration_list:
920                old_declaration
921                | old_declaration_list push old_declaration
922                                { $$ = $1->appendList( $3 ); }
923                ;
924
925label_declaration_opt:                                                                  // GCC, local label
926                // empty
927                | label_declaration_list
928                ;
929
930label_declaration_list:                                                                 // GCC, local label
931                LABEL label_list ';'
932                | label_declaration_list LABEL label_list ';'
933                ;
934
935label_list:                                                                                             // GCC, local label
936                no_attr_identifier_or_typedef_name                              {}
937                | label_list ',' no_attr_identifier_or_typedef_name {}
938                ;
939
940declaration:                                                                                    // CFA, new & old style declarations
941                new_declaration
942                | old_declaration
943                ;
944
945// C declaration syntax is notoriously confusing and error prone. Cforall provides its own type, variable and
946// function declarations. CFA declarations use the same declaration tokens as in C; however, CFA places
947// declaration modifiers to the left of the base type, while C declarations place modifiers to the right of
948// the base type. CFA declaration modifiers are interpreted from left to right and the entire type
949// specification is distributed across all variables in the declaration list (as in Pascal).  ANSI C and the
950// new CFA declarations may appear together in the same program block, but cannot be mixed within a specific
951// declaration.
952//
953//                      CFA                                     C
954//              [10] int x;                     int x[10];              // array of 10 integers
955//              [10] * char y;          char *y[10];    // array of 10 pointers to char
956
957new_declaration:                                                                                // CFA
958                new_variable_declaration pop ';'
959                | new_typedef_declaration pop ';'
960                | new_function_declaration pop ';'
961                | type_declaring_list pop ';'
962                | context_specifier pop ';'
963                ;
964
965new_variable_declaration:                                                               // CFA
966                new_variable_specifier initializer_opt
967                                {
968                                        typedefTable.addToEnclosingScope( TypedefTable::ID );
969                                        $$ = $1;
970                                }
971                | declaration_qualifier_list new_variable_specifier initializer_opt
972                                // declaration_qualifier_list also includes type_qualifier_list, so a semantic check is
973                                // necessary to preclude them as a type_qualifier cannot appear in that context.
974                                {
975                                        typedefTable.addToEnclosingScope( TypedefTable::ID );
976                                        $$ = $2->addQualifiers( $1 );
977                                }
978                | new_variable_declaration pop ',' push identifier_or_typedef_name initializer_opt
979                                {
980                                        typedefTable.addToEnclosingScope( *$5, TypedefTable::ID );
981                                        $$ = $1->appendList( $1->cloneType( $5 ) );
982                                }
983                ;
984
985new_variable_specifier:                                                                 // CFA
986                                // A semantic check is required to ensure asm_name only appears on declarations with implicit
987                                // or explicit static storage-class
988                new_abstract_declarator_no_tuple identifier_or_typedef_name asm_name_opt
989                                {
990                                        typedefTable.setNextIdentifier( *$2 );
991                                        $$ = $1->addName( $2 );
992                                }
993                | new_abstract_tuple identifier_or_typedef_name asm_name_opt
994                                {
995                                        typedefTable.setNextIdentifier( *$2 );
996                                        $$ = $1->addName( $2 );
997                                }
998                | type_qualifier_list new_abstract_tuple identifier_or_typedef_name asm_name_opt
999                                {
1000                                        typedefTable.setNextIdentifier( *$3 );
1001                                        $$ = $2->addQualifiers( $1 )->addName( $3 );
1002                                }
1003                ;
1004
1005new_function_declaration:                                                               // CFA
1006                new_function_specifier
1007                                {
1008                                        typedefTable.addToEnclosingScope( TypedefTable::ID );
1009                                        $$ = $1;
1010                                }
1011                | type_qualifier_list new_function_specifier
1012                                {
1013                                        typedefTable.addToEnclosingScope( TypedefTable::ID );
1014                                        $$ = $2->addQualifiers( $1 );
1015                                }
1016                | declaration_qualifier_list new_function_specifier
1017                                {
1018                                        typedefTable.addToEnclosingScope( TypedefTable::ID );
1019                                        $$ = $2->addQualifiers( $1 );
1020                                }
1021                | declaration_qualifier_list type_qualifier_list new_function_specifier
1022                                {
1023                                        typedefTable.addToEnclosingScope( TypedefTable::ID );
1024                                        $$ = $3->addQualifiers( $1 )->addQualifiers( $2 );
1025                                }
1026                | new_function_declaration pop ',' push identifier_or_typedef_name
1027                                {
1028                                        typedefTable.addToEnclosingScope( *$5, TypedefTable::ID );
1029                                        $$ = $1->appendList( $1->cloneType( $5 ) );
1030                                }
1031                ;
1032
1033new_function_specifier:                                                                 // CFA
1034                '[' push pop ']' identifier '(' push new_parameter_type_list_opt pop ')'
1035                                {
1036                                        typedefTable.setNextIdentifier( *($5) );
1037                                        $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true );
1038                                }
1039                | '[' push pop ']' TYPEDEFname '(' push new_parameter_type_list_opt pop ')'
1040                                {
1041                                        typedefTable.setNextIdentifier( *($5) );
1042                                        $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true );
1043                                }
1044                                // identifier_or_typedef_name must be broken apart because of the sequence:
1045                                //
1046                                //   '[' ']' identifier_or_typedef_name '(' new_parameter_type_list_opt ')'
1047                                //   '[' ']' type_specifier
1048                                //
1049                                // type_specifier can resolve to just TYPEDEFname (e.g. typedef int T; int f( T );). Therefore
1050                                // this must be flattened to allow lookahead to the '(' without having to reduce
1051                                // identifier_or_typedef_name.
1052                | new_abstract_tuple identifier_or_typedef_name '(' push new_parameter_type_list_opt pop ')'
1053                                // To obtain LR(1), this rule must be factored out from function return type (see
1054                                //   new_abstract_declarator).
1055                                {
1056                                        $$ = DeclarationNode::newFunction( $2, $1, $5, 0, true );
1057                                }
1058                | new_function_return identifier_or_typedef_name '(' push new_parameter_type_list_opt pop ')'
1059                                {
1060                                        $$ = DeclarationNode::newFunction( $2, $1, $5, 0, true );
1061                                }
1062                ;
1063
1064new_function_return:                                                                    // CFA
1065                '[' push new_parameter_list pop ']'
1066                                { $$ = DeclarationNode::newTuple( $3 ); }
1067                | '[' push new_parameter_list pop ',' push new_abstract_parameter_list pop ']'
1068                                // To obtain LR(1), the last new_abstract_parameter_list is added into this flattened rule to
1069                                // lookahead to the ']'.
1070                                { $$ = DeclarationNode::newTuple( $3->appendList( $7 ) ); }
1071                ;
1072
1073new_typedef_declaration:                                                                // CFA
1074                TYPEDEF new_variable_specifier
1075                                {
1076                                        typedefTable.addToEnclosingScope( TypedefTable::TD);
1077                                        $$ = $2->addTypedef();
1078                                }
1079                | TYPEDEF new_function_specifier
1080                                {
1081                                        typedefTable.addToEnclosingScope( TypedefTable::TD);
1082                                        $$ = $2->addTypedef();
1083                                }
1084                | new_typedef_declaration pop ',' push no_attr_identifier
1085                                {
1086                                        typedefTable.addToEnclosingScope( *$5, TypedefTable::TD);
1087                                        $$ = $1->appendList( $1->cloneType( $5 ) );
1088                                }
1089                ;
1090
1091// Traditionally typedef is part of storage-class specifier for syntactic convenience only. Here, it is
1092// factored out as a separate form of declaration, which syntactically precludes storage-class specifiers and
1093// initialization.
1094
1095typedef_declaration:
1096                TYPEDEF type_specifier declarator
1097                                {
1098                                        typedefTable.addToEnclosingScope( TypedefTable::TD);
1099                                        $$ = $3->addType( $2 )->addTypedef();
1100                                }
1101                | typedef_declaration pop ',' push declarator
1102                                {
1103                                        typedefTable.addToEnclosingScope( TypedefTable::TD);
1104                                        $$ = $1->appendList( $1->cloneBaseType( $5 )->addTypedef() );
1105                                }
1106                | type_qualifier_list TYPEDEF type_specifier declarator // remaining OBSOLESCENT (see 2)
1107                                {
1108                                        typedefTable.addToEnclosingScope( TypedefTable::TD);
1109                                        $$ = $4->addType( $3 )->addQualifiers( $1 )->addTypedef();
1110                                }
1111                | type_specifier TYPEDEF declarator
1112                                {
1113                                        typedefTable.addToEnclosingScope( TypedefTable::TD);
1114                                        $$ = $3->addType( $1 )->addTypedef();
1115                                }
1116                | type_specifier TYPEDEF type_qualifier_list declarator
1117                                {
1118                                        typedefTable.addToEnclosingScope( TypedefTable::TD);
1119                                        $$ = $4->addQualifiers($1)->addTypedef()->addType($1);
1120                                }
1121                ;
1122
1123typedef_expression:                                                                             // GCC, naming expression type
1124                TYPEDEF no_attr_identifier '=' assignment_expression
1125                                {
1126                                        typedefTable.addToEnclosingScope(*($2), TypedefTable::TD);
1127                                        $$ = DeclarationNode::newName( 0 ); // XXX
1128                                }
1129                | typedef_expression pop ',' push no_attr_identifier '=' assignment_expression
1130                                {
1131                                        typedefTable.addToEnclosingScope(*($5), TypedefTable::TD);
1132                                        $$ = DeclarationNode::newName( 0 ); // XXX
1133                                }
1134                ;
1135
1136old_declaration:
1137                declaring_list pop ';'
1138                | typedef_declaration pop ';'
1139                | typedef_expression pop ';'                                    // GCC, naming expression type
1140                | sue_declaration_specifier pop ';'
1141                ;
1142
1143declaring_list:
1144                                // A semantic check is required to ensure asm_name only appears on declarations with implicit
1145                                // or explicit static storage-class
1146                declaration_specifier declarator asm_name_opt initializer_opt
1147                                {
1148                                        typedefTable.addToEnclosingScope( TypedefTable::ID );
1149                                        $$ = ($2->addType( $1 ))->addInitializer($4);
1150                                }
1151                | declaring_list ',' attribute_list_opt declarator asm_name_opt initializer_opt
1152                                {
1153                                        typedefTable.addToEnclosingScope( TypedefTable::ID );
1154                                        $$ = $1->appendList( $1->cloneBaseType( $4->addInitializer($6) ) );
1155                                }
1156                ;
1157
1158declaration_specifier:                                                                  // type specifier + storage class
1159                basic_declaration_specifier
1160                | sue_declaration_specifier
1161                | typedef_declaration_specifier
1162                | typegen_declaration_specifier
1163                ;
1164
1165type_specifier:                                                                                 // declaration specifier - storage class
1166                basic_type_specifier
1167                | sue_type_specifier
1168                | typedef_type_specifier
1169                | typegen_type_specifier
1170                ;
1171
1172type_qualifier_list_opt:                                                                // GCC, used in asm_statement
1173                // empty
1174                                { $$ = 0; }
1175                | type_qualifier_list
1176                ;
1177
1178type_qualifier_list:
1179                                // A semantic check is necessary to ensure a type qualifier is appropriate for the kind of
1180                                // declaration.
1181                                //
1182                                // ISO/IEC 9899:1999 Section 6.7.3(4) : If the same qualifier appears more than once in the
1183                                // same specifier-qualifier-list, either directly or via one or more typedefs, the behavior is
1184                                // the same as if it appeared only once.
1185                type_qualifier
1186                | type_qualifier_list type_qualifier
1187                                { $$ = $1->addQualifiers( $2 ); }
1188                ;
1189
1190type_qualifier:
1191                type_qualifier_name
1192                | attribute
1193                                { $$ = DeclarationNode::newQualifier( DeclarationNode::Attribute ); }
1194                ;
1195
1196type_qualifier_name:
1197                CONST
1198                                { $$ = DeclarationNode::newQualifier( DeclarationNode::Const ); }
1199                | RESTRICT
1200                                { $$ = DeclarationNode::newQualifier( DeclarationNode::Restrict ); }
1201                | VOLATILE
1202                                { $$ = DeclarationNode::newQualifier( DeclarationNode::Volatile ); }
1203                | LVALUE                                                                                // CFA
1204                                { $$ = DeclarationNode::newQualifier( DeclarationNode::Lvalue ); }
1205                | ATOMIC
1206                                { $$ = DeclarationNode::newQualifier( DeclarationNode::Atomic ); }
1207                | FORALL '('
1208                                {
1209                                        typedefTable.enterScope();
1210                                }
1211                  type_parameter_list ')'                                               // CFA
1212                                {
1213                                        typedefTable.leaveScope();
1214                                        $$ = DeclarationNode::newForall( $4 );
1215                                }
1216                ;
1217
1218declaration_qualifier_list:
1219                storage_class_list
1220                | type_qualifier_list storage_class_list                // remaining OBSOLESCENT (see 2)
1221                                { $$ = $1->addQualifiers( $2 ); }
1222                | declaration_qualifier_list type_qualifier_list storage_class_list
1223                                { $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }
1224                ;
1225
1226storage_class_list:
1227                                // A semantic check is necessary to ensure a storage class is appropriate for the kind of
1228                                // declaration and that only one of each is specified, except for inline, which can appear
1229                                // with the others.
1230                                //
1231                                // ISO/IEC 9899:1999 Section 6.7.1(2) : At most, one storage-class specifier may be given in
1232                                // the declaration specifiers in a declaration.
1233                storage_class
1234                | storage_class_list storage_class
1235                                { $$ = $1->addQualifiers( $2 ); }
1236                ;
1237
1238storage_class:
1239                storage_class_name
1240                ;
1241
1242storage_class_name:
1243                EXTERN
1244                                { $$ = DeclarationNode::newStorageClass( DeclarationNode::Extern ); }
1245                | STATIC
1246                                { $$ = DeclarationNode::newStorageClass( DeclarationNode::Static ); }
1247                | AUTO
1248                                { $$ = DeclarationNode::newStorageClass( DeclarationNode::Auto ); }
1249                | REGISTER
1250                                { $$ = DeclarationNode::newStorageClass( DeclarationNode::Register ); }
1251                | INLINE                                                                                // C99
1252                                // INLINE is essentially a storage class specifier for functions, and hence, belongs here.
1253                                { $$ = DeclarationNode::newStorageClass( DeclarationNode::Inline ); }
1254                | FORTRAN                                                                               // C99
1255                                { $$ = DeclarationNode::newStorageClass( DeclarationNode::Fortran ); }
1256                ;
1257
1258basic_type_name:
1259                CHAR
1260                                { $$ = DeclarationNode::newBasicType( DeclarationNode::Char ); }
1261                | DOUBLE
1262                                { $$ = DeclarationNode::newBasicType( DeclarationNode::Double ); }
1263                | FLOAT
1264                                { $$ = DeclarationNode::newBasicType( DeclarationNode::Float ); }
1265                | INT
1266                                { $$ = DeclarationNode::newBasicType( DeclarationNode::Int ); }
1267                | LONG
1268                                { $$ = DeclarationNode::newModifier( DeclarationNode::Long ); }
1269                | SHORT
1270                                { $$ = DeclarationNode::newModifier( DeclarationNode::Short ); }
1271                | SIGNED
1272                                { $$ = DeclarationNode::newModifier( DeclarationNode::Signed ); }
1273                | UNSIGNED
1274                                { $$ = DeclarationNode::newModifier( DeclarationNode::Unsigned ); }
1275                | VOID
1276                                { $$ = DeclarationNode::newBasicType( DeclarationNode::Void ); }
1277                | BOOL                                                                                  // C99
1278                                { $$ = DeclarationNode::newBasicType( DeclarationNode::Bool ); }
1279                | COMPLEX                                                                               // C99
1280                                { $$ = DeclarationNode::newBasicType( DeclarationNode::Complex ); }
1281                | IMAGINARY                                                                             // C99
1282                                { $$ = DeclarationNode::newBasicType( DeclarationNode::Imaginary ); }
1283                ;
1284
1285basic_declaration_specifier:
1286                                // A semantic check is necessary for conflicting storage classes.
1287                basic_type_specifier
1288                | declaration_qualifier_list basic_type_specifier
1289                                { $$ = $2->addQualifiers( $1 ); }
1290                | basic_declaration_specifier storage_class             // remaining OBSOLESCENT (see 2)
1291                                { $$ = $1->addQualifiers( $2 ); }
1292                | basic_declaration_specifier storage_class type_qualifier_list
1293                                { $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }
1294                | basic_declaration_specifier storage_class basic_type_specifier
1295                                { $$ = $3->addQualifiers( $2 )->addType( $1 ); }
1296                ;
1297
1298basic_type_specifier:
1299                direct_type_name
1300                | type_qualifier_list_opt indirect_type_name type_qualifier_list_opt
1301                                { $$ = $2->addQualifiers( $1 )->addQualifiers( $3 ); }
1302                ;
1303
1304direct_type_name:
1305                                // A semantic check is necessary for conflicting type qualifiers.
1306                basic_type_name
1307                | type_qualifier_list basic_type_name
1308                                { $$ = $2->addQualifiers( $1 ); }
1309                | direct_type_name type_qualifier
1310                                { $$ = $1->addQualifiers( $2 ); }
1311                | direct_type_name basic_type_name
1312                                { $$ = $1->addType( $2 ); }
1313                ;
1314
1315indirect_type_name:
1316                TYPEOF '(' type_name ')'                                                // GCC: typeof(x) y;
1317                                { $$ = $3; }
1318                | TYPEOF '(' comma_expression ')'                               // GCC: typeof(a+b) y;
1319                                { $$ = DeclarationNode::newTypeof( $3 ); }
1320                | ATTR_TYPEGENname '(' type_name ')'                    // CFA: e.g., @type(x) y;
1321                                { $$ = DeclarationNode::newAttr( $1, $3 ); }
1322                | ATTR_TYPEGENname '(' comma_expression ')'             // CFA: e.g., @type(a+b) y;
1323                                { $$ = DeclarationNode::newAttr( $1, $3 ); }
1324                ;
1325
1326sue_declaration_specifier:
1327                sue_type_specifier
1328                | declaration_qualifier_list sue_type_specifier
1329                                { $$ = $2->addQualifiers( $1 ); }
1330                | sue_declaration_specifier storage_class               // remaining OBSOLESCENT (see 2)
1331                                { $$ = $1->addQualifiers( $2 ); }
1332                | sue_declaration_specifier storage_class type_qualifier_list
1333                                { $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }
1334                ;
1335
1336sue_type_specifier:
1337                elaborated_type_name                                                    // struct, union, enum
1338                | type_qualifier_list elaborated_type_name
1339                                { $$ = $2->addQualifiers( $1 ); }
1340                | sue_type_specifier type_qualifier
1341                                { $$ = $1->addQualifiers( $2 ); }
1342                ;
1343
1344typedef_declaration_specifier:
1345                typedef_type_specifier
1346                | declaration_qualifier_list typedef_type_specifier
1347                                { $$ = $2->addQualifiers( $1 ); }
1348                | typedef_declaration_specifier storage_class   // remaining OBSOLESCENT (see 2)
1349                                { $$ = $1->addQualifiers( $2 ); }
1350                | typedef_declaration_specifier storage_class type_qualifier_list
1351                                { $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }
1352                ;
1353
1354typedef_type_specifier:                                                                 // typedef types
1355                TYPEDEFname
1356                                { $$ = DeclarationNode::newFromTypedef( $1 ); }
1357                | type_qualifier_list TYPEDEFname
1358                                { $$ = DeclarationNode::newFromTypedef( $2 )->addQualifiers( $1 ); }
1359                | typedef_type_specifier type_qualifier
1360                                { $$ = $1->addQualifiers( $2 ); }
1361                ;
1362
1363elaborated_type_name:
1364                aggregate_name
1365                | enum_name
1366                ;
1367
1368aggregate_name:
1369                aggregate_key '{' field_declaration_list '}'
1370                                { $$ = DeclarationNode::newAggregate( $1, 0, 0, 0, $3 ); }
1371                | aggregate_key no_attr_identifier_or_typedef_name
1372                                { $$ = DeclarationNode::newAggregate( $1, $2, 0, 0, 0 ); }
1373                | aggregate_key no_attr_identifier_or_typedef_name '{' field_declaration_list '}'
1374                                { $$ = DeclarationNode::newAggregate( $1, $2, 0, 0, $4 ); }
1375                | aggregate_key '(' push type_parameter_list pop ')' '{' field_declaration_list '}' // CFA
1376                                { $$ = DeclarationNode::newAggregate( $1, 0, $4, 0, $8 ); }
1377                | aggregate_key '(' push type_parameter_list pop ')' no_attr_identifier_or_typedef_name // CFA
1378                                { $$ = DeclarationNode::newAggregate( $1, $7, $4, 0, 0 ); }
1379                | aggregate_key '(' push type_parameter_list pop ')' no_attr_identifier_or_typedef_name '{' field_declaration_list '}' // CFA
1380                                { $$ = DeclarationNode::newAggregate( $1, $7, $4, 0, $9 ); }
1381                | aggregate_key '(' push type_parameter_list pop ')' '(' type_name_list ')' '{' field_declaration_list '}' // CFA
1382                                { $$ = DeclarationNode::newAggregate( $1, 0, $4, $8, $11 ); }
1383                | aggregate_key '(' push type_name_list pop ')' no_attr_identifier_or_typedef_name // CFA
1384                                // push and pop are only to prevent S/R conflicts
1385                                { $$ = DeclarationNode::newAggregate( $1, $7, 0, $4, 0 ); }
1386                | aggregate_key '(' push type_parameter_list pop ')' '(' type_name_list ')' no_attr_identifier_or_typedef_name '{' field_declaration_list '}' // CFA
1387                                { $$ = DeclarationNode::newAggregate( $1, $10, $4, $8, $12 ); }
1388                ;
1389
1390aggregate_key:
1391                STRUCT attribute_list_opt
1392                                { $$ = DeclarationNode::Struct; }
1393                | UNION attribute_list_opt
1394                                { $$ = DeclarationNode::Union; }
1395                ;
1396
1397field_declaration_list:
1398                field_declaration
1399                                { $$ = $1; }
1400                | field_declaration_list field_declaration
1401                                { $$ = $1->appendList( $2 ); }
1402                ;
1403
1404field_declaration:
1405                new_field_declaring_list ';'                                    // CFA, new style field declaration
1406                | EXTENSION new_field_declaring_list ';'                // GCC
1407                                { $$ = $2; }
1408                | field_declaring_list ';'
1409                | EXTENSION field_declaring_list ';'                    // GCC
1410                                { $$ = $2; }
1411                ;
1412
1413new_field_declaring_list:                                                               // CFA, new style field declaration
1414                new_abstract_declarator_tuple                                   // CFA, no field name
1415                | new_abstract_declarator_tuple no_attr_identifier_or_typedef_name
1416                                { $$ = $1->addName( $2 ); }
1417                | new_field_declaring_list ',' no_attr_identifier_or_typedef_name
1418                                { $$ = $1->appendList( $1->cloneType( $3 ) ); }
1419                | new_field_declaring_list ','                                  // CFA, no field name
1420                                { $$ = $1->appendList( $1->cloneType( 0 ) ); }
1421                ;
1422
1423field_declaring_list:
1424                type_specifier field_declarator
1425                                { $$ = $2->addType( $1 ); }
1426                | field_declaring_list ',' attribute_list_opt field_declarator
1427                                { $$ = $1->appendList( $1->cloneBaseType( $4 ) ); }
1428                ;
1429
1430field_declarator:
1431                // empty
1432                                { $$ = DeclarationNode::newName( 0 ); /* XXX */ } // CFA, no field name
1433                | bit_subrange_size                                                             // no field name
1434                                { $$ = DeclarationNode::newBitfield( $1 ); }
1435                | variable_declarator bit_subrange_size_opt
1436                                // A semantic check is required to ensure bit_subrange only appears on base type int.
1437                                { $$ = $1->addBitfield( $2 ); }
1438                | typedef_redeclarator bit_subrange_size_opt
1439                                // A semantic check is required to ensure bit_subrange only appears on base type int.
1440                                { $$ = $1->addBitfield( $2 ); }
1441                | variable_abstract_declarator                                  // CFA, no field name
1442                ;
1443
1444bit_subrange_size_opt:
1445                // empty
1446                                { $$ = 0; }
1447                | bit_subrange_size
1448                                { $$ = $1; }
1449                ;
1450
1451bit_subrange_size:
1452                ':' constant_expression
1453                                { $$ = $2; }
1454                ;
1455
1456enum_key:
1457                ENUM attribute_list_opt
1458                ;
1459
1460enum_name:
1461                enum_key '{' enumerator_list comma_opt '}'
1462                                { $$ = DeclarationNode::newEnum( 0, $3 ); }
1463                | enum_key no_attr_identifier_or_typedef_name '{' enumerator_list comma_opt '}'
1464                                { $$ = DeclarationNode::newEnum( $2, $4 ); }
1465                | enum_key no_attr_identifier_or_typedef_name
1466                                { $$ = DeclarationNode::newEnum( $2, 0 ); }
1467                ;
1468
1469enumerator_list:
1470                no_attr_identifier_or_typedef_name enumerator_value_opt
1471                                { $$ = DeclarationNode::newEnumConstant( $1, $2 ); }
1472                | enumerator_list ',' no_attr_identifier_or_typedef_name enumerator_value_opt
1473                                { $$ = $1->appendList( DeclarationNode::newEnumConstant( $3, $4 ) ); }
1474                ;
1475
1476enumerator_value_opt:
1477                // empty
1478                                { $$ = 0; }
1479                | '=' constant_expression
1480                                { $$ = $2; }
1481                ;
1482
1483// Minimum of one parameter after which ellipsis is allowed only at the end.
1484
1485new_parameter_type_list_opt:                                                    // CFA
1486                // empty
1487                                { $$ = 0; }
1488                | new_parameter_type_list
1489                ;
1490
1491new_parameter_type_list:                                                                // CFA, abstract + real
1492                new_abstract_parameter_list
1493                | new_parameter_list
1494                | new_parameter_list pop ',' push new_abstract_parameter_list
1495                                { $$ = $1->appendList( $5 ); }
1496                | new_abstract_parameter_list pop ',' push ELLIPSIS
1497                                { $$ = $1->addVarArgs(); }
1498                | new_parameter_list pop ',' push ELLIPSIS
1499                                { $$ = $1->addVarArgs(); }
1500                ;
1501
1502new_parameter_list:                                                                             // CFA
1503                                // To obtain LR(1) between new_parameter_list and new_abstract_tuple, the last
1504                                // new_abstract_parameter_list is factored out from new_parameter_list, flattening the rules
1505                                // to get lookahead to the ']'.
1506                new_parameter_declaration
1507                | new_abstract_parameter_list pop ',' push new_parameter_declaration
1508                                { $$ = $1->appendList( $5 ); }
1509                | new_parameter_list pop ',' push new_parameter_declaration
1510                                { $$ = $1->appendList( $5 ); }
1511                | new_parameter_list pop ',' push new_abstract_parameter_list pop ',' push new_parameter_declaration
1512                                { $$ = $1->appendList( $5 )->appendList( $9 ); }
1513                ;
1514
1515new_abstract_parameter_list:                                                    // CFA, new & old style abstract
1516                new_abstract_parameter_declaration
1517                | new_abstract_parameter_list pop ',' push new_abstract_parameter_declaration
1518                                { $$ = $1->appendList( $5 ); }
1519                ;
1520
1521parameter_type_list_opt:
1522                // empty
1523                                { $$ = 0; }
1524                | parameter_type_list
1525                ;
1526
1527parameter_type_list:
1528                parameter_list
1529                | parameter_list pop ',' push ELLIPSIS
1530                                { $$ = $1->addVarArgs(); }
1531                ;
1532
1533parameter_list:                                                                                 // abstract + real
1534                abstract_parameter_declaration
1535                | parameter_declaration
1536                | parameter_list pop ',' push abstract_parameter_declaration
1537                                { $$ = $1->appendList( $5 ); }
1538                | parameter_list pop ',' push parameter_declaration
1539                                { $$ = $1->appendList( $5 ); }
1540                ;
1541
1542// Provides optional identifier names (abstract_declarator/variable_declarator), no initialization, different
1543// semantics for typedef name by using typedef_parameter_redeclarator instead of typedef_redeclarator, and
1544// function prototypes.
1545
1546new_parameter_declaration:                                                              // CFA, new & old style parameter declaration
1547                parameter_declaration
1548                | new_identifier_parameter_declarator_no_tuple identifier_or_typedef_name assignment_opt
1549                                { $$ = $1->addName( $2 ); }
1550                | new_abstract_tuple identifier_or_typedef_name assignment_opt
1551                                // To obtain LR(1), these rules must be duplicated here (see new_abstract_declarator).
1552                                { $$ = $1->addName( $2 ); }
1553                | type_qualifier_list new_abstract_tuple identifier_or_typedef_name assignment_opt
1554                                { $$ = $2->addName( $3 )->addQualifiers( $1 ); }
1555                | new_function_specifier
1556                ;
1557
1558new_abstract_parameter_declaration:                                             // CFA, new & old style parameter declaration
1559                abstract_parameter_declaration
1560                | new_identifier_parameter_declarator_no_tuple
1561                | new_abstract_tuple
1562                                // To obtain LR(1), these rules must be duplicated here (see new_abstract_declarator).
1563                | type_qualifier_list new_abstract_tuple
1564                                { $$ = $2->addQualifiers( $1 ); }
1565                | new_abstract_function
1566                ;
1567
1568parameter_declaration:
1569                declaration_specifier identifier_parameter_declarator assignment_opt
1570                                {
1571                                        typedefTable.addToEnclosingScope( TypedefTable::ID );
1572                                        $$ = $2->addType( $1 )->addInitializer( new InitializerNode($3) );
1573                                }
1574                | declaration_specifier typedef_parameter_redeclarator assignment_opt
1575                                {
1576                                        typedefTable.addToEnclosingScope( TypedefTable::ID );
1577                                        $$ = $2->addType( $1 )->addInitializer( new InitializerNode($3) );
1578                                }
1579                ;
1580
1581abstract_parameter_declaration:
1582                declaration_specifier
1583                | declaration_specifier abstract_parameter_declarator
1584                                { $$ = $2->addType( $1 ); }
1585                ;
1586
1587// ISO/IEC 9899:1999 Section 6.9.1(6) : "An identifier declared as a typedef name shall not be redeclared as a
1588// parameter." Because the scope of the K&R-style parameter-list sees the typedef first, the following is
1589// based only on identifiers.  The ANSI-style parameter-list can redefine a typedef name.
1590
1591identifier_list:                                                                                // K&R-style parameter list => no types
1592                no_attr_identifier
1593                                { $$ = DeclarationNode::newName( $1 ); }
1594                | identifier_list ',' no_attr_identifier
1595                                { $$ = $1->appendList( DeclarationNode::newName( $3 ) ); }
1596                ;
1597
1598identifier_or_typedef_name:
1599                identifier
1600                | TYPEDEFname
1601                | TYPEGENname
1602                ;
1603
1604no_01_identifier_or_typedef_name:
1605                no_01_identifier
1606                | TYPEDEFname
1607                | TYPEGENname
1608                ;
1609
1610no_attr_identifier_or_typedef_name:
1611                no_attr_identifier
1612                | TYPEDEFname
1613                | TYPEGENname
1614                ;
1615
1616type_name_no_function:                                                                  // sizeof, alignof, cast (constructor)
1617                new_abstract_declarator_tuple                                   // CFA
1618                | type_specifier
1619                | type_specifier variable_abstract_declarator
1620                                { $$ = $2->addType( $1 ); }
1621                ;
1622
1623type_name:                                                                                              // typeof, assertion
1624                new_abstract_declarator_tuple                                   // CFA
1625                | new_abstract_function                                                 // CFA
1626                | type_specifier
1627                | type_specifier abstract_declarator
1628                                { $$ = $2->addType( $1 ); }
1629                ;
1630
1631initializer_opt:
1632                // empty
1633                                { $$ = 0; }
1634                | '=' initializer                                                               { $$ = $2; }
1635                ;
1636
1637initializer:
1638                assignment_expression                                                   { $$ = new InitializerNode($1); }
1639                | '{' initializer_list comma_opt '}'                    { $$ = new InitializerNode($2, true); }
1640                ;
1641
1642initializer_list:
1643                initializer
1644                | designation initializer                                               { $$ = $2->set_designators( $1 ); }
1645                | initializer_list ',' initializer                              { $$ = (InitializerNode *)( $1->set_link($3) ); }
1646                | initializer_list ',' designation initializer
1647                                { $$ = (InitializerNode *)( $1->set_link( $4->set_designators($3) ) ); }
1648                ;
1649
1650// There is an unreconcileable parsing problem between C99 and CFA with respect to designators. The problem is
1651// use of '=' to separator the designator from the initializer value, as in:
1652//
1653//              int x[10] = { [1] = 3 };
1654//
1655// The string "[1] = 3" can be parsed as a designator assignment or a tuple assignment.  To disambiguate this
1656// case, CFA changes the syntax from "=" to ":" as the separator between the designator and initializer. GCC
1657// does uses ":" for field selection. The optional use of the "=" in GCC, or in this case ":", cannot be
1658// supported either due to shift/reduce conflicts
1659
1660designation:
1661                designator_list ':'                                                             // C99, CFA uses ":" instead of "="
1662                | no_attr_identifier_or_typedef_name ':'                // GCC, field name
1663                                                { $$ = new VarRefNode( $1 ); }
1664                ;
1665
1666designator_list:                                                                                // C99
1667                designator
1668                | designator_list designator                                            { $$ = (ExpressionNode *)($1->set_link( $2 )); }
1669                ;
1670
1671designator:
1672                '.' no_attr_identifier_or_typedef_name                  // C99, field name
1673                                { $$ = new VarRefNode( $2 ); }
1674                | '[' push assignment_expression pop ']'                // C99, single array element
1675                                // assignment_expression used instead of constant_expression because of shift/reduce conflicts
1676                                // with tuple.
1677                                { $$ = $3; }
1678                | '[' push subrange pop ']'                                             // CFA, multiple array elements
1679                                { $$ = $3; }
1680                | '[' push constant_expression ELLIPSIS constant_expression pop ']' // GCC, multiple array elements
1681                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Range), $3, $5); }
1682                | '.' '[' push field_list pop ']'                               // CFA, tuple field selector
1683                                { $$ = $4; }
1684                ;
1685
1686// The CFA type system is based on parametric polymorphism, the ability to declare functions with type
1687// parameters, rather than an object-oriented type system. This required four groups of extensions:
1688//
1689// Overloading: function, data, and operator identifiers may be overloaded.
1690//
1691// Type declarations: "type" is used to generate new types for declaring objects. Similarly, "dtype" is used
1692//     for object and incomplete types, and "ftype" is used for function types. Type declarations with
1693//     initializers provide definitions of new types. Type declarations with storage class "extern" provide
1694//     opaque types.
1695//
1696// Polymorphic functions: A forall clause declares a type parameter. The corresponding argument is inferred at
1697//     the call site. A polymorphic function is not a template; it is a function, with an address and a type.
1698//
1699// Specifications and Assertions: Specifications are collections of declarations parameterized by one or more
1700//     types. They serve many of the purposes of abstract classes, and specification hierarchies resemble
1701//     subclass hierarchies. Unlike classes, they can define relationships between types.  Assertions declare
1702//     that a type or types provide the operations declared by a specification.  Assertions are normally used
1703//     to declare requirements on type arguments of polymorphic functions.
1704
1705typegen_declaration_specifier:                                                  // CFA
1706                typegen_type_specifier
1707                | declaration_qualifier_list typegen_type_specifier
1708                                { $$ = $2->addQualifiers( $1 ); }
1709                | typegen_declaration_specifier storage_class   // remaining OBSOLESCENT (see 2)
1710                                { $$ = $1->addQualifiers( $2 ); }
1711                | typegen_declaration_specifier storage_class type_qualifier_list
1712                                { $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }
1713                ;
1714
1715typegen_type_specifier:                                                                 // CFA
1716                TYPEGENname '(' type_name_list ')'
1717                                { $$ = DeclarationNode::newFromTypeGen( $1, $3 ); }
1718                | type_qualifier_list TYPEGENname '(' type_name_list ')'
1719                                { $$ = DeclarationNode::newFromTypeGen( $2, $4 )->addQualifiers( $1 ); }
1720                | typegen_type_specifier type_qualifier
1721                                { $$ = $1->addQualifiers( $2 ); }
1722                ;
1723
1724type_parameter_list:                                                                    // CFA
1725                type_parameter assignment_opt
1726                | type_parameter_list ',' type_parameter assignment_opt
1727                                { $$ = $1->appendList( $3 ); }
1728                ;
1729
1730type_parameter:                                                                                 // CFA
1731                type_class no_attr_identifier_or_typedef_name
1732                                { typedefTable.addToEnclosingScope(*($2), TypedefTable::TD); }
1733                  assertion_list_opt
1734                                { $$ = DeclarationNode::newTypeParam( $1, $2 )->addAssertions( $4 ); }
1735                | type_specifier identifier_parameter_declarator
1736                ;
1737
1738type_class:                                                                                             // CFA
1739                TYPE
1740                                { $$ = DeclarationNode::Type; }
1741                | DTYPE
1742                                { $$ = DeclarationNode::Ftype; }
1743                | FTYPE
1744                                { $$ = DeclarationNode::Dtype; }
1745                ;
1746
1747assertion_list_opt:                                                                             // CFA
1748                // empty
1749                                { $$ = 0; }
1750                | assertion_list_opt assertion
1751                                { $$ = $1 == 0 ? $2 : $1->appendList( $2 ); }
1752                ;
1753
1754assertion:                                                                                              // CFA
1755                '|' no_attr_identifier_or_typedef_name '(' type_name_list ')'
1756                                {
1757                                        typedefTable.openContext( *($2) );
1758                                        $$ = DeclarationNode::newContextUse( $2, $4 );
1759                                }
1760                | '|' '{' push context_declaration_list '}'
1761                                { $$ = $4; }
1762                | '|' '(' push type_parameter_list pop ')' '{' push context_declaration_list '}' '(' type_name_list ')'
1763                                { $$ = 0; }
1764                ;
1765
1766type_name_list:                                                                                 // CFA
1767                type_name
1768                                { $$ = new TypeValueNode( $1 ); }
1769                | assignment_expression
1770                | type_name_list ',' type_name
1771                                { $$ = (ExpressionNode *)($1->set_link(new TypeValueNode( $3 ))); }
1772                | type_name_list ',' assignment_expression
1773                                { $$ = (ExpressionNode *)($1->set_link($3)); }
1774                ;
1775
1776type_declaring_list:                                                                    // CFA
1777                TYPE type_declarator
1778                                { $$ = $2; }
1779                | storage_class_list TYPE type_declarator
1780                                { $$ = $3->addQualifiers( $1 ); }
1781                | type_declaring_list ',' type_declarator
1782                                { $$ = $1->appendList( $3->copyStorageClasses( $1 ) ); }
1783                ;
1784
1785type_declarator:                                                                                // CFA
1786                type_declarator_name assertion_list_opt
1787                                { $$ = $1->addAssertions( $2 ); }
1788                | type_declarator_name assertion_list_opt '=' type_name
1789                                { $$ = $1->addAssertions( $2 )->addType( $4 ); }
1790                ;
1791
1792type_declarator_name:                                                                   // CFA
1793                no_attr_identifier_or_typedef_name
1794                                {
1795                                        typedefTable.addToEnclosingScope(*($1), TypedefTable::TD);
1796                                        $$ = DeclarationNode::newTypeDecl( $1, 0 );
1797                                }
1798                | no_01_identifier_or_typedef_name '(' push type_parameter_list pop ')'
1799                                {
1800                                        typedefTable.addToEnclosingScope(*($1), TypedefTable::TG);
1801                                        $$ = DeclarationNode::newTypeDecl( $1, $4 );
1802                                }
1803                ;
1804
1805context_specifier:                                                                              // CFA
1806                CONTEXT no_attr_identifier_or_typedef_name '(' push type_parameter_list pop ')' '{' '}'
1807                                {
1808                                        typedefTable.addToEnclosingScope(*($2), TypedefTable::ID );
1809                                        $$ = DeclarationNode::newContext( $2, $5, 0 );
1810                                }
1811                | CONTEXT no_attr_identifier_or_typedef_name '(' push type_parameter_list pop ')' '{'
1812                                {
1813                                        typedefTable.enterContext( *($2) );
1814                                        typedefTable.enterScope();
1815                                }
1816                  context_declaration_list '}'
1817                                {
1818                                        typedefTable.leaveContext();
1819                                        typedefTable.addToEnclosingScope(*($2), TypedefTable::ID );
1820                                        $$ = DeclarationNode::newContext( $2, $5, $10 );
1821                                }
1822                ;
1823
1824context_declaration_list:                                                               // CFA
1825                context_declaration
1826                | context_declaration_list push context_declaration
1827                                { $$ = $1->appendList( $3 ); }
1828                ;
1829
1830context_declaration:                                                                    // CFA
1831                new_context_declaring_list pop ';'
1832                | context_declaring_list pop ';'
1833                ;
1834
1835new_context_declaring_list:                                                             // CFA
1836                new_variable_specifier
1837                                {
1838                                        typedefTable.addToEnclosingScope2( TypedefTable::ID );
1839                                        $$ = $1;
1840                                }
1841                | new_function_specifier
1842                                {
1843                                        typedefTable.addToEnclosingScope2( TypedefTable::ID );
1844                                        $$ = $1;
1845                                }
1846                | new_context_declaring_list pop ',' push identifier_or_typedef_name
1847                                {
1848                                        typedefTable.addToEnclosingScope2( *($5), TypedefTable::ID );
1849                                        $$ = $1->appendList( $1->cloneType( $5 ) );
1850                                }
1851                ;
1852
1853context_declaring_list:                                                                 // CFA
1854                type_specifier declarator
1855                                {
1856                                        typedefTable.addToEnclosingScope2( TypedefTable::ID );
1857                                        $$ = $2->addType( $1 );
1858                                }
1859                | context_declaring_list pop ',' push declarator
1860                                {
1861                                        typedefTable.addToEnclosingScope2( TypedefTable::ID );
1862                                        $$ = $1->appendList( $1->cloneBaseType( $5 ) );
1863                                }
1864                ;
1865
1866//***************************** EXTERNAL DEFINITIONS *****************************
1867
1868translation_unit:
1869                // empty
1870                                {}                                                                              // empty input file
1871                | external_definition_list
1872                                {
1873                                        if ( theTree ) {
1874                                                theTree->appendList( $1 );
1875                                        } else {
1876                                                theTree = $1;
1877                                        }
1878                                }
1879                ;
1880
1881external_definition_list:
1882                external_definition
1883                | external_definition_list push external_definition
1884                                { $$ = ($1 != NULL ) ? $1->appendList( $3 ) : $3; }
1885                ;
1886
1887external_definition_list_opt:
1888                // empty
1889                                { $$ = 0; }
1890                | external_definition_list
1891                ;
1892
1893external_definition:
1894                declaration
1895                | function_definition
1896                | asm_statement                                                                 // GCC, global assembler statement
1897                                {}
1898                | EXTERN STRINGliteral
1899                                {
1900                                        linkageStack.push( linkage );
1901                                        linkage = LinkageSpec::fromString( *$2 );
1902                                }
1903                  '{' external_definition_list_opt '}'                  // C++-style linkage specifier
1904                                {
1905                                        linkage = linkageStack.top();
1906                                        linkageStack.pop();
1907                                        $$ = $5;
1908                                }
1909                | EXTENSION external_definition
1910                                { $$ = $2; }
1911                ;
1912
1913function_definition:
1914                new_function_declaration compound_statement             // CFA
1915                                {
1916                                        typedefTable.addToEnclosingScope( TypedefTable::ID );
1917                                        typedefTable.leaveScope();
1918                                        $$ = $1->addFunctionBody( $2 );
1919                                }
1920//              | declaration_qualifier_list new_function_specifier compound_statement // CFA
1921//                              // declaration_qualifier_list also includes type_qualifier_list, so a semantic check is
1922//                              // necessary to preclude them as a type_qualifier cannot appear in this context.
1923//                              {
1924//                                      typedefTable.addToEnclosingScope( TypedefTable::ID );
1925//                                      typedefTable.leaveScope();
1926//                                      $$ = $2->addFunctionBody( $3 )->addQualifiers( $1 );
1927//                              }
1928                | declaration_specifier function_declarator compound_statement
1929                                {
1930                                        typedefTable.addToEnclosingScope( TypedefTable::ID );
1931                                        typedefTable.leaveScope();
1932                                        $$ = $2->addFunctionBody( $3 )->addType( $1 );
1933                                }
1934
1935                                // These rules are a concession to the "implicit int" type_specifier because there is a
1936                                // significant amount of code with functions missing a type-specifier on the return type.
1937                                // Parsing is possible because function_definition does not appear in the context of an
1938                                // expression (nested functions would preclude this concession). A function prototype
1939                                // declaration must still have a type_specifier. OBSOLESCENT (see 1)
1940                | function_declarator compound_statement
1941                                {
1942                                        typedefTable.addToEnclosingScope( TypedefTable::ID );
1943                                        typedefTable.leaveScope();
1944                                        $$ = $1->addFunctionBody( $2 );
1945                                }
1946                | type_qualifier_list function_declarator compound_statement
1947                                {
1948                                        typedefTable.addToEnclosingScope( TypedefTable::ID );
1949                                        typedefTable.leaveScope();
1950                                        $$ = $2->addFunctionBody( $3 )->addQualifiers( $1 );
1951                                }
1952                | declaration_qualifier_list function_declarator compound_statement
1953                                {
1954                                        typedefTable.addToEnclosingScope( TypedefTable::ID );
1955                                        typedefTable.leaveScope();
1956                                        $$ = $2->addFunctionBody( $3 )->addQualifiers( $1 );
1957                                }
1958                | declaration_qualifier_list type_qualifier_list function_declarator compound_statement
1959                                {
1960                                        typedefTable.addToEnclosingScope( TypedefTable::ID );
1961                                        typedefTable.leaveScope();
1962                                        $$ = $3->addFunctionBody( $4 )->addQualifiers( $2 )->addQualifiers( $1 );
1963                                }
1964
1965                                // Old-style K&R function definition, OBSOLESCENT (see 4)
1966                | declaration_specifier old_function_declarator push old_declaration_list_opt compound_statement
1967                                {
1968                                        typedefTable.addToEnclosingScope( TypedefTable::ID );
1969                                        typedefTable.leaveScope();
1970                                        $$ = $2->addOldDeclList( $4 )->addFunctionBody( $5 )->addType( $1 );
1971                                }
1972                | old_function_declarator push old_declaration_list_opt compound_statement
1973                                {
1974                                        typedefTable.addToEnclosingScope( TypedefTable::ID );
1975                                        typedefTable.leaveScope();
1976                                        $$ = $1->addOldDeclList( $3 )->addFunctionBody( $4 );
1977                                }
1978                | type_qualifier_list old_function_declarator push old_declaration_list_opt compound_statement
1979                                {
1980                                        typedefTable.addToEnclosingScope( TypedefTable::ID );
1981                                        typedefTable.leaveScope();
1982                                        $$ = $2->addOldDeclList( $4 )->addFunctionBody( $5 )->addQualifiers( $1 );
1983                                }
1984
1985                                // Old-style K&R function definition with "implicit int" type_specifier, OBSOLESCENT (see 4)
1986                | declaration_qualifier_list old_function_declarator push old_declaration_list_opt compound_statement
1987                                {
1988                                        typedefTable.addToEnclosingScope( TypedefTable::ID );
1989                                        typedefTable.leaveScope();
1990                                        $$ = $2->addOldDeclList( $4 )->addFunctionBody( $5 )->addQualifiers( $1 );
1991                                }
1992                | declaration_qualifier_list type_qualifier_list old_function_declarator push old_declaration_list_opt compound_statement
1993                                {
1994                                        typedefTable.addToEnclosingScope( TypedefTable::ID );
1995                                        typedefTable.leaveScope();
1996                                        $$ = $3->addOldDeclList( $5 )->addFunctionBody( $6 )->addQualifiers( $2 )->addQualifiers( $1 );
1997                                }
1998                ;
1999
2000declarator:
2001                variable_declarator
2002                | function_declarator
2003                | typedef_redeclarator
2004                ;
2005
2006subrange:
2007                constant_expression '~' constant_expression             // CFA, integer subrange
2008                                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Range), $1, $3); }
2009                ;
2010
2011asm_name_opt:                                                                                   // GCC
2012                // empty
2013                | ASM '(' string_literal_list ')' attribute_list_opt
2014                ;
2015
2016attribute_list_opt:                                                                             // GCC
2017                // empty
2018                | attribute_list
2019                ;
2020
2021attribute_list:                                                                                 // GCC
2022                attribute
2023                | attribute_list attribute
2024                ;
2025
2026attribute:                                                                                              // GCC
2027                ATTRIBUTE '(' '(' attribute_parameter_list ')' ')'
2028                ;
2029
2030attribute_parameter_list:                                                               // GCC
2031                attrib
2032                | attribute_parameter_list ',' attrib
2033                ;
2034
2035attrib:                                                                                                 // GCC
2036                // empty
2037                | any_word
2038                | any_word '(' comma_expression_opt ')'
2039                ;
2040
2041any_word:                                                                                               // GCC
2042                identifier_or_typedef_name {}
2043                | storage_class_name {}
2044                | basic_type_name {}
2045                | type_qualifier {}
2046                ;
2047
2048// ============================================================================
2049// The following sections are a series of grammar patterns used to parse declarators. Multiple patterns are
2050// necessary because the type of an identifier in wrapped around the identifier in the same form as its usage
2051// in an expression, as in:
2052//
2053//              int (*f())[10] { ... };
2054//              ... (*f())[3] += 1;             // definition mimics usage
2055//
2056// Because these patterns are highly recursive, changes at a lower level in the recursion require copying some
2057// or all of the pattern. Each of these patterns has some subtle variation to ensure correct syntax in a
2058// particular context.
2059// ============================================================================
2060
2061// ----------------------------------------------------------------------------
2062// The set of valid declarators before a compound statement for defining a function is less than the set of
2063// declarators to define a variable or function prototype, e.g.:
2064//
2065//              valid declaration               invalid definition
2066//              -----------------               ------------------
2067//              int f;                                          int f {}
2068//              int *f;                                         int *f {}
2069//              int f[10];                              int f[10] {}
2070//              int (*f)(int);                          int (*f)(int) {}
2071//
2072// To preclude this syntactic anomaly requires separating the grammar rules for variable and function
2073// declarators, hence variable_declarator and function_declarator.
2074// ----------------------------------------------------------------------------
2075
2076// This pattern parses a declaration of a variable that is not redefining a typedef name. The pattern
2077// precludes declaring an array of functions versus a pointer to an array of functions.
2078
2079variable_declarator:
2080                paren_identifier attribute_list_opt
2081                | variable_ptr
2082                | variable_array attribute_list_opt
2083                | variable_function attribute_list_opt
2084                ;
2085
2086paren_identifier:
2087                identifier
2088                                {
2089                                        typedefTable.setNextIdentifier( *($1) );
2090                                        $$ = DeclarationNode::newName( $1 );
2091                                }
2092                | '(' paren_identifier ')'                                              // redundant parenthesis
2093                                { $$ = $2; }
2094                ;
2095
2096variable_ptr:
2097                '*' variable_declarator
2098                                { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
2099                | '*' type_qualifier_list variable_declarator
2100                                { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
2101                | '(' variable_ptr ')'
2102                                { $$ = $2; }
2103                ;
2104
2105variable_array:
2106                paren_identifier array_dimension
2107                                { $$ = $1->addArray( $2 ); }
2108                | '(' variable_ptr ')' array_dimension
2109                                { $$ = $2->addArray( $4 ); }
2110                | '(' variable_array ')' multi_array_dimension  // redundant parenthesis
2111                                { $$ = $2->addArray( $4 ); }
2112                | '(' variable_array ')'                                                // redundant parenthesis
2113                                { $$ = $2; }
2114                ;
2115
2116variable_function:
2117                '(' variable_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
2118                                { $$ = $2->addParamList( $6 ); }
2119                | '(' variable_function ')'                                             // redundant parenthesis
2120                                { $$ = $2; }
2121                ;
2122
2123// This pattern parses a function declarator that is not redefining a typedef name. Because functions cannot
2124// be nested, there is no context where a function definition can redefine a typedef name. To allow nested
2125// functions requires further separation of variable and function declarators in typedef_redeclarator.  The
2126// pattern precludes returning arrays and functions versus pointers to arrays and functions.
2127
2128function_declarator:
2129                function_no_ptr attribute_list_opt
2130                | function_ptr
2131                | function_array attribute_list_opt
2132                ;
2133
2134function_no_ptr:
2135                paren_identifier '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
2136                                { $$ = $1->addParamList( $4 ); }
2137                | '(' function_ptr ')' '(' push parameter_type_list_opt pop ')'
2138                                { $$ = $2->addParamList( $6 ); }
2139                | '(' function_no_ptr ')'                                               // redundant parenthesis
2140                                { $$ = $2; }
2141                ;
2142
2143function_ptr:
2144                '*' function_declarator
2145                                { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
2146                | '*' type_qualifier_list function_declarator
2147                                { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
2148                | '(' function_ptr ')'
2149                                { $$ = $2; }
2150                ;
2151
2152function_array:
2153                '(' function_ptr ')' array_dimension
2154                                { $$ = $2->addArray( $4 ); }
2155                | '(' function_array ')' multi_array_dimension  // redundant parenthesis
2156                                { $$ = $2->addArray( $4 ); }
2157                | '(' function_array ')'                                                // redundant parenthesis
2158                                { $$ = $2; }
2159                ;
2160
2161// This pattern parses an old-style K&R function declarator (OBSOLESCENT, see 4) that is not redefining a
2162// typedef name (see function_declarator for additional comments). The pattern precludes returning arrays and
2163// functions versus pointers to arrays and functions.
2164
2165old_function_declarator:
2166                old_function_no_ptr
2167                | old_function_ptr
2168                | old_function_array
2169                ;
2170
2171old_function_no_ptr:
2172                paren_identifier '(' identifier_list ')'                // function_declarator handles empty parameter
2173                                { $$ = $1->addIdList( $3 ); }
2174                | '(' old_function_ptr ')' '(' identifier_list ')'
2175                                { $$ = $2->addIdList( $5 ); }
2176                | '(' old_function_no_ptr ')'                                   // redundant parenthesis
2177                                { $$ = $2; }
2178                ;
2179
2180old_function_ptr:
2181                '*' old_function_declarator
2182                                { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
2183                | '*' type_qualifier_list old_function_declarator
2184                                { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
2185                | '(' old_function_ptr ')'
2186                                { $$ = $2; }
2187                ;
2188
2189old_function_array:
2190                '(' old_function_ptr ')' array_dimension
2191                                { $$ = $2->addArray( $4 ); }
2192                | '(' old_function_array ')' multi_array_dimension // redundant parenthesis
2193                                { $$ = $2->addArray( $4 ); }
2194                | '(' old_function_array ')'                                    // redundant parenthesis
2195                                { $$ = $2; }
2196                ;
2197
2198// This pattern parses a declaration for a variable or function prototype that redefines a typedef name, e.g.:
2199//
2200//              typedef int foo;
2201//              {
2202//                 int foo; // redefine typedef name in new scope
2203//              }
2204//
2205// The pattern precludes declaring an array of functions versus a pointer to an array of functions, and
2206// returning arrays and functions versus pointers to arrays and functions.
2207
2208typedef_redeclarator:
2209                paren_typedef attribute_list_opt
2210                | typedef_ptr
2211                | typedef_array attribute_list_opt
2212                | typedef_function attribute_list_opt
2213                ;
2214
2215paren_typedef:
2216                TYPEDEFname
2217                                {
2218                                typedefTable.setNextIdentifier( *($1) );
2219                                $$ = DeclarationNode::newName( $1 );
2220                                }
2221                | '(' paren_typedef ')'
2222                                { $$ = $2; }
2223                ;
2224
2225typedef_ptr:
2226                '*' typedef_redeclarator
2227                                { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
2228                | '*' type_qualifier_list typedef_redeclarator
2229                                { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
2230                | '(' typedef_ptr ')'
2231                                { $$ = $2; }
2232                ;
2233
2234typedef_array:
2235                paren_typedef array_dimension
2236                                { $$ = $1->addArray( $2 ); }
2237                | '(' typedef_ptr ')' array_dimension
2238                                { $$ = $2->addArray( $4 ); }
2239                | '(' typedef_array ')' multi_array_dimension   // redundant parenthesis
2240                                { $$ = $2->addArray( $4 ); }
2241                | '(' typedef_array ')'                                                 // redundant parenthesis
2242                                { $$ = $2; }
2243                ;
2244
2245typedef_function:
2246                paren_typedef '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
2247                                { $$ = $1->addParamList( $4 ); }
2248                | '(' typedef_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
2249                                { $$ = $2->addParamList( $6 ); }
2250                | '(' typedef_function ')'                                              // redundant parenthesis
2251                                { $$ = $2; }
2252                ;
2253
2254// This pattern parses a declaration for a parameter variable or function prototype that is not redefining a
2255// typedef name and allows the C99 array options, which can only appear in a parameter list.  The pattern
2256// precludes declaring an array of functions versus a pointer to an array of functions, and returning arrays
2257// and functions versus pointers to arrays and functions.
2258
2259identifier_parameter_declarator:
2260                paren_identifier attribute_list_opt
2261                | identifier_parameter_ptr
2262                | identifier_parameter_array attribute_list_opt
2263                | identifier_parameter_function attribute_list_opt
2264                ;
2265
2266identifier_parameter_ptr:
2267                '*' identifier_parameter_declarator
2268                                { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
2269                | '*' type_qualifier_list identifier_parameter_declarator
2270                                { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
2271                | '(' identifier_parameter_ptr ')'
2272                                { $$ = $2; }
2273                ;
2274
2275identifier_parameter_array:
2276                paren_identifier array_parameter_dimension
2277                                { $$ = $1->addArray( $2 ); }
2278                | '(' identifier_parameter_ptr ')' array_dimension
2279                                { $$ = $2->addArray( $4 ); }
2280                | '(' identifier_parameter_array ')' multi_array_dimension // redundant parenthesis
2281                                { $$ = $2->addArray( $4 ); }
2282                | '(' identifier_parameter_array ')'                    // redundant parenthesis
2283                                { $$ = $2; }
2284                ;
2285
2286identifier_parameter_function:
2287                paren_identifier '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
2288                                { $$ = $1->addParamList( $4 ); }
2289                | '(' identifier_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
2290                                { $$ = $2->addParamList( $6 ); }
2291                | '(' identifier_parameter_function ')'                 // redundant parenthesis
2292                                { $$ = $2; }
2293                ;
2294
2295// This pattern parses a declaration for a parameter variable or function prototype that is redefining a
2296// typedef name, e.g.:
2297//
2298//              typedef int foo;
2299//              int f( int foo ); // redefine typedef name in new scope
2300//
2301// and allows the C99 array options, which can only appear in a parameter list.  In addition, the pattern
2302// handles the special meaning of parenthesis around a typedef name:
2303//
2304//              ISO/IEC 9899:1999 Section 6.7.5.3(11) : "In a parameter declaration, a single typedef name in
2305//              parentheses is taken to be an abstract declarator that specifies a function with a single parameter,
2306//              not as redundant parentheses around the identifier."
2307//
2308// which precludes the following cases:
2309//
2310//              typedef float T;
2311//              int f( int ( T [5] ) );                                         // see abstract_parameter_declarator
2312//              int g( int ( T ( int ) ) );                             // see abstract_parameter_declarator
2313//              int f( int f1( T a[5] ) );                              // see identifier_parameter_declarator
2314//              int g( int g1( T g2( int p ) ) );               // see identifier_parameter_declarator
2315//
2316// In essence, a '(' immediately to the left of typedef name, T, is interpreted as starting a parameter type
2317// list, and not as redundant parentheses around a redeclaration of T. Finally, the pattern also precludes
2318// declaring an array of functions versus a pointer to an array of functions, and returning arrays and
2319// functions versus pointers to arrays and functions.
2320
2321typedef_parameter_redeclarator:
2322                typedef attribute_list_opt
2323                | typedef_parameter_ptr
2324                | typedef_parameter_array attribute_list_opt
2325                | typedef_parameter_function attribute_list_opt
2326                ;
2327
2328typedef:
2329                TYPEDEFname
2330                                {
2331                                        typedefTable.setNextIdentifier( *($1) );
2332                                        $$ = DeclarationNode::newName( $1 );
2333                                }
2334                ;
2335
2336typedef_parameter_ptr:
2337                '*' typedef_parameter_redeclarator
2338                                { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
2339                | '*' type_qualifier_list typedef_parameter_redeclarator
2340                                { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
2341                | '(' typedef_parameter_ptr ')'
2342                                { $$ = $2; }
2343                ;
2344
2345typedef_parameter_array:
2346                typedef array_parameter_dimension
2347                                { $$ = $1->addArray( $2 ); }
2348                | '(' typedef_parameter_ptr ')' array_parameter_dimension
2349                                { $$ = $2->addArray( $4 ); }
2350                ;
2351
2352typedef_parameter_function:
2353                typedef '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
2354                                { $$ = $1->addParamList( $4 ); }
2355                | '(' typedef_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
2356                                { $$ = $2->addParamList( $6 ); }
2357                ;
2358
2359// This pattern parses a declaration of an abstract variable or function prototype, i.e., there is no
2360// identifier to which the type applies, e.g.:
2361//
2362//              sizeof( int );
2363//              sizeof( int [10] );
2364//
2365// The pattern precludes declaring an array of functions versus a pointer to an array of functions, and
2366// returning arrays and functions versus pointers to arrays and functions.
2367
2368abstract_declarator:
2369                abstract_ptr
2370                | abstract_array attribute_list_opt
2371                | abstract_function attribute_list_opt
2372                ;
2373
2374abstract_ptr:
2375                '*'
2376                                { $$ = DeclarationNode::newPointer( 0 ); }
2377                | '*' type_qualifier_list
2378                                { $$ = DeclarationNode::newPointer( $2 ); }
2379                | '*' abstract_declarator
2380                                { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
2381                | '*' type_qualifier_list abstract_declarator
2382                                { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
2383                | '(' abstract_ptr ')'
2384                                { $$ = $2; }
2385                ;
2386
2387abstract_array:
2388                array_dimension
2389                | '(' abstract_ptr ')' array_dimension
2390                                { $$ = $2->addArray( $4 ); }
2391                | '(' abstract_array ')' multi_array_dimension  // redundant parenthesis
2392                                { $$ = $2->addArray( $4 ); }
2393                | '(' abstract_array ')'                                                // redundant parenthesis
2394                                { $$ = $2; }
2395                ;
2396
2397abstract_function:
2398                '(' push parameter_type_list_opt pop ')'                // empty parameter list OBSOLESCENT (see 3)
2399                                { $$ = DeclarationNode::newFunction( 0, 0, $3, 0 ); }
2400                | '(' abstract_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
2401                                { $$ = $2->addParamList( $6 ); }
2402                | '(' abstract_function ')'                                             // redundant parenthesis
2403                                { $$ = $2; }
2404                ;
2405
2406array_dimension:
2407                                // Only the first dimension can be empty.
2408                '[' push pop ']'
2409                                { $$ = DeclarationNode::newArray( 0, 0, false ); }
2410                | '[' push pop ']' multi_array_dimension
2411                                { $$ = DeclarationNode::newArray( 0, 0, false )->addArray( $5 ); }
2412                | multi_array_dimension
2413                ;
2414
2415multi_array_dimension:
2416                '[' push assignment_expression pop ']'
2417                                { $$ = DeclarationNode::newArray( $3, 0, false ); }
2418                | '[' push '*' pop ']'                                                          // C99
2419                                { $$ = DeclarationNode::newVarArray( 0 ); }
2420                | multi_array_dimension '[' push assignment_expression pop ']'
2421                                { $$ = $1->addArray( DeclarationNode::newArray( $4, 0, false ) ); }
2422                | multi_array_dimension '[' push '*' pop ']'            // C99
2423                                { $$ = $1->addArray( DeclarationNode::newVarArray( 0 ) ); }
2424                ;
2425
2426// This pattern parses a declaration of a parameter abstract variable or function prototype, i.e., there is no
2427// identifier to which the type applies, e.g.:
2428//
2429//              int f( int );                   // abstract variable parameter; no parameter name specified
2430//              int f( int (int) );             // abstract function-prototype parameter; no parameter name specified
2431//
2432// The pattern precludes declaring an array of functions versus a pointer to an array of functions, and
2433// returning arrays and functions versus pointers to arrays and functions.
2434
2435abstract_parameter_declarator:
2436                abstract_parameter_ptr
2437                | abstract_parameter_array attribute_list_opt
2438                | abstract_parameter_function attribute_list_opt
2439                ;
2440
2441abstract_parameter_ptr:
2442                '*'
2443                                { $$ = DeclarationNode::newPointer( 0 ); }
2444                | '*' type_qualifier_list
2445                                { $$ = DeclarationNode::newPointer( $2 ); }
2446                | '*' abstract_parameter_declarator
2447                                { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
2448                | '*' type_qualifier_list abstract_parameter_declarator
2449                                { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
2450                | '(' abstract_parameter_ptr ')'
2451                                { $$ = $2; }
2452                ;
2453
2454abstract_parameter_array:
2455                array_parameter_dimension
2456                | '(' abstract_parameter_ptr ')' array_parameter_dimension
2457                                { $$ = $2->addArray( $4 ); }
2458                | '(' abstract_parameter_array ')' multi_array_dimension // redundant parenthesis
2459                                { $$ = $2->addArray( $4 ); }
2460                | '(' abstract_parameter_array ')'                              // redundant parenthesis
2461                                { $$ = $2; }
2462                ;
2463
2464abstract_parameter_function:
2465                '(' push parameter_type_list_opt pop ')'                // empty parameter list OBSOLESCENT (see 3)
2466                                { $$ = DeclarationNode::newFunction( 0, 0, $3, 0 ); }
2467                | '(' abstract_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
2468                                { $$ = $2->addParamList( $6 ); }
2469                | '(' abstract_parameter_function ')'                   // redundant parenthesis
2470                                { $$ = $2; }
2471                ;
2472
2473array_parameter_dimension:
2474                                // Only the first dimension can be empty or have qualifiers.
2475                array_parameter_1st_dimension
2476                | array_parameter_1st_dimension multi_array_dimension
2477                                { $$ = $1->addArray( $2 ); }
2478                | multi_array_dimension
2479                ;
2480
2481// The declaration of an array parameter has additional syntax over arrays in normal variable declarations:
2482//
2483//              ISO/IEC 9899:1999 Section 6.7.5.2(1) : "The optional type qualifiers and the keyword static shall
2484//              appear only in a declaration of a function parameter with an array type, and then only in the
2485//              outermost array type derivation."
2486
2487array_parameter_1st_dimension:
2488                '[' push pop ']'
2489                                { $$ = DeclarationNode::newArray( 0, 0, false ); }
2490                // multi_array_dimension handles the '[' '*' ']' case
2491                | '[' push type_qualifier_list '*' pop ']'              // remaining C99
2492                                { $$ = DeclarationNode::newVarArray( $3 ); }
2493                | '[' push type_qualifier_list pop ']'
2494                                { $$ = DeclarationNode::newArray( 0, $3, false ); }
2495                // multi_array_dimension handles the '[' assignment_expression ']' case
2496                | '[' push type_qualifier_list assignment_expression pop ']'
2497                                { $$ = DeclarationNode::newArray( $4, $3, false ); }
2498                | '[' push STATIC type_qualifier_list_opt assignment_expression pop ']'
2499                                { $$ = DeclarationNode::newArray( $5, $4, true ); }
2500                | '[' push type_qualifier_list STATIC assignment_expression pop ']'
2501                                { $$ = DeclarationNode::newArray( $5, $3, true ); }
2502                ;
2503
2504// This pattern parses a declaration of an abstract variable, i.e., there is no identifier to which the type
2505// applies, e.g.:
2506//
2507//              sizeof( int ); // abstract variable; no identifier name specified
2508//
2509// The pattern precludes declaring an array of functions versus a pointer to an array of functions, and
2510// returning arrays and functions versus pointers to arrays and functions.
2511
2512variable_abstract_declarator:
2513                variable_abstract_ptr
2514                | variable_abstract_array attribute_list_opt
2515                | variable_abstract_function attribute_list_opt
2516                ;
2517
2518variable_abstract_ptr:
2519                '*'
2520                                { $$ = DeclarationNode::newPointer( 0 ); }
2521                | '*' type_qualifier_list
2522                                { $$ = DeclarationNode::newPointer( $2 ); }
2523                | '*' variable_abstract_declarator
2524                                { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
2525                | '*' type_qualifier_list variable_abstract_declarator
2526                                { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
2527                | '(' variable_abstract_ptr ')'
2528                                { $$ = $2; }
2529                ;
2530
2531variable_abstract_array:
2532                array_dimension
2533                | '(' variable_abstract_ptr ')' array_dimension
2534                                { $$ = $2->addArray( $4 ); }
2535                | '(' variable_abstract_array ')' multi_array_dimension // redundant parenthesis
2536                                { $$ = $2->addArray( $4 ); }
2537                | '(' variable_abstract_array ')'                               // redundant parenthesis
2538                                { $$ = $2; }
2539                ;
2540
2541variable_abstract_function:
2542                '(' variable_abstract_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
2543                                { $$ = $2->addParamList( $6 ); }
2544                | '(' variable_abstract_function ')'                    // redundant parenthesis
2545                                { $$ = $2; }
2546                ;
2547
2548// This pattern parses a new-style declaration for a parameter variable or function prototype that is either
2549// an identifier or typedef name and allows the C99 array options, which can only appear in a parameter list.
2550
2551new_identifier_parameter_declarator_tuple:                              // CFA
2552                new_identifier_parameter_declarator_no_tuple
2553                | new_abstract_tuple
2554                | type_qualifier_list new_abstract_tuple
2555                                { $$ = $2->addQualifiers( $1 ); }
2556                ;
2557
2558new_identifier_parameter_declarator_no_tuple:                   // CFA
2559                new_identifier_parameter_ptr
2560                | new_identifier_parameter_array
2561                ;
2562
2563new_identifier_parameter_ptr:                                                   // CFA
2564                '*' type_specifier
2565                                { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
2566                | type_qualifier_list '*' type_specifier
2567                                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
2568                | '*' new_abstract_function
2569                                { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
2570                | type_qualifier_list '*' new_abstract_function
2571                                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
2572                | '*' new_identifier_parameter_declarator_tuple
2573                                { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
2574                | type_qualifier_list '*' new_identifier_parameter_declarator_tuple
2575                                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
2576                ;
2577
2578new_identifier_parameter_array:                                                 // CFA
2579                                // Only the first dimension can be empty or have qualifiers. Empty dimension must be factored
2580                                // out due to shift/reduce conflict with new-style empty (void) function return type.
2581                '[' push pop ']' type_specifier
2582                                { $$ = $5->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
2583                | new_array_parameter_1st_dimension type_specifier
2584                                { $$ = $2->addNewArray( $1 ); }
2585                | '[' push pop ']' multi_array_dimension type_specifier
2586                                { $$ = $6->addNewArray( $5 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
2587                | new_array_parameter_1st_dimension multi_array_dimension type_specifier
2588                                { $$ = $3->addNewArray( $2 )->addNewArray( $1 ); }
2589                | multi_array_dimension type_specifier
2590                                { $$ = $2->addNewArray( $1 ); }
2591                | '[' push pop ']' new_identifier_parameter_ptr
2592                                { $$ = $5->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
2593                | new_array_parameter_1st_dimension new_identifier_parameter_ptr
2594                                { $$ = $2->addNewArray( $1 ); }
2595                | '[' push pop ']' multi_array_dimension new_identifier_parameter_ptr
2596                                { $$ = $6->addNewArray( $5 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
2597                | new_array_parameter_1st_dimension multi_array_dimension new_identifier_parameter_ptr
2598                                { $$ = $3->addNewArray( $2 )->addNewArray( $1 ); }
2599                | multi_array_dimension new_identifier_parameter_ptr
2600                                { $$ = $2->addNewArray( $1 ); }
2601                ;
2602
2603new_array_parameter_1st_dimension:
2604                '[' push type_qualifier_list '*' pop ']'                // remaining C99
2605                                { $$ = DeclarationNode::newVarArray( $3 ); }
2606                | '[' push type_qualifier_list assignment_expression pop ']'
2607                                { $$ = DeclarationNode::newArray( $4, $3, false ); }
2608                | '[' push declaration_qualifier_list assignment_expression pop ']'
2609                                // declaration_qualifier_list must be used because of shift/reduce conflict with
2610                                // assignment_expression, so a semantic check is necessary to preclude them as a
2611                                // type_qualifier cannot appear in this context.
2612                                { $$ = DeclarationNode::newArray( $4, $3, true ); }
2613                | '[' push declaration_qualifier_list type_qualifier_list assignment_expression pop ']'
2614                                { $$ = DeclarationNode::newArray( $5, $4->addQualifiers( $3 ), true ); }
2615                ;
2616
2617// This pattern parses a new-style declaration of an abstract variable or function prototype, i.e., there is
2618// no identifier to which the type applies, e.g.:
2619//
2620//              [int] f( int );                         // abstract variable parameter; no parameter name specified
2621//              [int] f( [int] (int) );         // abstract function-prototype parameter; no parameter name specified
2622//
2623// These rules need LR(3):
2624//
2625//              new_abstract_tuple identifier_or_typedef_name
2626//              '[' new_parameter_list ']' identifier_or_typedef_name '(' new_parameter_type_list_opt ')'
2627//
2628// since a function return type can be syntactically identical to a tuple type:
2629//
2630//              [int, int] t;
2631//              [int, int] f( int );
2632//
2633// Therefore, it is necessary to look at the token after identifier_or_typedef_name to know when to reduce
2634// new_abstract_tuple. To make this LR(1), several rules have to be flattened (lengthened) to allow the
2635// necessary lookahead. To accomplish this, new_abstract_declarator has an entry point without tuple, and
2636// tuple declarations are duplicated when appearing with new_function_specifier.
2637
2638new_abstract_declarator_tuple:                                                  // CFA
2639                new_abstract_tuple
2640                | type_qualifier_list new_abstract_tuple
2641                                { $$ = $2->addQualifiers( $1 ); }
2642                | new_abstract_declarator_no_tuple
2643                ;
2644
2645new_abstract_declarator_no_tuple:                                               // CFA
2646                new_abstract_ptr
2647                | new_abstract_array
2648                ;
2649
2650new_abstract_ptr:                                                                               // CFA
2651                '*' type_specifier
2652                                { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
2653                | type_qualifier_list '*' type_specifier
2654                                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
2655                | '*' new_abstract_function
2656                                { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
2657                | type_qualifier_list '*' new_abstract_function
2658                                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
2659                | '*' new_abstract_declarator_tuple
2660                                { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
2661                | type_qualifier_list '*' new_abstract_declarator_tuple
2662                                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
2663                ;
2664
2665new_abstract_array:                                                                             // CFA
2666                                // Only the first dimension can be empty. Empty dimension must be factored out due to
2667                                // shift/reduce conflict with empty (void) function return type.
2668                '[' push pop ']' type_specifier
2669                                { $$ = $5->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
2670                | '[' push pop ']' multi_array_dimension type_specifier
2671                                { $$ = $6->addNewArray( $5 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
2672                | multi_array_dimension type_specifier
2673                                { $$ = $2->addNewArray( $1 ); }
2674                | '[' push pop ']' new_abstract_ptr
2675                                { $$ = $5->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
2676                | '[' push pop ']' multi_array_dimension new_abstract_ptr
2677                                { $$ = $6->addNewArray( $5 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
2678                | multi_array_dimension new_abstract_ptr
2679                                { $$ = $2->addNewArray( $1 ); }
2680                ;
2681
2682new_abstract_tuple:                                                                             // CFA
2683                '[' push new_abstract_parameter_list pop ']'
2684                                { $$ = DeclarationNode::newTuple( $3 ); }
2685                ;
2686
2687new_abstract_function:                                                                  // CFA
2688                '[' push pop ']' '(' new_parameter_type_list_opt ')'
2689                                { $$ = DeclarationNode::newFunction( 0, DeclarationNode::newTuple( 0 ), $6, 0 ); }
2690                | new_abstract_tuple '(' push new_parameter_type_list_opt pop ')'
2691                                { $$ = DeclarationNode::newFunction( 0, $1, $4, 0 ); }
2692                | new_function_return '(' push new_parameter_type_list_opt pop ')'
2693                                { $$ = DeclarationNode::newFunction( 0, $1, $4, 0 ); }
2694                ;
2695
2696// 1) ISO/IEC 9899:1999 Section 6.7.2(2) : "At least one type specifier shall be given in the declaration
2697//    specifiers in each declaration, and in the specifier-qualifier list in each structure declaration and
2698//    type name."
2699//
2700// 2) ISO/IEC 9899:1999 Section 6.11.5(1) : "The placement of a storage-class specifier other than at the
2701//    beginning of the declaration specifiers in a declaration is an obsolescent feature."
2702//
2703// 3) ISO/IEC 9899:1999 Section 6.11.6(1) : "The use of function declarators with empty parentheses (not
2704//    prototype-format parameter type declarators) is an obsolescent feature."
2705//
2706// 4) ISO/IEC 9899:1999 Section 6.11.7(1) : "The use of function definitions with separate parameter
2707//    identifier and declaration lists (not prototype-format parameter type and identifier declarators) is an
2708//    obsolescent feature.
2709
2710//************************* MISCELLANEOUS ********************************
2711
2712comma_opt:                                                                                              // redundant comma
2713                // empty
2714                | ','
2715                ;
2716
2717assignment_opt:
2718                // empty
2719                                { $$ = 0; }
2720                | '=' assignment_expression
2721                                { $$ = $2; }
2722                ;
2723
2724%%
2725// ----end of grammar----
2726
2727void yyerror( char *string ) {
2728        using std::cout;
2729        using std::endl;
2730        cout << "Error ";
2731        if ( yyfilename ) {
2732                cout << "in file " << yyfilename << " ";
2733        }
2734        cout << "at line " << yylineno << " reading token \"" << *(yylval.tok.str) << "\"" << endl;
2735}
2736
2737// Local Variables: //
2738// fill-column: 110 //
2739// tab-width: 4 //
2740// mode: c++ //
2741// compile-command: "make install" //
2742// End: //
Note: See TracBrowser for help on using the repository browser.