source: translator/Parser/cfa.y@ c11e31c

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors ctor deferred_resn demangler enum forall-pointer-decay gc_noraii jacob/cs343-translation jenkins-sandbox memory new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new string with_gc
Last change on this file since c11e31c was c11e31c, checked in by Peter A. Buhr <pabuhr@…>, 11 years ago

add inline and attribute qualifiers, cfa.y comment formatting, fix error message in isIntegralType

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