Changeset 4d51835


Ignore:
Timestamp:
May 27, 2015, 11:09:08 AM (9 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
Children:
42336618
Parents:
e15b0a0a
Message:

parsing support for nested functions

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/cfa.y

    re15b0a0a r4d51835  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue May 26 22:38:42 2015
    13 // Update Count     : 995
     12// Last Modified On : Wed May 27 09:20:53 2015
     13// Update Count     : 1015
    1414//
    1515
     
    177177%type<en> field field_list
    178178
    179 %type<decl> function_array function_declarator function_definition function_no_ptr function_ptr
     179%type<decl> external_function_definition function_definition function_array function_declarator function_no_ptr function_ptr
    180180
    181181%type<decl> identifier_parameter_array identifier_parameter_declarator identifier_parameter_function
     
    279279
    280280push:
    281                                 {
    282                                         typedefTable.enterScope();
    283                                 }
    284                 ;
     281                {
     282                        typedefTable.enterScope();
     283                }
     284        ;
    285285
    286286pop:
    287                                 {
    288                                         typedefTable.leaveScope();
    289                                 }
    290                 ;
     287                {
     288                        typedefTable.leaveScope();
     289                }
     290        ;
    291291
    292292//************************* CONSTANTS ********************************
    293293
    294294constant:
    295                                 // ENUMERATIONconstant is not included here; it is treated as a variable with type
    296                                 // "enumeration constant".
    297                 INTEGERconstant                                                                 { $$ = new ConstantNode(ConstantNode::Integer, $1); }
    298                 | FLOATINGconstant                                                              { $$ = new ConstantNode(ConstantNode::Float, $1); }
    299                 | CHARACTERconstant                                                             { $$ = new ConstantNode(ConstantNode::Character, $1); }
    300                 ;
     295                // ENUMERATIONconstant is not included here; it is treated as a variable with type
     296                // "enumeration constant".
     297        INTEGERconstant                                                         { $$ = new ConstantNode(ConstantNode::Integer, $1); }
     298        | FLOATINGconstant                                                      { $$ = new ConstantNode(ConstantNode::Float, $1); }
     299        | CHARACTERconstant                                                     { $$ = new ConstantNode(ConstantNode::Character, $1); }
     300        ;
    301301
    302302identifier:
    303                 IDENTIFIER
    304                 | ATTR_IDENTIFIER                                                               // CFA
    305                 | zero_one                                                                              // CFA
    306                 ;
     303        IDENTIFIER
     304        | ATTR_IDENTIFIER                                                                       // CFA
     305        | zero_one                                                                                      // CFA
     306        ;
    307307
    308308no_01_identifier:
    309                 IDENTIFIER
    310                 | ATTR_IDENTIFIER                                                               // CFA
    311                 ;
     309        IDENTIFIER
     310        | ATTR_IDENTIFIER                                                                       // CFA
     311        ;
    312312
    313313no_attr_identifier:
    314                 IDENTIFIER
    315                 ;
     314        IDENTIFIER
     315        ;
    316316
    317317zero_one:                                                                                               // CFA
    318                 ZERO
    319                 | ONE
    320                 ;
     318        ZERO
     319        | ONE
     320        ;
    321321
    322322string_literal_list:                                                                    // juxtaposed strings are concatenated
    323                 STRINGliteral                                                                   { $$ = new ConstantNode(ConstantNode::String, $1); }
    324                 | string_literal_list STRINGliteral                             { $$ = $1->append( $2 ); }
    325                 ;
     323        STRINGliteral                                                           { $$ = new ConstantNode(ConstantNode::String, $1); }
     324        | string_literal_list STRINGliteral                     { $$ = $1->append( $2 ); }
     325        ;
    326326
    327327//************************* EXPRESSIONS ********************************
    328328
    329329primary_expression:
    330                 IDENTIFIER                                                                              // typedef name cannot be used as a variable name
    331                                 { $$ = new VarRefNode($1); }
    332                 | zero_one
    333                                 { $$ = new VarRefNode($1); }
    334                 | constant
    335                                 { $$ = $1; }
    336                 | string_literal_list
    337                                 { $$ = $1; }
    338                 | '(' comma_expression ')'
    339                                 { $$ = $2; }
    340                 | '(' compound_statement ')'                                    // GCC, lambda expression
    341                                 { $$ = new ValofExprNode($2); }
    342                 ;
     330        IDENTIFIER                                                                                      // typedef name cannot be used as a variable name
     331                { $$ = new VarRefNode($1); }
     332        | zero_one
     333                { $$ = new VarRefNode($1); }
     334        | constant
     335                { $$ = $1; }
     336        | string_literal_list
     337                { $$ = $1; }
     338        | '(' comma_expression ')'
     339                { $$ = $2; }
     340        | '(' compound_statement ')'                                            // GCC, lambda expression
     341                { $$ = new ValofExprNode($2); }
     342        ;
    343343
    344344postfix_expression:
    345                 primary_expression
    346                 | postfix_expression '[' push assignment_expression pop ']'
    347                                 // CFA, comma_expression disallowed in the context because it results in a commom user error:
    348                                 // subscripting a matrix with x[i,j] instead of x[i][j]. While this change is not backwards
    349                                 // compatible, there seems to be little advantage to this feature and many disadvantages. It
    350                                 // is possible to write x[(i,j)] in CFA, which is equivalent to the old x[i,j].
    351                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Index), $1, $4); }
    352                 | postfix_expression '(' argument_expression_list ')'
    353                                 { $$ = new CompositeExprNode($1, $3); }
    354                 | postfix_expression '.' no_attr_identifier
    355                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::FieldSel), $1, new VarRefNode($3)); }
    356                 | postfix_expression '.' '[' push field_list pop ']' // CFA, tuple field selector
    357                 | postfix_expression ARROW no_attr_identifier
    358                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::PFieldSel), $1, new VarRefNode($3)); }
    359                 | postfix_expression ARROW '[' push field_list pop ']' // CFA, tuple field selector
    360                 | postfix_expression ICR
    361                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::IncrPost), $1); }
    362                 | postfix_expression DECR
    363                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::DecrPost), $1); }
    364                                 // GCC has priority: cast_expression
    365                 | '(' type_name_no_function ')' '{' initializer_list comma_opt '}' // C99
    366                                 { $$ = 0; }
    367                 ;
     345        primary_expression
     346        | postfix_expression '[' push assignment_expression pop ']'
     347                // CFA, comma_expression disallowed in the context because it results in a commom user error:
     348                // subscripting a matrix with x[i,j] instead of x[i][j]. While this change is not backwards
     349                // compatible, there seems to be little advantage to this feature and many disadvantages. It is
     350                // possible to write x[(i,j)] in CFA, which is equivalent to the old x[i,j].
     351                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Index), $1, $4); }
     352        | postfix_expression '(' argument_expression_list ')'
     353                { $$ = new CompositeExprNode($1, $3); }
     354        | postfix_expression '.' no_attr_identifier
     355                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::FieldSel), $1, new VarRefNode($3)); }
     356        | postfix_expression '.' '[' push field_list pop ']' // CFA, tuple field selector
     357        | postfix_expression ARROW no_attr_identifier
     358                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::PFieldSel), $1, new VarRefNode($3)); }
     359        | postfix_expression ARROW '[' push field_list pop ']' // CFA, tuple field selector
     360        | postfix_expression ICR
     361                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::IncrPost), $1); }
     362        | postfix_expression DECR
     363                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::DecrPost), $1); }
     364                // GCC has priority: cast_expression
     365        | '(' type_name_no_function ')' '{' initializer_list comma_opt '}' // C99
     366                { $$ = 0; }
     367        ;
    368368
    369369argument_expression_list:
    370                 argument_expression
    371                 | argument_expression_list ',' argument_expression
    372                                 { $$ = (ExpressionNode *)($1->set_link($3)); }
    373                 ;
     370        argument_expression
     371        | argument_expression_list ',' argument_expression
     372                { $$ = (ExpressionNode *)($1->set_link($3)); }
     373        ;
    374374
    375375argument_expression:
    376                 // empty
    377                                 { $$ = 0; }                                                             // use default argument
    378                 | assignment_expression
    379                 | no_attr_identifier ':' assignment_expression
    380                                 { $$ = $3->set_asArgName($1); }
    381                                 // Only a list of no_attr_identifier_or_typedef_name is allowed in this context. However,
    382                                 // there is insufficient look ahead to distinguish between this list of parameter names and a
    383                                 // tuple, so the tuple form must be used with an appropriate semantic check.
    384                 | '[' push assignment_expression pop ']' ':' assignment_expression
    385                                 { $$ = $7->set_asArgName($3); }
    386                 | '[' push assignment_expression ',' tuple_expression_list pop ']' ':' assignment_expression
    387                                 { $$ = $9->set_asArgName(new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ), (ExpressionNode *)$3->set_link( flattenCommas( $5 )))); }
    388                 ;
     376        // empty
     377                { $$ = 0; }                                                                             // use default argument
     378        | assignment_expression
     379        | no_attr_identifier ':' assignment_expression
     380                { $$ = $3->set_asArgName($1); }
     381                // Only a list of no_attr_identifier_or_typedef_name is allowed in this context. However, there is
     382                // insufficient look ahead to distinguish between this list of parameter names and a tuple, so the
     383                // tuple form must be used with an appropriate semantic check.
     384        | '[' push assignment_expression pop ']' ':' assignment_expression
     385                { $$ = $7->set_asArgName($3); }
     386        | '[' push assignment_expression ',' tuple_expression_list pop ']' ':' assignment_expression
     387                { $$ = $9->set_asArgName( new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ), (ExpressionNode *)$3->set_link( flattenCommas( $5 )))); }
     388        ;
    389389
    390390field_list:                                                                                             // CFA, tuple field selector
    391                 field
    392                 | field_list ',' field                                                  { $$ = (ExpressionNode *)$1->set_link( $3 ); }
    393                 ;
     391        field
     392        | field_list ',' field                                          { $$ = (ExpressionNode *)$1->set_link( $3 ); }
     393        ;
    394394
    395395field:                                                                                                  // CFA, tuple field selector
    396                 no_attr_identifier
    397                                 { $$ = new VarRefNode( $1 ); }
    398                 | no_attr_identifier '.' field
    399                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::FieldSel), new VarRefNode( $1 ), $3); }
    400                 | no_attr_identifier '.' '[' push field_list pop ']'
    401                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::FieldSel), new VarRefNode( $1 ), $5); }
    402                 | no_attr_identifier ARROW field
    403                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::PFieldSel), new VarRefNode( $1 ), $3); }
    404                 | no_attr_identifier ARROW '[' push field_list pop ']'
    405                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::PFieldSel), new VarRefNode( $1 ), $5); }
    406                 ;
     396        no_attr_identifier
     397                { $$ = new VarRefNode( $1 ); }
     398        | no_attr_identifier '.' field
     399                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::FieldSel), new VarRefNode( $1 ), $3); }
     400        | no_attr_identifier '.' '[' push field_list pop ']'
     401                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::FieldSel), new VarRefNode( $1 ), $5); }
     402        | no_attr_identifier ARROW field
     403                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::PFieldSel), new VarRefNode( $1 ), $3); }
     404        | no_attr_identifier ARROW '[' push field_list pop ']'
     405                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::PFieldSel), new VarRefNode( $1 ), $5); }
     406        ;
    407407
    408408unary_expression:
    409                 postfix_expression
    410                 | ICR unary_expression
    411                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Incr), $2); }
    412                 | DECR unary_expression
    413                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Decr), $2); }
    414                 | EXTENSION cast_expression                                             // GCC
    415                                 { $$ = $2; }
    416                 | unary_operator cast_expression
    417                                 { $$ = new CompositeExprNode($1, $2); }
    418                 | '!' cast_expression
    419                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Neg), $2); }
    420                 | '*' cast_expression                                                   // CFA
    421                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::PointTo), $2); }
    422                                 // '*' is is separated from unary_operator because of shift/reduce conflict in:
    423                                 //              { * X; } // dereference X
    424                                 //              { * int X; } // CFA declaration of pointer to int
    425                                 // '&' must be moved here if C++ reference variables are supported.
    426                 | SIZEOF unary_expression
    427                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::SizeOf), $2); }
    428                 | SIZEOF '(' type_name_no_function ')'
    429                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::SizeOf), new TypeValueNode($3)); }
    430                 | ATTR_IDENTIFIER
    431                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Attr), new VarRefNode($1)); }
    432                 | ATTR_IDENTIFIER '(' type_name ')'
    433                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Attr), new VarRefNode($1), new TypeValueNode($3)); }
    434                 | ATTR_IDENTIFIER '(' argument_expression ')'
    435                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Attr), new VarRefNode($1), $3); }
    436                 | ALIGNOF unary_expression                                              // GCC, variable alignment
    437                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::AlignOf), $2); }
    438                 | ALIGNOF '(' type_name_no_function ')'                 // GCC, type alignment
    439                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::AlignOf), new TypeValueNode($3)); }
    440                 | ANDAND no_attr_identifier                                             // GCC, address of label
    441                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::LabelAddress), new VarRefNode($2, true)); }
    442                 ;
     409        postfix_expression
     410        | ICR unary_expression
     411                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Incr), $2); }
     412        | DECR unary_expression
     413                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Decr), $2); }
     414        | EXTENSION cast_expression                                                     // GCC
     415                { $$ = $2; }
     416        | unary_operator cast_expression
     417                { $$ = new CompositeExprNode($1, $2); }
     418        | '!' cast_expression
     419                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Neg), $2); }
     420        | '*' cast_expression                                                           // CFA
     421                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::PointTo), $2); }
     422                // '*' is is separated from unary_operator because of shift/reduce conflict in:
     423                //              { * X; } // dereference X
     424                //              { * int X; } // CFA declaration of pointer to int
     425                // '&' must be moved here if C++ reference variables are supported.
     426        | SIZEOF unary_expression
     427                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::SizeOf), $2); }
     428        | SIZEOF '(' type_name_no_function ')'
     429                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::SizeOf), new TypeValueNode($3)); }
     430        | ATTR_IDENTIFIER
     431                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Attr), new VarRefNode($1)); }
     432        | ATTR_IDENTIFIER '(' type_name ')'
     433                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Attr), new VarRefNode($1), new TypeValueNode($3)); }
     434        | ATTR_IDENTIFIER '(' argument_expression ')'
     435                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Attr), new VarRefNode($1), $3); }
     436        | ALIGNOF unary_expression                                                      // GCC, variable alignment
     437                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::AlignOf), $2); }
     438        | ALIGNOF '(' type_name_no_function ')'                         // GCC, type alignment
     439                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::AlignOf), new TypeValueNode($3)); }
     440        | ANDAND no_attr_identifier                                                     // GCC, address of label
     441                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::LabelAddress), new VarRefNode($2, true)); }
     442        ;
    443443
    444444unary_operator:
    445                 '&'                                                                                             { $$ = new OperatorNode(OperatorNode::AddressOf); }
    446                 | '+'                                                                                   { $$ = new OperatorNode(OperatorNode::UnPlus); }
    447                 | '-'                                                                                   { $$ = new OperatorNode(OperatorNode::UnMinus); }
    448                 | '~'                                                                                   { $$ = new OperatorNode(OperatorNode::BitNeg); }
    449                 ;
     445        '&'                                                                                     { $$ = new OperatorNode(OperatorNode::AddressOf); }
     446        | '+'                                                                           { $$ = new OperatorNode(OperatorNode::UnPlus); }
     447        | '-'                                                                           { $$ = new OperatorNode(OperatorNode::UnMinus); }
     448        | '~'                                                                           { $$ = new OperatorNode(OperatorNode::BitNeg); }
     449        ;
    450450
    451451cast_expression:
    452                 unary_expression
    453                 | '(' type_name_no_function ')' cast_expression
    454                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Cast), new TypeValueNode($2), $4); }
    455                 | '(' type_name_no_function ')' tuple
    456                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Cast), new TypeValueNode($2), $4); }
    457                 ;
     452        unary_expression
     453        | '(' type_name_no_function ')' cast_expression
     454                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Cast), new TypeValueNode($2), $4); }
     455        | '(' type_name_no_function ')' tuple
     456                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Cast), new TypeValueNode($2), $4); }
     457        ;
    458458
    459459multiplicative_expression:
    460                 cast_expression
    461                 | multiplicative_expression '*' cast_expression
    462                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Mul),$1,$3); }
    463                 | multiplicative_expression '/' cast_expression
    464                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Div),$1,$3); }
    465                 | multiplicative_expression '%' cast_expression
    466                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Mod),$1,$3); }
    467                 ;
     460        cast_expression
     461        | multiplicative_expression '*' cast_expression
     462                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Mul),$1,$3); }
     463        | multiplicative_expression '/' cast_expression
     464                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Div),$1,$3); }
     465        | multiplicative_expression '%' cast_expression
     466                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Mod),$1,$3); }
     467        ;
    468468
    469469additive_expression:
    470                 multiplicative_expression
    471                 | additive_expression '+' multiplicative_expression
    472                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Plus),$1,$3); }
    473                 | additive_expression '-' multiplicative_expression
    474                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Minus),$1,$3); }
    475                 ;
     470        multiplicative_expression
     471        | additive_expression '+' multiplicative_expression
     472                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Plus),$1,$3); }
     473        | additive_expression '-' multiplicative_expression
     474                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Minus),$1,$3); }
     475        ;
    476476
    477477shift_expression:
    478                 additive_expression
    479                 | shift_expression LS additive_expression
    480                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::LShift),$1,$3); }
    481                 | shift_expression RS additive_expression
    482                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::RShift),$1,$3); }
    483                 ;
     478        additive_expression
     479        | shift_expression LS additive_expression
     480                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::LShift),$1,$3); }
     481        | shift_expression RS additive_expression
     482                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::RShift),$1,$3); }
     483        ;
    484484
    485485relational_expression:
    486                 shift_expression
    487                 | relational_expression '<' shift_expression
    488                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::LThan),$1,$3); }
    489                 | relational_expression '>' shift_expression
    490                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::GThan),$1,$3); }
    491                 | relational_expression LE shift_expression
    492                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::LEThan),$1,$3); }
    493                 | relational_expression GE shift_expression
    494                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::GEThan),$1,$3); }
    495                 ;
     486        shift_expression
     487        | relational_expression '<' shift_expression
     488                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::LThan),$1,$3); }
     489        | relational_expression '>' shift_expression
     490                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::GThan),$1,$3); }
     491        | relational_expression LE shift_expression
     492                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::LEThan),$1,$3); }
     493        | relational_expression GE shift_expression
     494                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::GEThan),$1,$3); }
     495        ;
    496496
    497497equality_expression:
    498                 relational_expression
    499                 | equality_expression EQ relational_expression
    500                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Eq), $1, $3); }
    501                 | equality_expression NE relational_expression
    502                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Neq), $1, $3); }
    503                 ;
     498        relational_expression
     499        | equality_expression EQ relational_expression
     500                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Eq), $1, $3); }
     501        | equality_expression NE relational_expression
     502                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Neq), $1, $3); }
     503        ;
    504504
    505505AND_expression:
    506                 equality_expression
    507                 | AND_expression '&' equality_expression
    508                                 { $$ =new CompositeExprNode(new OperatorNode(OperatorNode::BitAnd), $1, $3); }
    509                 ;
     506        equality_expression
     507        | AND_expression '&' equality_expression
     508                { $$ =new CompositeExprNode(new OperatorNode(OperatorNode::BitAnd), $1, $3); }
     509        ;
    510510
    511511exclusive_OR_expression:
    512                 AND_expression
    513                 | exclusive_OR_expression '^' AND_expression
    514                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Xor), $1, $3); }
    515                 ;
     512        AND_expression
     513        | exclusive_OR_expression '^' AND_expression
     514                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Xor), $1, $3); }
     515        ;
    516516
    517517inclusive_OR_expression:
    518                 exclusive_OR_expression
    519                 | inclusive_OR_expression '|' exclusive_OR_expression
    520                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::BitOr), $1, $3); }
    521                 ;
     518        exclusive_OR_expression
     519        | inclusive_OR_expression '|' exclusive_OR_expression
     520                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::BitOr), $1, $3); }
     521        ;
    522522
    523523logical_AND_expression:
    524                 inclusive_OR_expression
    525                 | logical_AND_expression ANDAND inclusive_OR_expression
    526                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::And), $1, $3); }
    527                 ;
     524        inclusive_OR_expression
     525        | logical_AND_expression ANDAND inclusive_OR_expression
     526                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::And), $1, $3); }
     527        ;
    528528
    529529logical_OR_expression:
    530                 logical_AND_expression
    531                 | logical_OR_expression OROR logical_AND_expression
    532                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Or), $1, $3); }
    533                 ;
     530        logical_AND_expression
     531        | logical_OR_expression OROR logical_AND_expression
     532                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Or), $1, $3); }
     533        ;
    534534
    535535conditional_expression:
    536                 logical_OR_expression
    537                 | logical_OR_expression '?' comma_expression ':' conditional_expression
    538                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Cond), (ExpressionNode *)mkList((*$1,*$3,*$5))); }
    539                 | logical_OR_expression '?' /* empty */ ':' conditional_expression // GCC, omitted first operand
    540                                 { $$=new CompositeExprNode(new OperatorNode(OperatorNode::NCond),$1,$4); }
    541                 | logical_OR_expression '?' comma_expression ':' tuple // CFA, tuple expression
    542                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Cond), (ExpressionNode *)mkList(( *$1, *$3, *$5 ))); }
    543                 ;
     536        logical_OR_expression
     537        | logical_OR_expression '?' comma_expression ':' conditional_expression
     538                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Cond), (ExpressionNode *)mkList((*$1,*$3,*$5))); }
     539        | logical_OR_expression '?' /* empty */ ':' conditional_expression // GCC, omitted first operand
     540                { $$=new CompositeExprNode(new OperatorNode(OperatorNode::NCond),$1,$4); }
     541        | logical_OR_expression '?' comma_expression ':' tuple // CFA, tuple expression
     542                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Cond), (ExpressionNode *)mkList(( *$1, *$3, *$5 ))); }
     543        ;
    544544
    545545constant_expression:
    546                 conditional_expression
    547                 ;
     546        conditional_expression
     547        ;
    548548
    549549assignment_expression:
    550                                 // CFA, assignment is separated from assignment_operator to ensure no assignment operations
    551                                 // for tuples
    552                 conditional_expression
    553                 | unary_expression '=' assignment_expression
    554                                 { $$ =new CompositeExprNode(new OperatorNode(OperatorNode::Assign), $1, $3); }
    555                 | unary_expression assignment_operator assignment_expression
    556                                 { $$ =new CompositeExprNode($2, $1, $3); }
    557                 | tuple assignment_opt                                                  // CFA, tuple expression
    558                                 { $$ = ($2 == 0) ? $1 : new CompositeExprNode( new OperatorNode( OperatorNode::Assign ), $1, $2 ); }
    559                 ;
     550                // CFA, assignment is separated from assignment_operator to ensure no assignment operations for tuples
     551        conditional_expression
     552        | unary_expression '=' assignment_expression
     553                { $$ =new CompositeExprNode(new OperatorNode(OperatorNode::Assign), $1, $3); }
     554        | unary_expression assignment_operator assignment_expression
     555                { $$ =new CompositeExprNode($2, $1, $3); }
     556        | tuple assignment_opt                                                          // CFA, tuple expression
     557                { $$ = ($2 == 0) ? $1 : new CompositeExprNode( new OperatorNode( OperatorNode::Assign ), $1, $2 ); }
     558        ;
    560559
    561560assignment_expression_opt:
    562                 // empty
    563                                 { $$ = new NullExprNode; }
    564                 | assignment_expression
    565                 ;
     561        // empty
     562                { $$ = new NullExprNode; }
     563        | assignment_expression
     564        ;
    566565
    567566tuple:                                                                                                  // CFA, tuple
    568                                 // CFA, one assignment_expression is factored out of comma_expression to eliminate a
    569                                 // shift/reduce conflict with comma_expression in new_identifier_parameter_array and
    570                                 // new_abstract_array
    571                 '[' push pop ']'
    572                                 { $$ = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ) ); }
    573                 | '[' push assignment_expression pop ']'
    574                                 { $$ = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ), $3 ); }
    575                 | '[' push ',' tuple_expression_list pop ']'
    576                                 { $$ = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ), (ExpressionNode *)(new NullExprNode)->set_link( $4 ) ); }
    577                 | '[' push assignment_expression ',' tuple_expression_list pop ']'
    578                                 { $$ = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ), (ExpressionNode *)$3->set_link( flattenCommas( $5 ) ) ); }
    579                 ;
     567                // CFA, one assignment_expression is factored out of comma_expression to eliminate a shift/reduce
     568                // conflict with comma_expression in new_identifier_parameter_array and new_abstract_array
     569        '[' push pop ']'
     570                { $$ = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ) ); }
     571        | '[' push assignment_expression pop ']'
     572                { $$ = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ), $3 ); }
     573        | '[' push ',' tuple_expression_list pop ']'
     574                { $$ = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ), (ExpressionNode *)(new NullExprNode)->set_link( $4 ) ); }
     575        | '[' push assignment_expression ',' tuple_expression_list pop ']'
     576                { $$ = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ), (ExpressionNode *)$3->set_link( flattenCommas( $5 ) ) ); }
     577        ;
    580578
    581579tuple_expression_list:
    582                 assignment_expression_opt
    583                 | tuple_expression_list ',' assignment_expression_opt
    584                                 { $$ = (ExpressionNode *)$1->set_link( $3 ); }
    585                 ;
     580        assignment_expression_opt
     581        | tuple_expression_list ',' assignment_expression_opt
     582                { $$ = (ExpressionNode *)$1->set_link( $3 ); }
     583        ;
    586584
    587585assignment_operator:
    588                 MULTassign                                                                              { $$ = new OperatorNode(OperatorNode::MulAssn); }
    589                 | DIVassign                                                                             { $$ = new OperatorNode(OperatorNode::DivAssn); }
    590                 | MODassign                                                                             { $$ = new OperatorNode(OperatorNode::ModAssn); }
    591                 | PLUSassign                                                                    { $$ = new OperatorNode(OperatorNode::PlusAssn); }
    592                 | MINUSassign                                                                   { $$ = new OperatorNode(OperatorNode::MinusAssn); }
    593                 | LSassign                                                                              { $$ = new OperatorNode(OperatorNode::LSAssn); }
    594                 | RSassign                                                                              { $$ = new OperatorNode(OperatorNode::RSAssn); }
    595                 | ANDassign                                                                             { $$ = new OperatorNode(OperatorNode::AndAssn); }
    596                 | ERassign                                                                              { $$ = new OperatorNode(OperatorNode::ERAssn); }
    597                 | ORassign                                                                              { $$ = new OperatorNode(OperatorNode::OrAssn); }
    598                 ;
     586        MULTassign                                                                      { $$ = new OperatorNode(OperatorNode::MulAssn); }
     587        | DIVassign                                                                     { $$ = new OperatorNode(OperatorNode::DivAssn); }
     588        | MODassign                                                                     { $$ = new OperatorNode(OperatorNode::ModAssn); }
     589        | PLUSassign                                                            { $$ = new OperatorNode(OperatorNode::PlusAssn); }
     590        | MINUSassign                                                           { $$ = new OperatorNode(OperatorNode::MinusAssn); }
     591        | LSassign                                                                      { $$ = new OperatorNode(OperatorNode::LSAssn); }
     592        | RSassign                                                                      { $$ = new OperatorNode(OperatorNode::RSAssn); }
     593        | ANDassign                                                                     { $$ = new OperatorNode(OperatorNode::AndAssn); }
     594        | ERassign                                                                      { $$ = new OperatorNode(OperatorNode::ERAssn); }
     595        | ORassign                                                                      { $$ = new OperatorNode(OperatorNode::OrAssn); }
     596        ;
    599597
    600598comma_expression:
    601                 assignment_expression
    602                 | comma_expression ',' assignment_expression    // { $$ = (ExpressionNode *)$1->add_to_list($3); }
    603                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Comma),$1,$3); }
    604                 ;
     599        assignment_expression
     600        | comma_expression ',' assignment_expression    // { $$ = (ExpressionNode *)$1->add_to_list($3); }
     601                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Comma),$1,$3); }
     602        ;
    605603
    606604comma_expression_opt:
    607                 // empty
    608                                 { $$ = 0; }
    609                 | comma_expression
    610                 ;
     605        // empty
     606                { $$ = 0; }
     607        | comma_expression
     608        ;
    611609
    612610//*************************** STATEMENTS *******************************
    613611
    614612statement:
    615                 labeled_statement
    616                 | compound_statement
    617                 | expression_statement                                                  { $$ = $1; }
    618                 | selection_statement
    619                 | iteration_statement
    620                 | jump_statement
    621                 | exception_statement
    622                 | asm_statement
    623                 ;
     613        labeled_statement
     614        | compound_statement
     615        | expression_statement                                          { $$ = $1; }
     616        | selection_statement
     617        | iteration_statement
     618        | jump_statement
     619        | exception_statement
     620        | asm_statement
     621        ;
    624622
    625623labeled_statement:
    626                 no_attr_identifier ':' attribute_list_opt statement
    627                                 { $$ = $4->add_label($1);}
    628                 ;
     624        no_attr_identifier ':' attribute_list_opt statement
     625                { $$ = $4->add_label($1);}
     626        ;
    629627
    630628compound_statement:
    631                 '{' '}'
    632                                 { $$ = new CompoundStmtNode( (StatementNode *)0 ); }
    633                 | '{'
    634                                 // Two scopes are necessary because the block itself has a scope, but every declaration within
    635                                 // the block also requires its own scope
    636                   push push
    637                   label_declaration_opt                                                 // GCC, local labels
    638                   block_item_list pop '}'                                               // C99, intermix declarations and statements
    639                                 { $$ = new CompoundStmtNode( $5 ); }
    640                 ;
     629        '{' '}'
     630                { $$ = new CompoundStmtNode( (StatementNode *)0 ); }
     631        | '{'
     632                // Two scopes are necessary because the block itself has a scope, but every declaration within the
     633                // block also requires its own scope
     634          push push
     635          label_declaration_opt                                                         // GCC, local labels
     636          block_item_list pop '}'                                                       // C99, intermix declarations and statements
     637                { $$ = new CompoundStmtNode( $5 ); }
     638        ;
    641639
    642640block_item_list:                                                                                // C99
    643                 block_item
    644                 | block_item_list push block_item
    645                                 { if ($1 != 0) { $1->set_link($3); $$ = $1; } }
    646                 ;
     641        block_item
     642        | block_item_list push block_item
     643                { if ($1 != 0) { $1->set_link($3); $$ = $1; } }
     644        ;
    647645
    648646block_item:
    649                 declaration                                                                             // CFA, new & old style declarations
    650                                 { $$ = new StatementNode( $1 ); }
    651                 | EXTENSION declaration                                                 // GCC
    652                                 { $$ = new StatementNode( $2 ); }
    653                 | statement pop
    654                 ;
     647        declaration                                                                                     // CFA, new & old style declarations
     648                { $$ = new StatementNode( $1 ); }
     649        | EXTENSION declaration                                                         // GCC
     650                { $$ = new StatementNode( $2 ); }
     651        | function_definition
     652                { $$ = new StatementNode( $1 ); }
     653        | statement pop
     654        ;
    655655
    656656statement_list:
    657                 statement
    658                 | statement_list statement
    659                                 { if ($1 != 0) { $1->set_link($2); $$ = $1; } }
    660                 ;
     657        statement
     658        | statement_list statement
     659                { if ($1 != 0) { $1->set_link($2); $$ = $1; } }
     660        ;
    661661
    662662expression_statement:
    663                 comma_expression_opt ';'
    664                                 { $$ = new StatementNode(StatementNode::Exp, $1, 0); }
    665                 ;
     663        comma_expression_opt ';'
     664                { $$ = new StatementNode(StatementNode::Exp, $1, 0); }
     665        ;
    666666
    667667selection_statement:
    668                 IF '(' comma_expression ')' statement                           %prec THEN
    669                                 // explicitly deal with the shift/reduce conflict on if/else
    670                                 { $$ = new StatementNode(StatementNode::If, $3, $5); }
    671                 | IF '(' comma_expression ')' statement ELSE statement
    672                                 { $$ = new StatementNode(StatementNode::If, $3, (StatementNode *)mkList((*$5, *$7)) ); }
    673                 | SWITCH '(' comma_expression ')' case_clause   // CFA
    674                                 { $$ = new StatementNode(StatementNode::Switch, $3, $5); }
    675                 | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt '}' // CFA
    676                                 { $$ = new StatementNode(StatementNode::Switch, $3, $8); /* xxx */ }
    677                                 // The semantics of the declaration list is changed to include any associated initialization,
    678                                 // which is performed *before* the transfer to the appropriate case clause.  Statements after
    679                                 // the initial declaration list can never be executed, and therefore, are removed from the
    680                                 // grammar even though C allows it.
    681                 | CHOOSE '(' comma_expression ')' case_clause   // CFA
    682                                 { $$ = new StatementNode(StatementNode::Choose, $3, $5); }
    683                 | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt choose_clause_list_opt '}' // CFA
    684                                 { $$ = new StatementNode(StatementNode::Choose, $3, $8); }
    685                 ;
     668        IF '(' comma_expression ')' statement                           %prec THEN
     669                // explicitly deal with the shift/reduce conflict on if/else
     670                { $$ = new StatementNode(StatementNode::If, $3, $5); }
     671        | IF '(' comma_expression ')' statement ELSE statement
     672                { $$ = new StatementNode(StatementNode::If, $3, (StatementNode *)mkList((*$5, *$7)) ); }
     673        | SWITCH '(' comma_expression ')' case_clause           // CFA
     674                { $$ = new StatementNode(StatementNode::Switch, $3, $5); }
     675        | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt '}' // CFA
     676                { $$ = new StatementNode(StatementNode::Switch, $3, $8); /* xxx */ }
     677                // The semantics of the declaration list is changed to include any associated initialization, which is
     678                // performed *before* the transfer to the appropriate case clause.  Statements after the initial
     679                // declaration list can never be executed, and therefore, are removed from the grammar even though C
     680                // allows it.
     681        | CHOOSE '(' comma_expression ')' case_clause           // CFA
     682                { $$ = new StatementNode(StatementNode::Choose, $3, $5); }
     683        | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt choose_clause_list_opt '}' // CFA
     684                { $$ = new StatementNode(StatementNode::Choose, $3, $8); }
     685        ;
    686686
    687687// CASE and DEFAULT clauses are only allowed in the SWITCH statement, precluding Duff's device. In addition, a
     
    689689
    690690case_value:                                                                                             // CFA
    691                 constant_expression                                                             { $$ = $1; }
    692                 | constant_expression ELLIPSIS constant_expression // GCC, subrange
    693                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Range),$1,$3); }
    694                 | subrange                                                                              // CFA, subrange
    695                 ;
     691        constant_expression                                                     { $$ = $1; }
     692        | constant_expression ELLIPSIS constant_expression      // GCC, subrange
     693                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Range),$1,$3); }
     694        | subrange                                                                                      // CFA, subrange
     695        ;
    696696
    697697case_value_list:                                                                                // CFA
    698                 case_value
    699                 | case_value_list ',' case_value
    700                                 { $$ = new CompositeExprNode(new OperatorNode( OperatorNode::TupleC ), (ExpressionNode *)(tupleContents($1))->set_link($3) ); }
    701                 ;
     698        case_value
     699        | case_value_list ',' case_value
     700                { $$ = new CompositeExprNode(new OperatorNode( OperatorNode::TupleC ), (ExpressionNode *)(tupleContents($1))->set_link($3) ); }
     701        ;
    702702
    703703case_label:                                                                                             // CFA
    704                 CASE case_value_list ':'                                                { $$ = new StatementNode(StatementNode::Case, $2, 0); }
    705                 | DEFAULT ':'                                                               { $$ = new StatementNode(StatementNode::Default); }
    706                                 // A semantic check is required to ensure only one default clause per switch/choose statement.
    707                 ;
     704        CASE case_value_list ':'                                        { $$ = new StatementNode(StatementNode::Case, $2, 0); }
     705        | DEFAULT ':'                                                           { $$ = new StatementNode(StatementNode::Default); }
     706                // A semantic check is required to ensure only one default clause per switch/choose statement.
     707        ;
    708708
    709709case_label_list:                                                                                // CFA
    710                 case_label
    711                 | case_label_list case_label                                    { $$ = (StatementNode *)($1->set_link($2)); }
    712                 ;
     710        case_label
     711        | case_label_list case_label                            { $$ = (StatementNode *)($1->set_link($2)); }
     712        ;
    713713
    714714case_clause:                                                                                    // CFA
    715                 case_label_list statement                                               { $$ = $1->append_last_case($2); }
    716                 ;
     715        case_label_list statement                                       { $$ = $1->append_last_case($2); }
     716        ;
    717717
    718718switch_clause_list_opt:                                                                 // CFA
    719                 // empty
    720                                 { $$ = 0; }
    721                 | switch_clause_list
    722                 ;
     719        // empty
     720                { $$ = 0; }
     721        | switch_clause_list
     722        ;
    723723
    724724switch_clause_list:                                                                             // CFA
    725                 case_label_list statement_list
    726                                 { $$ = $1->append_last_case($2); }
    727                 | switch_clause_list case_label_list statement_list
    728                                 { $$ = (StatementNode *)($1->set_link($2->append_last_case($3))); }
    729                 ;
     725        case_label_list statement_list
     726                { $$ = $1->append_last_case($2); }
     727        | switch_clause_list case_label_list statement_list
     728                { $$ = (StatementNode *)($1->set_link($2->append_last_case($3))); }
     729        ;
    730730
    731731choose_clause_list_opt:                                                                 // CFA
    732                 // empty
    733                                 { $$ = 0; }
    734                 | choose_clause_list
    735                 ;
     732        // empty
     733                { $$ = 0; }
     734        | choose_clause_list
     735        ;
    736736
    737737choose_clause_list:                                                                             // CFA
    738                 case_label_list fall_through
    739                                 { $$ = $1->append_last_case($2); }
    740                 | case_label_list statement_list fall_through_opt
    741                                 { $$ = $1->append_last_case((StatementNode *)mkList((*$2,*$3))); }
    742                 | choose_clause_list case_label_list fall_through
    743                                 { $$ = (StatementNode *)($1->set_link($2->append_last_case($3))); }
    744                 | choose_clause_list case_label_list statement_list fall_through_opt
    745                                 { $$ = (StatementNode *)($1->set_link($2->append_last_case((StatementNode *)mkList((*$3,*$4))))); }
    746                 ;
     738        case_label_list fall_through
     739                { $$ = $1->append_last_case($2); }
     740        | case_label_list statement_list fall_through_opt
     741                { $$ = $1->append_last_case((StatementNode *)mkList((*$2,*$3))); }
     742        | choose_clause_list case_label_list fall_through
     743                { $$ = (StatementNode *)($1->set_link($2->append_last_case($3))); }
     744        | choose_clause_list case_label_list statement_list fall_through_opt
     745                { $$ = (StatementNode *)($1->set_link($2->append_last_case((StatementNode *)mkList((*$3,*$4))))); }
     746        ;
    747747
    748748fall_through_opt:                                                                               // CFA
    749                 // empty
    750                                 { $$ = 0; }
    751                 | fall_through
    752                 ;
     749        // empty
     750                { $$ = 0; }
     751        | fall_through
     752        ;
    753753
    754754fall_through:                                                                                   // CFA
    755                 FALLTHRU                                                                                { $$ = new StatementNode(StatementNode::Fallthru, 0, 0); }
    756                 | FALLTHRU ';'                                                                  { $$ = new StatementNode(StatementNode::Fallthru, 0, 0); }
    757                 ;
     755        FALLTHRU                                                                        { $$ = new StatementNode(StatementNode::Fallthru, 0, 0); }
     756        | FALLTHRU ';'                                                          { $$ = new StatementNode(StatementNode::Fallthru, 0, 0); }
     757        ;
    758758
    759759iteration_statement:
    760                 WHILE '(' comma_expression ')' statement
    761                                 { $$ = new StatementNode(StatementNode::While, $3, $5); }
    762                 | DO statement WHILE '(' comma_expression ')' ';'
    763                                 { $$ = new StatementNode(StatementNode::Do, $5, $2); }
    764                 | FOR '(' push for_control_expression ')' statement
    765                                 { $$ = new StatementNode(StatementNode::For, $4, $6); }
    766                 ;
     760        WHILE '(' comma_expression ')' statement
     761                { $$ = new StatementNode(StatementNode::While, $3, $5); }
     762        | DO statement WHILE '(' comma_expression ')' ';'
     763                { $$ = new StatementNode(StatementNode::Do, $5, $2); }
     764        | FOR '(' push for_control_expression ')' statement
     765                { $$ = new StatementNode(StatementNode::For, $4, $6); }
     766        ;
    767767
    768768for_control_expression:
    769                 comma_expression_opt pop ';' comma_expression_opt ';' comma_expression_opt
    770                                 { $$ = new ForCtlExprNode($1, $4, $6); }
    771                 | declaration comma_expression_opt ';' comma_expression_opt // C99
    772                                 // Like C++, the loop index can be declared local to the loop.
    773                                 { $$ = new ForCtlExprNode($1, $2, $4); }
    774                 ;
     769        comma_expression_opt pop ';' comma_expression_opt ';' comma_expression_opt
     770                { $$ = new ForCtlExprNode($1, $4, $6); }
     771        | declaration comma_expression_opt ';' comma_expression_opt // C99
     772                // Like C++, the loop index can be declared local to the loop.
     773                { $$ = new ForCtlExprNode($1, $2, $4); }
     774        ;
    775775
    776776jump_statement:
    777                 GOTO no_attr_identifier ';'
    778                                 { $$ = new StatementNode(StatementNode::Goto, $2); }
    779                 | GOTO '*' comma_expression ';'                         // GCC, computed goto
    780                                 // The syntax for the GCC computed goto violates normal expression precedence, e.g., goto
    781                                 // *i+3; => goto *(i+3); whereas normal operator precedence yields goto (*i)+3;
    782                                 { $$ = new StatementNode(StatementNode::Goto, $3); }
    783                 | CONTINUE ';'
    784                                 // A semantic check is required to ensure this statement appears only in the body of an
    785                                 // iteration statement.
    786                                 { $$ = new StatementNode(StatementNode::Continue, 0, 0); }
    787                 | CONTINUE no_attr_identifier ';'               // CFA, multi-level continue
    788                                 // A semantic check is required to ensure this statement appears only in the body of an
    789                                 // iteration statement, and the target of the transfer appears only at the start of an
    790                                 // iteration statement.
    791                                 { $$ = new StatementNode(StatementNode::Continue, $2); }
    792                 | BREAK ';'
    793                                 // A semantic check is required to ensure this statement appears only in the body of an
    794                                 // iteration statement.
    795                                 { $$ = new StatementNode(StatementNode::Break, 0, 0); }
    796                 | BREAK no_attr_identifier ';'                          // CFA, multi-level exit
    797                                 // A semantic check is required to ensure this statement appears only in the body of an
    798                                 // iteration statement, and the target of the transfer appears only at the start of an
    799                                 // iteration statement.
    800                                 { $$ = new StatementNode(StatementNode::Break, $2 ); }
    801                 | RETURN comma_expression_opt ';'
    802                                 { $$ = new StatementNode(StatementNode::Return, $2, 0); }
    803                 | THROW assignment_expression ';'
    804                                 { $$ = new StatementNode(StatementNode::Throw, $2, 0); }
    805                 | THROW ';'
    806                                 { $$ = new StatementNode(StatementNode::Throw, 0, 0); }
    807                 ;
     777        GOTO no_attr_identifier ';'
     778                { $$ = new StatementNode(StatementNode::Goto, $2); }
     779        | GOTO '*' comma_expression ';'                                         // GCC, computed goto
     780                // The syntax for the GCC computed goto violates normal expression precedence, e.g., goto *i+3; =>
     781                // goto *(i+3); whereas normal operator precedence yields goto (*i)+3;
     782                { $$ = new StatementNode(StatementNode::Goto, $3); }
     783        | CONTINUE ';'
     784                // A semantic check is required to ensure this statement appears only in the body of an iteration
     785                // statement.
     786                { $$ = new StatementNode(StatementNode::Continue, 0, 0); }
     787        | CONTINUE no_attr_identifier ';'                                       // CFA, multi-level continue
     788                // A semantic check is required to ensure this statement appears only in the body of an iteration
     789                // statement, and the target of the transfer appears only at the start of an iteration statement.
     790                { $$ = new StatementNode(StatementNode::Continue, $2); }
     791        | BREAK ';'
     792                // A semantic check is required to ensure this statement appears only in the body of an iteration
     793                // statement.
     794                { $$ = new StatementNode(StatementNode::Break, 0, 0); }
     795        | BREAK no_attr_identifier ';'                                          // CFA, multi-level exit
     796                // A semantic check is required to ensure this statement appears only in the body of an iteration
     797                // statement, and the target of the transfer appears only at the start of an iteration statement.
     798                { $$ = new StatementNode(StatementNode::Break, $2 ); }
     799        | RETURN comma_expression_opt ';'
     800                { $$ = new StatementNode(StatementNode::Return, $2, 0); }
     801        | THROW assignment_expression ';'
     802                { $$ = new StatementNode(StatementNode::Throw, $2, 0); }
     803        | THROW ';'
     804                { $$ = new StatementNode(StatementNode::Throw, 0, 0); }
     805        ;
    808806
    809807exception_statement:
    810                 TRY compound_statement handler_list
    811                                 { $$ = new StatementNode(StatementNode::Try, 0,(StatementNode *)(mkList((*$2,*$3)))); }
    812                 | TRY compound_statement finally_clause
    813                                 { $$ = new StatementNode(StatementNode::Try, 0,(StatementNode *)(mkList((*$2,*$3)))); }
    814                 | TRY compound_statement handler_list finally_clause
    815                                 {
    816                                         $3->set_link($4);
    817                                         $$ = new StatementNode(StatementNode::Try, 0,(StatementNode *)(mkList((*$2,*$3))));
    818                                 }
    819                 ;
     808        TRY compound_statement handler_list
     809                { $$ = new StatementNode(StatementNode::Try, 0,(StatementNode *)(mkList((*$2,*$3)))); }
     810        | TRY compound_statement finally_clause
     811                { $$ = new StatementNode(StatementNode::Try, 0,(StatementNode *)(mkList((*$2,*$3)))); }
     812        | TRY compound_statement handler_list finally_clause
     813                {
     814                        $3->set_link($4);
     815                        $$ = new StatementNode(StatementNode::Try, 0,(StatementNode *)(mkList((*$2,*$3))));
     816                }
     817        ;
    820818
    821819handler_list:
    822                                 // There must be at least one catch clause
    823                 handler_clause
    824                                 // ISO/IEC 9899:1999 Section 15.3(6) If present, a "..." handler shall be the last handler for
    825                                 // its try block.
    826                 | CATCH '(' ELLIPSIS ')' compound_statement
    827                                 { $$ = StatementNode::newCatchStmt( 0, $5, true ); }
    828                 | handler_clause CATCH '(' ELLIPSIS ')' compound_statement
    829                                 { $$ = $1->set_link( StatementNode::newCatchStmt( 0, $6, true ) ); }
    830                 ;
     820                // There must be at least one catch clause
     821        handler_clause
     822                // ISO/IEC 9899:1999 Section 15.3(6) If present, a "..." handler shall be the last handler for its try
     823                // block.
     824        | CATCH '(' ELLIPSIS ')' compound_statement
     825                { $$ = StatementNode::newCatchStmt( 0, $5, true ); }
     826        | handler_clause CATCH '(' ELLIPSIS ')' compound_statement
     827                { $$ = $1->set_link( StatementNode::newCatchStmt( 0, $6, true ) ); }
     828        ;
    831829
    832830handler_clause:
    833                 CATCH '(' push push exception_declaration pop ')' compound_statement pop
    834                                 { $$ = StatementNode::newCatchStmt($5, $8); }
    835                 | handler_clause CATCH '(' push push exception_declaration pop ')' compound_statement pop
    836                                 { $$ = $1->set_link( StatementNode::newCatchStmt($6, $9) ); }
    837                 ;
     831        CATCH '(' push push exception_declaration pop ')' compound_statement pop
     832                { $$ = StatementNode::newCatchStmt($5, $8); }
     833        | handler_clause CATCH '(' push push exception_declaration pop ')' compound_statement pop
     834                { $$ = $1->set_link( StatementNode::newCatchStmt($6, $9) ); }
     835        ;
    838836
    839837finally_clause:
    840                 FINALLY compound_statement
    841                                 { $$ = new StatementNode(StatementNode::Finally, 0, $2);
    842                                         std::cout << "Just created a finally node" << std::endl;
    843                                 }
    844                 ;
     838        FINALLY compound_statement
     839                {
     840                        $$ = new StatementNode(StatementNode::Finally, 0, $2);
     841                        std::cout << "Just created a finally node" << std::endl;
     842                }
     843        ;
    845844
    846845exception_declaration:
    847                                 // A semantic check is required to ensure type_specifier does not create a new type, e.g.:
    848                                 //
    849                                 //              catch ( struct { int i; } x ) ...
    850                                 //
    851                                 // This new type cannot catch any thrown type because of name equivalence among types.
    852                 type_specifier
    853                 | type_specifier declarator
    854                                 {
    855                                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    856                                         $$ = $2->addType( $1 );
    857                                 }
    858                 | type_specifier variable_abstract_declarator
    859                                 { $$ = $2->addType( $1 ); }
    860                 | new_abstract_declarator_tuple no_attr_identifier // CFA
    861                                 {
    862                                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    863                                         $$ = $1->addName( $2 );
    864                                 }
    865                 | new_abstract_declarator_tuple                                 // CFA
    866                 ;
     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        ;
    867866
    868867asm_statement:
    869                 ASM type_qualifier_list_opt '(' constant_expression ')' ';'
    870                                 { $$ = new StatementNode(StatementNode::Asm, 0, 0); }
    871                 | ASM type_qualifier_list_opt '(' constant_expression ':' asm_operands_opt ')' ';' // remaining GCC
    872                                 { $$ = new StatementNode(StatementNode::Asm, 0, 0); }
    873                 | ASM type_qualifier_list_opt '(' constant_expression ':' asm_operands_opt ':' asm_operands_opt ')' ';'
    874                                 { $$ = new StatementNode(StatementNode::Asm, 0, 0); }
    875                 | ASM type_qualifier_list_opt '(' constant_expression ':' asm_operands_opt ':' asm_operands_opt ':'
    876                                                 asm_clobbers_list ')' ';'
    877                                 { $$ = new StatementNode(StatementNode::Asm, 0, 0); }
    878                 ;
     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 ':' asm_clobbers_list ')' ';'
     875                { $$ = new StatementNode(StatementNode::Asm, 0, 0); }
     876        ;
    879877
    880878asm_operands_opt:                                                                               // GCC
    881                 // empty
    882                 | asm_operands_list
    883                 ;
     879        // empty
     880        | asm_operands_list
     881        ;
    884882
    885883asm_operands_list:                                                                              // GCC
    886                 asm_operand
    887                 | asm_operands_list ',' asm_operand
    888                 ;
     884        asm_operand
     885        | asm_operands_list ',' asm_operand
     886        ;
    889887
    890888asm_operand:                                                                                    // GCC
    891                 STRINGliteral '(' constant_expression ')'               {}
    892                 ;
     889        STRINGliteral '(' constant_expression ')'               {}
     890        ;
    893891
    894892asm_clobbers_list:                                                                              // GCC
    895                 STRINGliteral                                                                   {}
    896                 | asm_clobbers_list ',' STRINGliteral
    897                 ;
     893        STRINGliteral                                                           {}
     894        | asm_clobbers_list ',' STRINGliteral
     895        ;
    898896
    899897//******************************* DECLARATIONS *********************************
    900898
    901899declaration_list_opt:                                                                   // used at beginning of switch statement
    902                 pop
    903                                 { $$ = 0; }
    904                 | declaration_list
    905                 ;
     900        pop
     901                { $$ = 0; }
     902        | declaration_list
     903        ;
    906904
    907905declaration_list:
    908                 declaration
    909                 | declaration_list push declaration
    910                                 { $$ = $1->appendList( $3 ); }
    911                 ;
     906        declaration
     907        | declaration_list push declaration
     908                { $$ = $1->appendList( $3 ); }
     909        ;
    912910
    913911old_declaration_list_opt:                                                               // used to declare parameter types in K&R style functions
    914                 pop
    915                                 { $$ = 0; }
    916                 | old_declaration_list
    917                 ;
     912        pop
     913                { $$ = 0; }
     914        | old_declaration_list
     915        ;
    918916
    919917old_declaration_list:
    920                 old_declaration
    921                 | old_declaration_list push old_declaration
    922                                 { $$ = $1->appendList( $3 ); }
    923                 ;
     918        old_declaration
     919        | old_declaration_list push old_declaration
     920                { $$ = $1->appendList( $3 ); }
     921        ;
    924922
    925923label_declaration_opt:                                                                  // GCC, local label
    926                 // empty
    927                 | label_declaration_list
    928                 ;
     924        // empty
     925        | label_declaration_list
     926        ;
    929927
    930928label_declaration_list:                                                                 // GCC, local label
    931                 LABEL label_list ';'
    932                 | label_declaration_list LABEL label_list ';'
    933                 ;
     929        LABEL label_list ';'
     930        | label_declaration_list LABEL label_list ';'
     931        ;
    934932
    935933label_list:                                                                                             // GCC, local label
    936                 no_attr_identifier_or_typedef_name                              {}
    937                 | label_list ',' no_attr_identifier_or_typedef_name {}
    938                 ;
     934        no_attr_identifier_or_typedef_name                      {}
     935        | label_list ',' no_attr_identifier_or_typedef_name {}
     936        ;
    939937
    940938declaration:                                                                                    // CFA, new & old style declarations
    941                 new_declaration
    942                 | old_declaration
    943                 ;
     939        new_declaration
     940        | old_declaration
     941        ;
    944942
    945943// C declaration syntax is notoriously confusing and error prone. Cforall provides its own type, variable and
     
    956954
    957955new_declaration:                                                                                // CFA
    958                 new_variable_declaration pop ';'
    959                 | new_typedef_declaration pop ';'
    960                 | new_function_declaration pop ';'
    961                 | type_declaring_list pop ';'
    962                 | context_specifier pop ';'
    963                 ;
     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        ;
    964962
    965963new_variable_declaration:                                                               // CFA
    966                 new_variable_specifier initializer_opt
    967                                 {
    968                                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    969                                         $$ = $1;
    970                                 }
    971                 | declaration_qualifier_list new_variable_specifier initializer_opt
    972                                 // declaration_qualifier_list also includes type_qualifier_list, so a semantic check is
    973                                 // necessary to preclude them as a type_qualifier cannot appear in that context.
    974                                 {
    975                                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    976                                         $$ = $2->addQualifiers( $1 );
    977                                 }
    978                 | new_variable_declaration pop ',' push identifier_or_typedef_name initializer_opt
    979                                 {
    980                                         typedefTable.addToEnclosingScope( *$5, TypedefTable::ID );
    981                                         $$ = $1->appendList( $1->cloneType( $5 ) );
    982                                 }
    983                 ;
     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        ;
    984982
    985983new_variable_specifier:                                                                 // CFA
    986                                 // A semantic check is required to ensure asm_name only appears on declarations with implicit
    987                                 // or explicit static storage-class
    988                 new_abstract_declarator_no_tuple identifier_or_typedef_name asm_name_opt
    989                                 {
    990                                         typedefTable.setNextIdentifier( *$2 );
    991                                         $$ = $1->addName( $2 );
    992                                 }
    993                 | new_abstract_tuple identifier_or_typedef_name asm_name_opt
    994                                 {
    995                                         typedefTable.setNextIdentifier( *$2 );
    996                                         $$ = $1->addName( $2 );
    997                                 }
    998                 | type_qualifier_list new_abstract_tuple identifier_or_typedef_name asm_name_opt
    999                                 {
    1000                                         typedefTable.setNextIdentifier( *$3 );
    1001                                         $$ = $2->addQualifiers( $1 )->addName( $3 );
    1002                                 }
    1003                 ;
     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        ;
    10041002
    10051003new_function_declaration:                                                               // CFA
    1006                 new_function_specifier
    1007                                 {
    1008                                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    1009                                         $$ = $1;
    1010                                 }
    1011                 | type_qualifier_list new_function_specifier
    1012                                 {
    1013                                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    1014                                         $$ = $2->addQualifiers( $1 );
    1015                                 }
    1016                 | declaration_qualifier_list new_function_specifier
    1017                                 {
    1018                                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    1019                                         $$ = $2->addQualifiers( $1 );
    1020                                 }
    1021                 | declaration_qualifier_list type_qualifier_list new_function_specifier
    1022                                 {
    1023                                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    1024                                         $$ = $3->addQualifiers( $1 )->addQualifiers( $2 );
    1025                                 }
    1026                 | new_function_declaration pop ',' push identifier_or_typedef_name
    1027                                 {
    1028                                         typedefTable.addToEnclosingScope( *$5, TypedefTable::ID );
    1029                                         $$ = $1->appendList( $1->cloneType( $5 ) );
    1030                                 }
    1031                 ;
     1004        new_function_specifier
     1005                {
     1006                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     1007                        $$ = $1;
     1008                }
     1009        | type_qualifier_list new_function_specifier
     1010                {
     1011                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     1012                        $$ = $2->addQualifiers( $1 );
     1013                }
     1014        | declaration_qualifier_list new_function_specifier
     1015                {
     1016                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     1017                        $$ = $2->addQualifiers( $1 );
     1018                }
     1019        | declaration_qualifier_list type_qualifier_list new_function_specifier
     1020                {
     1021                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     1022                        $$ = $3->addQualifiers( $1 )->addQualifiers( $2 );
     1023                }
     1024        | new_function_declaration pop ',' push identifier_or_typedef_name
     1025                {
     1026                        typedefTable.addToEnclosingScope( *$5, TypedefTable::ID );
     1027                        $$ = $1->appendList( $1->cloneType( $5 ) );
     1028                }
     1029        ;
    10321030
    10331031new_function_specifier:                                                                 // CFA
    1034                 '[' push pop ']' identifier '(' push new_parameter_type_list_opt pop ')'
    1035                                 {
    1036                                         typedefTable.setNextIdentifier( *($5) );
    1037                                         $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true );
    1038                                 }
    1039                 | '[' push pop ']' TYPEDEFname '(' push new_parameter_type_list_opt pop ')'
    1040                                 {
    1041                                         typedefTable.setNextIdentifier( *($5) );
    1042                                         $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true );
    1043                                 }
    1044                                 // identifier_or_typedef_name must be broken apart because of the sequence:
    1045                                 //
    1046                                 //   '[' ']' identifier_or_typedef_name '(' new_parameter_type_list_opt ')'
    1047                                 //   '[' ']' type_specifier
    1048                                 //
    1049                                 // type_specifier can resolve to just TYPEDEFname (e.g. typedef int T; int f( T );). Therefore
    1050                                 // this must be flattened to allow lookahead to the '(' without having to reduce
    1051                                 // identifier_or_typedef_name.
    1052                 | new_abstract_tuple identifier_or_typedef_name '(' push new_parameter_type_list_opt pop ')'
    1053                                 // To obtain LR(1), this rule must be factored out from function return type (see
    1054                                 //   new_abstract_declarator).
    1055                                 {
    1056                                         $$ = DeclarationNode::newFunction( $2, $1, $5, 0, true );
    1057                                 }
    1058                 | new_function_return identifier_or_typedef_name '(' push new_parameter_type_list_opt pop ')'
    1059                                 {
    1060                                         $$ = DeclarationNode::newFunction( $2, $1, $5, 0, true );
    1061                                 }
    1062                 ;
     1032        '[' push pop ']' identifier '(' push new_parameter_type_list_opt pop ')'
     1033                {
     1034                        typedefTable.setNextIdentifier( *($5) );
     1035                        $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true );
     1036                }
     1037        | '[' push pop ']' TYPEDEFname '(' push new_parameter_type_list_opt pop ')'
     1038                {
     1039                        typedefTable.setNextIdentifier( *($5) );
     1040                        $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true );
     1041                }
     1042                // identifier_or_typedef_name must be broken apart because of the sequence:
     1043                //
     1044                //   '[' ']' identifier_or_typedef_name '(' new_parameter_type_list_opt ')'
     1045                //   '[' ']' type_specifier
     1046                //
     1047                // type_specifier can resolve to just TYPEDEFname (e.g. typedef int T; int f( T );). Therefore this
     1048                // must be flattened to allow lookahead to the '(' without having to reduce
     1049                // identifier_or_typedef_name.
     1050        | new_abstract_tuple identifier_or_typedef_name '(' push new_parameter_type_list_opt pop ')'
     1051                // To obtain LR(1), this rule must be factored out from function return type (see
     1052                //   new_abstract_declarator).
     1053                {
     1054                        $$ = DeclarationNode::newFunction( $2, $1, $5, 0, true );
     1055                }
     1056        | new_function_return identifier_or_typedef_name '(' push new_parameter_type_list_opt pop ')'
     1057                {
     1058                        $$ = DeclarationNode::newFunction( $2, $1, $5, 0, true );
     1059                }
     1060        ;
    10631061
    10641062new_function_return:                                                                    // CFA
    1065                 '[' push new_parameter_list pop ']'
    1066                                 { $$ = DeclarationNode::newTuple( $3 ); }
    1067                 | '[' push new_parameter_list pop ',' push new_abstract_parameter_list pop ']'
    1068                                 // To obtain LR(1), the last new_abstract_parameter_list is added into this flattened rule to
    1069                                 // lookahead to the ']'.
    1070                                 { $$ = DeclarationNode::newTuple( $3->appendList( $7 ) ); }
    1071                 ;
     1063        '[' push new_parameter_list pop ']'
     1064                { $$ = DeclarationNode::newTuple( $3 ); }
     1065        | '[' push new_parameter_list pop ',' push new_abstract_parameter_list pop ']'
     1066                // To obtain LR(1), the last new_abstract_parameter_list is added into this flattened rule to
     1067                // lookahead to the ']'.
     1068                { $$ = DeclarationNode::newTuple( $3->appendList( $7 ) ); }
     1069        ;
    10721070
    10731071new_typedef_declaration:                                                                // CFA
    1074                 TYPEDEF new_variable_specifier
    1075                                 {
    1076                                         typedefTable.addToEnclosingScope( TypedefTable::TD);
    1077                                         $$ = $2->addTypedef();
    1078                                 }
    1079                 | TYPEDEF new_function_specifier
    1080                                 {
    1081                                         typedefTable.addToEnclosingScope( TypedefTable::TD);
    1082                                         $$ = $2->addTypedef();
    1083                                 }
    1084                 | new_typedef_declaration pop ',' push no_attr_identifier
    1085                                 {
    1086                                         typedefTable.addToEnclosingScope( *$5, TypedefTable::TD);
    1087                                         $$ = $1->appendList( $1->cloneType( $5 ) );
    1088                                 }
    1089                 ;
     1072        TYPEDEF new_variable_specifier
     1073                {
     1074                        typedefTable.addToEnclosingScope( TypedefTable::TD);
     1075                        $$ = $2->addTypedef();
     1076                }
     1077        | TYPEDEF new_function_specifier
     1078                {
     1079                        typedefTable.addToEnclosingScope( TypedefTable::TD);
     1080                        $$ = $2->addTypedef();
     1081                }
     1082        | new_typedef_declaration pop ',' push no_attr_identifier
     1083                {
     1084                        typedefTable.addToEnclosingScope( *$5, TypedefTable::TD);
     1085                        $$ = $1->appendList( $1->cloneType( $5 ) );
     1086                }
     1087        ;
    10901088
    10911089// Traditionally typedef is part of storage-class specifier for syntactic convenience only. Here, it is
     
    10941092
    10951093typedef_declaration:
    1096                 TYPEDEF type_specifier declarator
    1097                                 {
    1098                                         typedefTable.addToEnclosingScope( TypedefTable::TD);
    1099                                         $$ = $3->addType( $2 )->addTypedef();
    1100                                 }
    1101                 | typedef_declaration pop ',' push declarator
    1102                                 {
    1103                                         typedefTable.addToEnclosingScope( TypedefTable::TD);
    1104                                         $$ = $1->appendList( $1->cloneBaseType( $5 )->addTypedef() );
    1105                                 }
    1106                 | type_qualifier_list TYPEDEF type_specifier declarator // remaining OBSOLESCENT (see 2)
    1107                                 {
    1108                                         typedefTable.addToEnclosingScope( TypedefTable::TD);
    1109                                         $$ = $4->addType( $3 )->addQualifiers( $1 )->addTypedef();
    1110                                 }
    1111                 | type_specifier TYPEDEF declarator
    1112                                 {
    1113                                         typedefTable.addToEnclosingScope( TypedefTable::TD);
    1114                                         $$ = $3->addType( $1 )->addTypedef();
    1115                                 }
    1116                 | type_specifier TYPEDEF type_qualifier_list declarator
    1117                                 {
    1118                                         typedefTable.addToEnclosingScope( TypedefTable::TD);
    1119                                         $$ = $4->addQualifiers($1)->addTypedef()->addType($1);
    1120                                 }
    1121                 ;
     1094        TYPEDEF type_specifier declarator
     1095                {
     1096                        typedefTable.addToEnclosingScope( TypedefTable::TD);
     1097                        $$ = $3->addType( $2 )->addTypedef();
     1098                }
     1099        | typedef_declaration pop ',' push declarator
     1100                {
     1101                        typedefTable.addToEnclosingScope( TypedefTable::TD);
     1102                        $$ = $1->appendList( $1->cloneBaseType( $5 )->addTypedef() );
     1103                }
     1104        | type_qualifier_list TYPEDEF type_specifier declarator // remaining OBSOLESCENT (see 2)
     1105                {
     1106                        typedefTable.addToEnclosingScope( TypedefTable::TD);
     1107                        $$ = $4->addType( $3 )->addQualifiers( $1 )->addTypedef();
     1108                }
     1109        | type_specifier TYPEDEF declarator
     1110                {
     1111                        typedefTable.addToEnclosingScope( TypedefTable::TD);
     1112                        $$ = $3->addType( $1 )->addTypedef();
     1113                }
     1114        | type_specifier TYPEDEF type_qualifier_list declarator
     1115                {
     1116                        typedefTable.addToEnclosingScope( TypedefTable::TD);
     1117                        $$ = $4->addQualifiers($1)->addTypedef()->addType($1);
     1118                }
     1119        ;
    11221120
    11231121typedef_expression:                                                                             // GCC, naming expression type
    1124                 TYPEDEF no_attr_identifier '=' assignment_expression
    1125                                 {
    1126                                         typedefTable.addToEnclosingScope(*($2), TypedefTable::TD);
    1127                                         $$ = DeclarationNode::newName( 0 ); // XXX
    1128                                 }
    1129                 | typedef_expression pop ',' push no_attr_identifier '=' assignment_expression
    1130                                 {
    1131                                         typedefTable.addToEnclosingScope(*($5), TypedefTable::TD);
    1132                                         $$ = DeclarationNode::newName( 0 ); // XXX
    1133                                 }
    1134                 ;
     1122        TYPEDEF no_attr_identifier '=' assignment_expression
     1123                {
     1124                        typedefTable.addToEnclosingScope(*($2), TypedefTable::TD);
     1125                        $$ = DeclarationNode::newName( 0 ); // XXX
     1126                }
     1127        | typedef_expression pop ',' push no_attr_identifier '=' assignment_expression
     1128                {
     1129                        typedefTable.addToEnclosingScope(*($5), TypedefTable::TD);
     1130                        $$ = DeclarationNode::newName( 0 ); // XXX
     1131                }
     1132        ;
    11351133
    11361134old_declaration:
    1137                 declaring_list pop ';'
    1138                 | typedef_declaration pop ';'
    1139                 | typedef_expression pop ';'                                    // GCC, naming expression type
    1140                 | sue_declaration_specifier pop ';'
    1141                 ;
     1135        declaring_list pop ';'
     1136        | typedef_declaration pop ';'
     1137        | typedef_expression pop ';'                                            // GCC, naming expression type
     1138        | sue_declaration_specifier pop ';'
     1139        ;
    11421140
    11431141declaring_list:
    1144                                 // A semantic check is required to ensure asm_name only appears on declarations with implicit
    1145                                 // or explicit static storage-class
    1146                 declaration_specifier declarator asm_name_opt initializer_opt
    1147                                 {
    1148                                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    1149                                         $$ = ($2->addType( $1 ))->addInitializer($4);
    1150                                 }
    1151                 | declaring_list ',' attribute_list_opt declarator asm_name_opt initializer_opt
    1152                                 {
    1153                                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    1154                                         $$ = $1->appendList( $1->cloneBaseType( $4->addInitializer($6) ) );
    1155                                 }
    1156                 ;
     1142                // A semantic check is required to ensure asm_name only appears on declarations with implicit or
     1143                // explicit static storage-class
     1144        declaration_specifier declarator asm_name_opt initializer_opt
     1145                {
     1146                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     1147                        $$ = ($2->addType( $1 ))->addInitializer($4);
     1148                }
     1149        | declaring_list ',' attribute_list_opt declarator asm_name_opt initializer_opt
     1150                {
     1151                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     1152                        $$ = $1->appendList( $1->cloneBaseType( $4->addInitializer($6) ) );
     1153                }
     1154        ;
    11571155
    11581156declaration_specifier:                                                                  // type specifier + storage class
    1159                 basic_declaration_specifier
    1160                 | sue_declaration_specifier
    1161                 | typedef_declaration_specifier
    1162                 | typegen_declaration_specifier
    1163                 ;
     1157        basic_declaration_specifier
     1158        | sue_declaration_specifier
     1159        | typedef_declaration_specifier
     1160        | typegen_declaration_specifier
     1161        ;
    11641162
    11651163type_specifier:                                                                                 // declaration specifier - storage class
    1166                 basic_type_specifier
    1167                 | sue_type_specifier
    1168                 | typedef_type_specifier
    1169                 | typegen_type_specifier
    1170                 ;
     1164        basic_type_specifier
     1165        | sue_type_specifier
     1166        | typedef_type_specifier
     1167        | typegen_type_specifier
     1168        ;
    11711169
    11721170type_qualifier_list_opt:                                                                // GCC, used in asm_statement
    1173                 // empty
    1174                                 { $$ = 0; }
    1175                 | type_qualifier_list
    1176                 ;
     1171        // empty
     1172                { $$ = 0; }
     1173        | type_qualifier_list
     1174        ;
    11771175
    11781176type_qualifier_list:
    1179                                 // A semantic check is necessary to ensure a type qualifier is appropriate for the kind of
    1180                                 // declaration.
    1181                                 //
    1182                                 // ISO/IEC 9899:1999 Section 6.7.3(4) : If the same qualifier appears more than once in the
    1183                                 // same specifier-qualifier-list, either directly or via one or more typedefs, the behavior is
    1184                                 // the same as if it appeared only once.
    1185                 type_qualifier
    1186                 | type_qualifier_list type_qualifier
    1187                                 { $$ = $1->addQualifiers( $2 ); }
    1188                 ;
     1177                // A semantic check is necessary to ensure a type qualifier is appropriate for the kind of
     1178                // declaration.
     1179                //
     1180                // ISO/IEC 9899:1999 Section 6.7.3(4) : If the same qualifier appears more than once in the same
     1181                // specifier-qualifier-list, either directly or via one or more typedefs, the behavior is the same as
     1182                // if it appeared only once.
     1183        type_qualifier
     1184        | type_qualifier_list type_qualifier
     1185                { $$ = $1->addQualifiers( $2 ); }
     1186        ;
    11891187
    11901188type_qualifier:
    1191                 type_qualifier_name
    1192                 | attribute
    1193                                 { $$ = DeclarationNode::newQualifier( DeclarationNode::Attribute ); }
    1194                 ;
     1189        type_qualifier_name
     1190        | attribute
     1191                { $$ = DeclarationNode::newQualifier( DeclarationNode::Attribute ); }
     1192        ;
    11951193
    11961194type_qualifier_name:
    1197                 CONST
    1198                                 { $$ = DeclarationNode::newQualifier( DeclarationNode::Const ); }
    1199                 | RESTRICT
    1200                                 { $$ = DeclarationNode::newQualifier( DeclarationNode::Restrict ); }
    1201                 | VOLATILE
    1202                                 { $$ = DeclarationNode::newQualifier( DeclarationNode::Volatile ); }
    1203                 | LVALUE                                                                                // CFA
    1204                                 { $$ = DeclarationNode::newQualifier( DeclarationNode::Lvalue ); }
    1205                 | ATOMIC
    1206                                 { $$ = DeclarationNode::newQualifier( DeclarationNode::Atomic ); }
    1207                 | FORALL '('
    1208                                 {
    1209                                         typedefTable.enterScope();
    1210                                 }
    1211                   type_parameter_list ')'                                               // CFA
    1212                                 {
    1213                                         typedefTable.leaveScope();
    1214                                         $$ = DeclarationNode::newForall( $4 );
    1215                                 }
    1216                 ;
     1195        CONST
     1196                { $$ = DeclarationNode::newQualifier( DeclarationNode::Const ); }
     1197        | RESTRICT
     1198                { $$ = DeclarationNode::newQualifier( DeclarationNode::Restrict ); }
     1199        | VOLATILE
     1200                { $$ = DeclarationNode::newQualifier( DeclarationNode::Volatile ); }
     1201        | LVALUE                                                                                        // CFA
     1202                { $$ = DeclarationNode::newQualifier( DeclarationNode::Lvalue ); }
     1203        | ATOMIC
     1204                { $$ = DeclarationNode::newQualifier( DeclarationNode::Atomic ); }
     1205        | FORALL '('
     1206                {
     1207                        typedefTable.enterScope();
     1208                }
     1209          type_parameter_list ')'                                                       // CFA
     1210                {
     1211                        typedefTable.leaveScope();
     1212                        $$ = DeclarationNode::newForall( $4 );
     1213                }
     1214        ;
    12171215
    12181216declaration_qualifier_list:
    1219                 storage_class_list
    1220                 | type_qualifier_list storage_class_list                // remaining OBSOLESCENT (see 2)
    1221                                 { $$ = $1->addQualifiers( $2 ); }
    1222                 | declaration_qualifier_list type_qualifier_list storage_class_list
    1223                                 { $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }
    1224                 ;
     1217        storage_class_list
     1218        | type_qualifier_list storage_class_list                        // remaining OBSOLESCENT (see 2)
     1219                { $$ = $1->addQualifiers( $2 ); }
     1220        | declaration_qualifier_list type_qualifier_list storage_class_list
     1221                { $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }
     1222        ;
    12251223
    12261224storage_class_list:
    1227                                 // A semantic check is necessary to ensure a storage class is appropriate for the kind of
    1228                                 // declaration and that only one of each is specified, except for inline, which can appear
    1229                                 // with the others.
    1230                                 //
    1231                                 // ISO/IEC 9899:1999 Section 6.7.1(2) : At most, one storage-class specifier may be given in
    1232                                 // the declaration specifiers in a declaration.
    1233                 storage_class
    1234                 | storage_class_list storage_class
    1235                                 { $$ = $1->addQualifiers( $2 ); }
    1236                 ;
     1225                // A semantic check is necessary to ensure a storage class is appropriate for the kind of declaration
     1226                // and that only one of each is specified, except for inline, which can appear with the others.
     1227                //
     1228                // ISO/IEC 9899:1999 Section 6.7.1(2) : At most, one storage-class specifier may be given in the
     1229                // declaration specifiers in a declaration.
     1230        storage_class
     1231        | storage_class_list storage_class
     1232                { $$ = $1->addQualifiers( $2 ); }
     1233        ;
    12371234
    12381235storage_class:
    1239                 storage_class_name
    1240                 ;
     1236        storage_class_name
     1237        ;
    12411238
    12421239storage_class_name:
    1243                 EXTERN
    1244                                 { $$ = DeclarationNode::newStorageClass( DeclarationNode::Extern ); }
    1245                 | STATIC
    1246                                 { $$ = DeclarationNode::newStorageClass( DeclarationNode::Static ); }
    1247                 | AUTO
    1248                                 { $$ = DeclarationNode::newStorageClass( DeclarationNode::Auto ); }
    1249                 | REGISTER
    1250                                 { $$ = DeclarationNode::newStorageClass( DeclarationNode::Register ); }
    1251                 | INLINE                                                                                // C99
    1252                                 // INLINE is essentially a storage class specifier for functions, and hence, belongs here.
    1253                                 { $$ = DeclarationNode::newStorageClass( DeclarationNode::Inline ); }
    1254                 | FORTRAN                                                                               // C99
    1255                                 { $$ = DeclarationNode::newStorageClass( DeclarationNode::Fortran ); }
    1256                 ;
     1240        EXTERN
     1241                { $$ = DeclarationNode::newStorageClass( DeclarationNode::Extern ); }
     1242        | STATIC
     1243                { $$ = DeclarationNode::newStorageClass( DeclarationNode::Static ); }
     1244        | AUTO
     1245                { $$ = DeclarationNode::newStorageClass( DeclarationNode::Auto ); }
     1246        | REGISTER
     1247                { $$ = DeclarationNode::newStorageClass( DeclarationNode::Register ); }
     1248        | INLINE                                                                                        // C99
     1249                // INLINE is essentially a storage class specifier for functions, and hence, belongs here.
     1250                { $$ = DeclarationNode::newStorageClass( DeclarationNode::Inline ); }
     1251        | FORTRAN                                                                                       // C99
     1252                { $$ = DeclarationNode::newStorageClass( DeclarationNode::Fortran ); }
     1253        ;
    12571254
    12581255basic_type_name:
    1259                 CHAR
    1260                                 { $$ = DeclarationNode::newBasicType( DeclarationNode::Char ); }
    1261                 | DOUBLE
    1262                                 { $$ = DeclarationNode::newBasicType( DeclarationNode::Double ); }
    1263                 | FLOAT
    1264                                 { $$ = DeclarationNode::newBasicType( DeclarationNode::Float ); }
    1265                 | INT
    1266                                 { $$ = DeclarationNode::newBasicType( DeclarationNode::Int ); }
    1267                 | LONG
    1268                                 { $$ = DeclarationNode::newModifier( DeclarationNode::Long ); }
    1269                 | SHORT
    1270                                 { $$ = DeclarationNode::newModifier( DeclarationNode::Short ); }
    1271                 | SIGNED
    1272                                 { $$ = DeclarationNode::newModifier( DeclarationNode::Signed ); }
    1273                 | UNSIGNED
    1274                                 { $$ = DeclarationNode::newModifier( DeclarationNode::Unsigned ); }
    1275                 | VOID
    1276                                 { $$ = DeclarationNode::newBasicType( DeclarationNode::Void ); }
    1277                 | BOOL                                                                                  // C99
    1278                                 { $$ = DeclarationNode::newBasicType( DeclarationNode::Bool ); }
    1279                 | COMPLEX                                                                               // C99
    1280                                 { $$ = DeclarationNode::newBasicType( DeclarationNode::Complex ); }
    1281                 | IMAGINARY                                                                             // C99
    1282                                 { $$ = DeclarationNode::newBasicType( DeclarationNode::Imaginary ); }
    1283                 ;
     1256        CHAR
     1257                { $$ = DeclarationNode::newBasicType( DeclarationNode::Char ); }
     1258        | DOUBLE
     1259                { $$ = DeclarationNode::newBasicType( DeclarationNode::Double ); }
     1260        | FLOAT
     1261                { $$ = DeclarationNode::newBasicType( DeclarationNode::Float ); }
     1262        | INT
     1263                { $$ = DeclarationNode::newBasicType( DeclarationNode::Int ); }
     1264        | LONG
     1265                { $$ = DeclarationNode::newModifier( DeclarationNode::Long ); }
     1266        | SHORT
     1267                { $$ = DeclarationNode::newModifier( DeclarationNode::Short ); }
     1268        | SIGNED
     1269                { $$ = DeclarationNode::newModifier( DeclarationNode::Signed ); }
     1270        | UNSIGNED
     1271                { $$ = DeclarationNode::newModifier( DeclarationNode::Unsigned ); }
     1272        | VOID
     1273                { $$ = DeclarationNode::newBasicType( DeclarationNode::Void ); }
     1274        | BOOL                                                                                          // C99
     1275                { $$ = DeclarationNode::newBasicType( DeclarationNode::Bool ); }
     1276        | COMPLEX                                                                                       // C99
     1277                { $$ = DeclarationNode::newBasicType( DeclarationNode::Complex ); }
     1278        | IMAGINARY                                                                                     // C99
     1279                { $$ = DeclarationNode::newBasicType( DeclarationNode::Imaginary ); }
     1280        ;
    12841281
    12851282basic_declaration_specifier:
    1286                                 // A semantic check is necessary for conflicting storage classes.
    1287                 basic_type_specifier
    1288                 | declaration_qualifier_list basic_type_specifier
    1289                                 { $$ = $2->addQualifiers( $1 ); }
    1290                 | basic_declaration_specifier storage_class             // remaining OBSOLESCENT (see 2)
    1291                                 { $$ = $1->addQualifiers( $2 ); }
    1292                 | basic_declaration_specifier storage_class type_qualifier_list
    1293                                 { $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }
    1294                 | basic_declaration_specifier storage_class basic_type_specifier
    1295                                 { $$ = $3->addQualifiers( $2 )->addType( $1 ); }
    1296                 ;
     1283                // A semantic check is necessary for conflicting storage classes.
     1284        basic_type_specifier
     1285        | declaration_qualifier_list basic_type_specifier
     1286                { $$ = $2->addQualifiers( $1 ); }
     1287        | basic_declaration_specifier storage_class                     // remaining OBSOLESCENT (see 2)
     1288                { $$ = $1->addQualifiers( $2 ); }
     1289        | basic_declaration_specifier storage_class type_qualifier_list
     1290                { $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }
     1291        | basic_declaration_specifier storage_class basic_type_specifier
     1292                { $$ = $3->addQualifiers( $2 )->addType( $1 ); }
     1293        ;
    12971294
    12981295basic_type_specifier:
    1299                 direct_type_name
    1300                 | type_qualifier_list_opt indirect_type_name type_qualifier_list_opt
    1301                                 { $$ = $2->addQualifiers( $1 )->addQualifiers( $3 ); }
    1302                 ;
     1296        direct_type_name
     1297        | type_qualifier_list_opt indirect_type_name type_qualifier_list_opt
     1298                { $$ = $2->addQualifiers( $1 )->addQualifiers( $3 ); }
     1299        ;
    13031300
    13041301direct_type_name:
    1305                                 // A semantic check is necessary for conflicting type qualifiers.
    1306                 basic_type_name
    1307                 | type_qualifier_list basic_type_name
    1308                                 { $$ = $2->addQualifiers( $1 ); }
    1309                 | direct_type_name type_qualifier
    1310                                 { $$ = $1->addQualifiers( $2 ); }
    1311                 | direct_type_name basic_type_name
    1312                                 { $$ = $1->addType( $2 ); }
    1313                 ;
     1302                // A semantic check is necessary for conflicting type qualifiers.
     1303        basic_type_name
     1304        | type_qualifier_list basic_type_name
     1305                { $$ = $2->addQualifiers( $1 ); }
     1306        | direct_type_name type_qualifier
     1307                { $$ = $1->addQualifiers( $2 ); }
     1308        | direct_type_name basic_type_name
     1309                { $$ = $1->addType( $2 ); }
     1310        ;
    13141311
    13151312indirect_type_name:
    1316                 TYPEOF '(' type_name ')'                                                // GCC: typeof(x) y;
    1317                                 { $$ = $3; }
    1318                 | TYPEOF '(' comma_expression ')'                               // GCC: typeof(a+b) y;
    1319                                 { $$ = DeclarationNode::newTypeof( $3 ); }
    1320                 | ATTR_TYPEGENname '(' type_name ')'                    // CFA: e.g., @type(x) y;
    1321                                 { $$ = DeclarationNode::newAttr( $1, $3 ); }
    1322                 | ATTR_TYPEGENname '(' comma_expression ')'             // CFA: e.g., @type(a+b) y;
    1323                                 { $$ = DeclarationNode::newAttr( $1, $3 ); }
    1324                 ;
     1313        TYPEOF '(' type_name ')'                                                        // GCC: typeof(x) y;
     1314                { $$ = $3; }
     1315        | TYPEOF '(' comma_expression ')'                                       // GCC: typeof(a+b) y;
     1316                { $$ = DeclarationNode::newTypeof( $3 ); }
     1317        | ATTR_TYPEGENname '(' type_name ')'                            // CFA: e.g., @type(x) y;
     1318                { $$ = DeclarationNode::newAttr( $1, $3 ); }
     1319        | ATTR_TYPEGENname '(' comma_expression ')'                     // CFA: e.g., @type(a+b) y;
     1320                { $$ = DeclarationNode::newAttr( $1, $3 ); }
     1321        ;
    13251322
    13261323sue_declaration_specifier:
    1327                 sue_type_specifier
    1328                 | declaration_qualifier_list sue_type_specifier
    1329                                 { $$ = $2->addQualifiers( $1 ); }
    1330                 | sue_declaration_specifier storage_class               // remaining OBSOLESCENT (see 2)
    1331                                 { $$ = $1->addQualifiers( $2 ); }
    1332                 | sue_declaration_specifier storage_class type_qualifier_list
    1333                                 { $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }
    1334                 ;
     1324        sue_type_specifier
     1325        | declaration_qualifier_list sue_type_specifier
     1326                { $$ = $2->addQualifiers( $1 ); }
     1327        | sue_declaration_specifier storage_class                       // remaining OBSOLESCENT (see 2)
     1328                { $$ = $1->addQualifiers( $2 ); }
     1329        | sue_declaration_specifier storage_class type_qualifier_list
     1330                { $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }
     1331        ;
    13351332
    13361333sue_type_specifier:
    1337                 elaborated_type_name                                                    // struct, union, enum
    1338                 | type_qualifier_list elaborated_type_name
    1339                                 { $$ = $2->addQualifiers( $1 ); }
    1340                 | sue_type_specifier type_qualifier
    1341                                 { $$ = $1->addQualifiers( $2 ); }
    1342                 ;
     1334        elaborated_type_name                                                            // struct, union, enum
     1335        | type_qualifier_list elaborated_type_name
     1336                { $$ = $2->addQualifiers( $1 ); }
     1337        | sue_type_specifier type_qualifier
     1338                { $$ = $1->addQualifiers( $2 ); }
     1339        ;
    13431340
    13441341typedef_declaration_specifier:
    1345                 typedef_type_specifier
    1346                 | declaration_qualifier_list typedef_type_specifier
    1347                                 { $$ = $2->addQualifiers( $1 ); }
    1348                 | typedef_declaration_specifier storage_class   // remaining OBSOLESCENT (see 2)
    1349                                 { $$ = $1->addQualifiers( $2 ); }
    1350                 | typedef_declaration_specifier storage_class type_qualifier_list
    1351                                 { $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }
    1352                 ;
     1342        typedef_type_specifier
     1343        | declaration_qualifier_list typedef_type_specifier
     1344                { $$ = $2->addQualifiers( $1 ); }
     1345        | typedef_declaration_specifier storage_class           // remaining OBSOLESCENT (see 2)
     1346                { $$ = $1->addQualifiers( $2 ); }
     1347        | typedef_declaration_specifier storage_class type_qualifier_list
     1348                { $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }
     1349        ;
    13531350
    13541351typedef_type_specifier:                                                                 // typedef types
    1355                 TYPEDEFname
    1356                                 { $$ = DeclarationNode::newFromTypedef( $1 ); }
    1357                 | type_qualifier_list TYPEDEFname
    1358                                 { $$ = DeclarationNode::newFromTypedef( $2 )->addQualifiers( $1 ); }
    1359                 | typedef_type_specifier type_qualifier
    1360                                 { $$ = $1->addQualifiers( $2 ); }
    1361                 ;
     1352        TYPEDEFname
     1353                { $$ = DeclarationNode::newFromTypedef( $1 ); }
     1354        | type_qualifier_list TYPEDEFname
     1355                { $$ = DeclarationNode::newFromTypedef( $2 )->addQualifiers( $1 ); }
     1356        | typedef_type_specifier type_qualifier
     1357                { $$ = $1->addQualifiers( $2 ); }
     1358        ;
    13621359
    13631360elaborated_type_name:
    1364                 aggregate_name
    1365                 | enum_name
    1366                 ;
     1361        aggregate_name
     1362        | enum_name
     1363        ;
    13671364
    13681365aggregate_name:
    1369                 aggregate_key '{' field_declaration_list '}'
    1370                                 { $$ = DeclarationNode::newAggregate( $1, 0, 0, 0, $3 ); }
    1371                 | aggregate_key no_attr_identifier_or_typedef_name
    1372                                 { $$ = DeclarationNode::newAggregate( $1, $2, 0, 0, 0 ); }
    1373                 | aggregate_key no_attr_identifier_or_typedef_name '{' field_declaration_list '}'
    1374                                 { $$ = DeclarationNode::newAggregate( $1, $2, 0, 0, $4 ); }
    1375                 | aggregate_key '(' push type_parameter_list pop ')' '{' field_declaration_list '}' // CFA
    1376                                 { $$ = DeclarationNode::newAggregate( $1, 0, $4, 0, $8 ); }
    1377                 | aggregate_key '(' push type_parameter_list pop ')' no_attr_identifier_or_typedef_name // CFA
    1378                                 { $$ = DeclarationNode::newAggregate( $1, $7, $4, 0, 0 ); }
    1379                 | aggregate_key '(' push type_parameter_list pop ')' no_attr_identifier_or_typedef_name '{' field_declaration_list '}' // CFA
    1380                                 { $$ = DeclarationNode::newAggregate( $1, $7, $4, 0, $9 ); }
    1381                 | aggregate_key '(' push type_parameter_list pop ')' '(' type_name_list ')' '{' field_declaration_list '}' // CFA
    1382                                 { $$ = DeclarationNode::newAggregate( $1, 0, $4, $8, $11 ); }
    1383                 | aggregate_key '(' push type_name_list pop ')' no_attr_identifier_or_typedef_name // CFA
    1384                                 // push and pop are only to prevent S/R conflicts
    1385                                 { $$ = DeclarationNode::newAggregate( $1, $7, 0, $4, 0 ); }
    1386                 | aggregate_key '(' push type_parameter_list pop ')' '(' type_name_list ')' no_attr_identifier_or_typedef_name '{' field_declaration_list '}' // CFA
    1387                                 { $$ = DeclarationNode::newAggregate( $1, $10, $4, $8, $12 ); }
    1388                 ;
     1366        aggregate_key '{' field_declaration_list '}'
     1367                { $$ = DeclarationNode::newAggregate( $1, 0, 0, 0, $3 ); }
     1368        | aggregate_key no_attr_identifier_or_typedef_name
     1369                { $$ = DeclarationNode::newAggregate( $1, $2, 0, 0, 0 ); }
     1370        | aggregate_key no_attr_identifier_or_typedef_name '{' field_declaration_list '}'
     1371                { $$ = DeclarationNode::newAggregate( $1, $2, 0, 0, $4 ); }
     1372        | aggregate_key '(' push type_parameter_list pop ')' '{' field_declaration_list '}' // CFA
     1373                { $$ = DeclarationNode::newAggregate( $1, 0, $4, 0, $8 ); }
     1374        | aggregate_key '(' push type_parameter_list pop ')' no_attr_identifier_or_typedef_name // CFA
     1375                { $$ = DeclarationNode::newAggregate( $1, $7, $4, 0, 0 ); }
     1376        | aggregate_key '(' push type_parameter_list pop ')' no_attr_identifier_or_typedef_name '{' field_declaration_list '}' // CFA
     1377                { $$ = DeclarationNode::newAggregate( $1, $7, $4, 0, $9 ); }
     1378        | aggregate_key '(' push type_parameter_list pop ')' '(' type_name_list ')' '{' field_declaration_list '}' // CFA
     1379                { $$ = DeclarationNode::newAggregate( $1, 0, $4, $8, $11 ); }
     1380        | aggregate_key '(' push type_name_list pop ')' no_attr_identifier_or_typedef_name // CFA
     1381                // push and pop are only to prevent S/R conflicts
     1382                { $$ = DeclarationNode::newAggregate( $1, $7, 0, $4, 0 ); }
     1383        | aggregate_key '(' push type_parameter_list pop ')' '(' type_name_list ')' no_attr_identifier_or_typedef_name '{' field_declaration_list '}' // CFA
     1384                { $$ = DeclarationNode::newAggregate( $1, $10, $4, $8, $12 ); }
     1385        ;
    13891386
    13901387aggregate_key:
    1391                 STRUCT attribute_list_opt
    1392                                 { $$ = DeclarationNode::Struct; }
    1393                 | UNION attribute_list_opt
    1394                                 { $$ = DeclarationNode::Union; }
    1395                 ;
     1388        STRUCT attribute_list_opt
     1389                { $$ = DeclarationNode::Struct; }
     1390        | UNION attribute_list_opt
     1391                { $$ = DeclarationNode::Union; }
     1392        ;
    13961393
    13971394field_declaration_list:
    1398                 field_declaration
    1399                                 { $$ = $1; }
    1400                 | field_declaration_list field_declaration
    1401                                 { $$ = $1->appendList( $2 ); }
    1402                 ;
     1395        field_declaration
     1396                { $$ = $1; }
     1397        | field_declaration_list field_declaration
     1398                { $$ = $1->appendList( $2 ); }
     1399        ;
    14031400
    14041401field_declaration:
    1405                 new_field_declaring_list ';'                                    // CFA, new style field declaration
    1406                 | EXTENSION new_field_declaring_list ';'                // GCC
    1407                                 { $$ = $2; }
    1408                 | field_declaring_list ';'
    1409                 | EXTENSION field_declaring_list ';'                    // GCC
    1410                                 { $$ = $2; }
    1411                 ;
     1402        new_field_declaring_list ';'                                            // CFA, new style field declaration
     1403        | EXTENSION new_field_declaring_list ';'                        // GCC
     1404                { $$ = $2; }
     1405        | field_declaring_list ';'
     1406        | EXTENSION field_declaring_list ';'                            // GCC
     1407                { $$ = $2; }
     1408        ;
    14121409
    14131410new_field_declaring_list:                                                               // CFA, new style field declaration
    1414                 new_abstract_declarator_tuple                                   // CFA, no field name
    1415                 | new_abstract_declarator_tuple no_attr_identifier_or_typedef_name
    1416                                 { $$ = $1->addName( $2 ); }
    1417                 | new_field_declaring_list ',' no_attr_identifier_or_typedef_name
    1418                                 { $$ = $1->appendList( $1->cloneType( $3 ) ); }
    1419                 | new_field_declaring_list ','                                  // CFA, no field name
    1420                                 { $$ = $1->appendList( $1->cloneType( 0 ) ); }
    1421                 ;
     1411        new_abstract_declarator_tuple                                           // CFA, no field name
     1412        | new_abstract_declarator_tuple no_attr_identifier_or_typedef_name
     1413                { $$ = $1->addName( $2 ); }
     1414        | new_field_declaring_list ',' no_attr_identifier_or_typedef_name
     1415                { $$ = $1->appendList( $1->cloneType( $3 ) ); }
     1416        | new_field_declaring_list ','                                          // CFA, no field name
     1417                { $$ = $1->appendList( $1->cloneType( 0 ) ); }
     1418        ;
    14221419
    14231420field_declaring_list:
    1424                 type_specifier field_declarator
    1425                                 { $$ = $2->addType( $1 ); }
    1426                 | field_declaring_list ',' attribute_list_opt field_declarator
    1427                                 { $$ = $1->appendList( $1->cloneBaseType( $4 ) ); }
    1428                 ;
     1421        type_specifier field_declarator
     1422                { $$ = $2->addType( $1 ); }
     1423        | field_declaring_list ',' attribute_list_opt field_declarator
     1424                { $$ = $1->appendList( $1->cloneBaseType( $4 ) ); }
     1425        ;
    14291426
    14301427field_declarator:
    1431                 // empty
    1432                                 { $$ = DeclarationNode::newName( 0 ); /* XXX */ } // CFA, no field name
    1433                 | bit_subrange_size                                                             // no field name
    1434                                 { $$ = DeclarationNode::newBitfield( $1 ); }
    1435                 | variable_declarator bit_subrange_size_opt
    1436                                 // A semantic check is required to ensure bit_subrange only appears on base type int.
    1437                                 { $$ = $1->addBitfield( $2 ); }
    1438                 | typedef_redeclarator bit_subrange_size_opt
    1439                                 // A semantic check is required to ensure bit_subrange only appears on base type int.
    1440                                 { $$ = $1->addBitfield( $2 ); }
    1441                 | variable_abstract_declarator                                  // CFA, no field name
    1442                 ;
     1428        // empty
     1429                { $$ = DeclarationNode::newName( 0 ); /* XXX */ } // CFA, no field name
     1430        | bit_subrange_size                                                                     // no field name
     1431                { $$ = DeclarationNode::newBitfield( $1 ); }
     1432        | variable_declarator bit_subrange_size_opt
     1433                // A semantic check is required to ensure bit_subrange only appears on base type int.
     1434                { $$ = $1->addBitfield( $2 ); }
     1435        | typedef_redeclarator bit_subrange_size_opt
     1436                // A semantic check is required to ensure bit_subrange only appears on base type int.
     1437                { $$ = $1->addBitfield( $2 ); }
     1438        | variable_abstract_declarator                                          // CFA, no field name
     1439        ;
    14431440
    14441441bit_subrange_size_opt:
    1445                 // empty
    1446                                 { $$ = 0; }
    1447                 | bit_subrange_size
    1448                                 { $$ = $1; }
    1449                 ;
     1442        // empty
     1443                { $$ = 0; }
     1444        | bit_subrange_size
     1445                { $$ = $1; }
     1446        ;
    14501447
    14511448bit_subrange_size:
    1452                 ':' constant_expression
    1453                                 { $$ = $2; }
    1454                 ;
     1449        ':' constant_expression
     1450                { $$ = $2; }
     1451        ;
    14551452
    14561453enum_key:
    1457                 ENUM attribute_list_opt
    1458                 ;
     1454        ENUM attribute_list_opt
     1455        ;
    14591456
    14601457enum_name:
    1461                 enum_key '{' enumerator_list comma_opt '}'
    1462                                 { $$ = DeclarationNode::newEnum( 0, $3 ); }
    1463                 | enum_key no_attr_identifier_or_typedef_name '{' enumerator_list comma_opt '}'
    1464                                 { $$ = DeclarationNode::newEnum( $2, $4 ); }
    1465                 | enum_key no_attr_identifier_or_typedef_name
    1466                                 { $$ = DeclarationNode::newEnum( $2, 0 ); }
    1467                 ;
     1458        enum_key '{' enumerator_list comma_opt '}'
     1459                { $$ = DeclarationNode::newEnum( 0, $3 ); }
     1460        | enum_key no_attr_identifier_or_typedef_name '{' enumerator_list comma_opt '}'
     1461                { $$ = DeclarationNode::newEnum( $2, $4 ); }
     1462        | enum_key no_attr_identifier_or_typedef_name
     1463                { $$ = DeclarationNode::newEnum( $2, 0 ); }
     1464        ;
    14681465
    14691466enumerator_list:
    1470                 no_attr_identifier_or_typedef_name enumerator_value_opt
    1471                                 { $$ = DeclarationNode::newEnumConstant( $1, $2 ); }
    1472                 | enumerator_list ',' no_attr_identifier_or_typedef_name enumerator_value_opt
    1473                                 { $$ = $1->appendList( DeclarationNode::newEnumConstant( $3, $4 ) ); }
    1474                 ;
     1467        no_attr_identifier_or_typedef_name enumerator_value_opt
     1468                { $$ = DeclarationNode::newEnumConstant( $1, $2 ); }
     1469        | enumerator_list ',' no_attr_identifier_or_typedef_name enumerator_value_opt
     1470                { $$ = $1->appendList( DeclarationNode::newEnumConstant( $3, $4 ) ); }
     1471        ;
    14751472
    14761473enumerator_value_opt:
    1477                 // empty
    1478                                 { $$ = 0; }
    1479                 | '=' constant_expression
    1480                                 { $$ = $2; }
    1481                 ;
     1474        // empty
     1475                { $$ = 0; }
     1476        | '=' constant_expression
     1477                { $$ = $2; }
     1478        ;
    14821479
    14831480// Minimum of one parameter after which ellipsis is allowed only at the end.
    14841481
    14851482new_parameter_type_list_opt:                                                    // CFA
    1486                 // empty
    1487                                 { $$ = 0; }
    1488                 | new_parameter_type_list
    1489                 ;
     1483        // empty
     1484                { $$ = 0; }
     1485        | new_parameter_type_list
     1486        ;
    14901487
    14911488new_parameter_type_list:                                                                // CFA, abstract + real
    1492                 new_abstract_parameter_list
    1493                 | new_parameter_list
    1494                 | new_parameter_list pop ',' push new_abstract_parameter_list
    1495                                 { $$ = $1->appendList( $5 ); }
    1496                 | new_abstract_parameter_list pop ',' push ELLIPSIS
    1497                                 { $$ = $1->addVarArgs(); }
    1498                 | new_parameter_list pop ',' push ELLIPSIS
    1499                                 { $$ = $1->addVarArgs(); }
    1500                 ;
     1489        new_abstract_parameter_list
     1490        | new_parameter_list
     1491        | new_parameter_list pop ',' push new_abstract_parameter_list
     1492                { $$ = $1->appendList( $5 ); }
     1493        | new_abstract_parameter_list pop ',' push ELLIPSIS
     1494                { $$ = $1->addVarArgs(); }
     1495        | new_parameter_list pop ',' push ELLIPSIS
     1496                { $$ = $1->addVarArgs(); }
     1497        ;
    15011498
    15021499new_parameter_list:                                                                             // CFA
    1503                                 // To obtain LR(1) between new_parameter_list and new_abstract_tuple, the last
    1504                                 // new_abstract_parameter_list is factored out from new_parameter_list, flattening the rules
    1505                                 // to get lookahead to the ']'.
    1506                 new_parameter_declaration
    1507                 | new_abstract_parameter_list pop ',' push new_parameter_declaration
    1508                                 { $$ = $1->appendList( $5 ); }
    1509                 | new_parameter_list pop ',' push new_parameter_declaration
    1510                                 { $$ = $1->appendList( $5 ); }
    1511                 | new_parameter_list pop ',' push new_abstract_parameter_list pop ',' push new_parameter_declaration
    1512                                 { $$ = $1->appendList( $5 )->appendList( $9 ); }
    1513                 ;
     1500                // To obtain LR(1) between new_parameter_list and new_abstract_tuple, the last
     1501                // new_abstract_parameter_list is factored out from new_parameter_list, flattening the rules to get
     1502                // lookahead to the ']'.
     1503        new_parameter_declaration
     1504        | new_abstract_parameter_list pop ',' push new_parameter_declaration
     1505                { $$ = $1->appendList( $5 ); }
     1506        | new_parameter_list pop ',' push new_parameter_declaration
     1507                { $$ = $1->appendList( $5 ); }
     1508        | new_parameter_list pop ',' push new_abstract_parameter_list pop ',' push new_parameter_declaration
     1509                { $$ = $1->appendList( $5 )->appendList( $9 ); }
     1510        ;
    15141511
    15151512new_abstract_parameter_list:                                                    // CFA, new & old style abstract
    1516                 new_abstract_parameter_declaration
    1517                 | new_abstract_parameter_list pop ',' push new_abstract_parameter_declaration
    1518                                 { $$ = $1->appendList( $5 ); }
    1519                 ;
     1513        new_abstract_parameter_declaration
     1514        | new_abstract_parameter_list pop ',' push new_abstract_parameter_declaration
     1515                { $$ = $1->appendList( $5 ); }
     1516        ;
    15201517
    15211518parameter_type_list_opt:
    1522                 // empty
    1523                                 { $$ = 0; }
    1524                 | parameter_type_list
    1525                 ;
     1519        // empty
     1520                { $$ = 0; }
     1521        | parameter_type_list
     1522        ;
    15261523
    15271524parameter_type_list:
    1528                 parameter_list
    1529                 | parameter_list pop ',' push ELLIPSIS
    1530                                 { $$ = $1->addVarArgs(); }
    1531                 ;
     1525        parameter_list
     1526        | parameter_list pop ',' push ELLIPSIS
     1527                { $$ = $1->addVarArgs(); }
     1528        ;
    15321529
    15331530parameter_list:                                                                                 // abstract + real
    1534                 abstract_parameter_declaration
    1535                 | parameter_declaration
    1536                 | parameter_list pop ',' push abstract_parameter_declaration
    1537                                 { $$ = $1->appendList( $5 ); }
    1538                 | parameter_list pop ',' push parameter_declaration
    1539                                 { $$ = $1->appendList( $5 ); }
    1540                 ;
     1531        abstract_parameter_declaration
     1532        | parameter_declaration
     1533        | parameter_list pop ',' push abstract_parameter_declaration
     1534                { $$ = $1->appendList( $5 ); }
     1535        | parameter_list pop ',' push parameter_declaration
     1536                { $$ = $1->appendList( $5 ); }
     1537        ;
    15411538
    15421539// Provides optional identifier names (abstract_declarator/variable_declarator), no initialization, different
     
    15451542
    15461543new_parameter_declaration:                                                              // CFA, new & old style parameter declaration
    1547                 parameter_declaration
    1548                 | new_identifier_parameter_declarator_no_tuple identifier_or_typedef_name assignment_opt
    1549                                 { $$ = $1->addName( $2 ); }
    1550                 | new_abstract_tuple identifier_or_typedef_name assignment_opt
    1551                                 // To obtain LR(1), these rules must be duplicated here (see new_abstract_declarator).
    1552                                 { $$ = $1->addName( $2 ); }
    1553                 | type_qualifier_list new_abstract_tuple identifier_or_typedef_name assignment_opt
    1554                                 { $$ = $2->addName( $3 )->addQualifiers( $1 ); }
    1555                 | new_function_specifier
    1556                 ;
     1544        parameter_declaration
     1545        | new_identifier_parameter_declarator_no_tuple identifier_or_typedef_name assignment_opt
     1546                { $$ = $1->addName( $2 ); }
     1547        | new_abstract_tuple identifier_or_typedef_name assignment_opt
     1548                // To obtain LR(1), these rules must be duplicated here (see new_abstract_declarator).
     1549                { $$ = $1->addName( $2 ); }
     1550        | type_qualifier_list new_abstract_tuple identifier_or_typedef_name assignment_opt
     1551                { $$ = $2->addName( $3 )->addQualifiers( $1 ); }
     1552        | new_function_specifier
     1553        ;
    15571554
    15581555new_abstract_parameter_declaration:                                             // CFA, new & old style parameter declaration
    1559                 abstract_parameter_declaration
    1560                 | new_identifier_parameter_declarator_no_tuple
    1561                 | new_abstract_tuple
    1562                                 // To obtain LR(1), these rules must be duplicated here (see new_abstract_declarator).
    1563                 | type_qualifier_list new_abstract_tuple
    1564                                 { $$ = $2->addQualifiers( $1 ); }
    1565                 | new_abstract_function
    1566                 ;
     1556        abstract_parameter_declaration
     1557        | new_identifier_parameter_declarator_no_tuple
     1558        | new_abstract_tuple
     1559                // To obtain LR(1), these rules must be duplicated here (see new_abstract_declarator).
     1560        | type_qualifier_list new_abstract_tuple
     1561                { $$ = $2->addQualifiers( $1 ); }
     1562        | new_abstract_function
     1563        ;
    15671564
    15681565parameter_declaration:
    1569                 declaration_specifier identifier_parameter_declarator assignment_opt
    1570                                 {
    1571                                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    1572                                         $$ = $2->addType( $1 )->addInitializer( new InitializerNode($3) );
    1573                                 }
    1574                 | declaration_specifier typedef_parameter_redeclarator assignment_opt
    1575                                 {
    1576                                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    1577                                         $$ = $2->addType( $1 )->addInitializer( new InitializerNode($3) );
    1578                                 }
    1579                 ;
     1566        declaration_specifier identifier_parameter_declarator assignment_opt
     1567                {
     1568                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     1569                        $$ = $2->addType( $1 )->addInitializer( new InitializerNode($3) );
     1570                }
     1571        | declaration_specifier typedef_parameter_redeclarator assignment_opt
     1572                {
     1573                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     1574                        $$ = $2->addType( $1 )->addInitializer( new InitializerNode($3) );
     1575                }
     1576        ;
    15801577
    15811578abstract_parameter_declaration:
    1582                 declaration_specifier
    1583                 | declaration_specifier abstract_parameter_declarator
    1584                                 { $$ = $2->addType( $1 ); }
    1585                 ;
     1579        declaration_specifier
     1580        | declaration_specifier abstract_parameter_declarator
     1581                { $$ = $2->addType( $1 ); }
     1582        ;
    15861583
    15871584// ISO/IEC 9899:1999 Section 6.9.1(6) : "An identifier declared as a typedef name shall not be redeclared as a
     
    15901587
    15911588identifier_list:                                                                                // K&R-style parameter list => no types
    1592                 no_attr_identifier
    1593                                 { $$ = DeclarationNode::newName( $1 ); }
    1594                 | identifier_list ',' no_attr_identifier
    1595                                 { $$ = $1->appendList( DeclarationNode::newName( $3 ) ); }
    1596                 ;
     1589        no_attr_identifier
     1590                { $$ = DeclarationNode::newName( $1 ); }
     1591        | identifier_list ',' no_attr_identifier
     1592                { $$ = $1->appendList( DeclarationNode::newName( $3 ) ); }
     1593        ;
    15971594
    15981595identifier_or_typedef_name:
    1599                 identifier
    1600                 | TYPEDEFname
    1601                 | TYPEGENname
    1602                 ;
     1596        identifier
     1597        | TYPEDEFname
     1598        | TYPEGENname
     1599        ;
    16031600
    16041601no_01_identifier_or_typedef_name:
    1605                 no_01_identifier
    1606                 | TYPEDEFname
    1607                 | TYPEGENname
    1608                 ;
     1602        no_01_identifier
     1603        | TYPEDEFname
     1604        | TYPEGENname
     1605        ;
    16091606
    16101607no_attr_identifier_or_typedef_name:
    1611                 no_attr_identifier
    1612                 | TYPEDEFname
    1613                 | TYPEGENname
    1614                 ;
     1608        no_attr_identifier
     1609        | TYPEDEFname
     1610        | TYPEGENname
     1611        ;
    16151612
    16161613type_name_no_function:                                                                  // sizeof, alignof, cast (constructor)
    1617                 new_abstract_declarator_tuple                                   // CFA
    1618                 | type_specifier
    1619                 | type_specifier variable_abstract_declarator
    1620                                 { $$ = $2->addType( $1 ); }
    1621                 ;
     1614        new_abstract_declarator_tuple                                           // CFA
     1615        | type_specifier
     1616        | type_specifier variable_abstract_declarator
     1617                { $$ = $2->addType( $1 ); }
     1618        ;
    16221619
    16231620type_name:                                                                                              // typeof, assertion
    1624                 new_abstract_declarator_tuple                                   // CFA
    1625                 | new_abstract_function                                                 // CFA
    1626                 | type_specifier
    1627                 | type_specifier abstract_declarator
    1628                                 { $$ = $2->addType( $1 ); }
    1629                 ;
     1621        new_abstract_declarator_tuple                                           // CFA
     1622        | new_abstract_function                                                         // CFA
     1623        | type_specifier
     1624        | type_specifier abstract_declarator
     1625                { $$ = $2->addType( $1 ); }
     1626        ;
    16301627
    16311628initializer_opt:
    1632                 // empty
    1633                                 { $$ = 0; }
    1634                 | '=' initializer                                                               { $$ = $2; }
    1635                 ;
     1629        // empty
     1630                { $$ = 0; }
     1631        | '=' initializer                                                       { $$ = $2; }
     1632        ;
    16361633
    16371634initializer:
    1638                 assignment_expression                                                   { $$ = new InitializerNode($1); }
    1639                 | '{' initializer_list comma_opt '}'                    { $$ = new InitializerNode($2, true); }
    1640                 ;
     1635        assignment_expression                                           { $$ = new InitializerNode($1); }
     1636        | '{' initializer_list comma_opt '}'            { $$ = new InitializerNode($2, true); }
     1637        ;
    16411638
    16421639initializer_list:
    1643                 initializer
    1644                 | designation initializer                                               { $$ = $2->set_designators( $1 ); }
    1645                 | initializer_list ',' initializer                              { $$ = (InitializerNode *)( $1->set_link($3) ); }
    1646                 | initializer_list ',' designation initializer
    1647                                 { $$ = (InitializerNode *)( $1->set_link( $4->set_designators($3) ) ); }
    1648                 ;
     1640        initializer
     1641        | designation initializer                                       { $$ = $2->set_designators( $1 ); }
     1642        | initializer_list ',' initializer                      { $$ = (InitializerNode *)( $1->set_link($3) ); }
     1643        | initializer_list ',' designation initializer
     1644                { $$ = (InitializerNode *)( $1->set_link( $4->set_designators($3) ) ); }
     1645        ;
    16491646
    16501647// There is an unreconcileable parsing problem between C99 and CFA with respect to designators. The problem is
     
    16591656
    16601657designation:
    1661                 designator_list ':'                                                             // C99, CFA uses ":" instead of "="
    1662                 | no_attr_identifier_or_typedef_name ':'                // GCC, field name
    1663                                                 { $$ = new VarRefNode( $1 ); }
    1664                 ;
     1658        designator_list ':'                                                                     // C99, CFA uses ":" instead of "="
     1659        | no_attr_identifier_or_typedef_name ':'                        // GCC, field name
     1660                                { $$ = new VarRefNode( $1 ); }
     1661        ;
    16651662
    16661663designator_list:                                                                                // C99
    1667                 designator
    1668                 | designator_list designator                                            { $$ = (ExpressionNode *)($1->set_link( $2 )); }
    1669                 ;
     1664        designator
     1665        | designator_list designator                                    { $$ = (ExpressionNode *)($1->set_link( $2 )); }
     1666        ;
    16701667
    16711668designator:
    1672                 '.' no_attr_identifier_or_typedef_name                  // C99, field name
    1673                                 { $$ = new VarRefNode( $2 ); }
    1674                 | '[' push assignment_expression pop ']'                // C99, single array element
    1675                                 // assignment_expression used instead of constant_expression because of shift/reduce conflicts
    1676                                 // with tuple.
    1677                                 { $$ = $3; }
    1678                 | '[' push subrange pop ']'                                             // CFA, multiple array elements
    1679                                 { $$ = $3; }
    1680                 | '[' push constant_expression ELLIPSIS constant_expression pop ']' // GCC, multiple array elements
    1681                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Range), $3, $5); }
    1682                 | '.' '[' push field_list pop ']'                               // CFA, tuple field selector
    1683                                 { $$ = $4; }
    1684                 ;
     1669        '.' no_attr_identifier_or_typedef_name                          // C99, field name
     1670                { $$ = new VarRefNode( $2 ); }
     1671        | '[' push assignment_expression pop ']'                        // C99, single array element
     1672                // assignment_expression used instead of constant_expression because of shift/reduce conflicts with
     1673                // tuple.
     1674                { $$ = $3; }
     1675        | '[' push subrange pop ']'                                                     // CFA, multiple array elements
     1676                { $$ = $3; }
     1677        | '[' push constant_expression ELLIPSIS constant_expression pop ']' // GCC, multiple array elements
     1678                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Range), $3, $5); }
     1679        | '.' '[' push field_list pop ']'                                       // CFA, tuple field selector
     1680                { $$ = $4; }
     1681        ;
    16851682
    16861683// The CFA type system is based on parametric polymorphism, the ability to declare functions with type
     
    17041701
    17051702typegen_declaration_specifier:                                                  // CFA
    1706                 typegen_type_specifier
    1707                 | declaration_qualifier_list typegen_type_specifier
    1708                                 { $$ = $2->addQualifiers( $1 ); }
    1709                 | typegen_declaration_specifier storage_class   // remaining OBSOLESCENT (see 2)
    1710                                 { $$ = $1->addQualifiers( $2 ); }
    1711                 | typegen_declaration_specifier storage_class type_qualifier_list
    1712                                 { $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }
    1713                 ;
     1703        typegen_type_specifier
     1704        | declaration_qualifier_list typegen_type_specifier
     1705                { $$ = $2->addQualifiers( $1 ); }
     1706        | typegen_declaration_specifier storage_class           // remaining OBSOLESCENT (see 2)
     1707                { $$ = $1->addQualifiers( $2 ); }
     1708        | typegen_declaration_specifier storage_class type_qualifier_list
     1709                { $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }
     1710        ;
    17141711
    17151712typegen_type_specifier:                                                                 // CFA
    1716                 TYPEGENname '(' type_name_list ')'
    1717                                 { $$ = DeclarationNode::newFromTypeGen( $1, $3 ); }
    1718                 | type_qualifier_list TYPEGENname '(' type_name_list ')'
    1719                                 { $$ = DeclarationNode::newFromTypeGen( $2, $4 )->addQualifiers( $1 ); }
    1720                 | typegen_type_specifier type_qualifier
    1721                                 { $$ = $1->addQualifiers( $2 ); }
    1722                 ;
     1713        TYPEGENname '(' type_name_list ')'
     1714                { $$ = DeclarationNode::newFromTypeGen( $1, $3 ); }
     1715        | type_qualifier_list TYPEGENname '(' type_name_list ')'
     1716                { $$ = DeclarationNode::newFromTypeGen( $2, $4 )->addQualifiers( $1 ); }
     1717        | typegen_type_specifier type_qualifier
     1718                { $$ = $1->addQualifiers( $2 ); }
     1719        ;
    17231720
    17241721type_parameter_list:                                                                    // CFA
    1725                 type_parameter assignment_opt
    1726                 | type_parameter_list ',' type_parameter assignment_opt
    1727                                 { $$ = $1->appendList( $3 ); }
    1728                 ;
     1722        type_parameter assignment_opt
     1723        | type_parameter_list ',' type_parameter assignment_opt
     1724                { $$ = $1->appendList( $3 ); }
     1725        ;
    17291726
    17301727type_parameter:                                                                                 // CFA
    1731                 type_class no_attr_identifier_or_typedef_name
    1732                                 { typedefTable.addToEnclosingScope(*($2), TypedefTable::TD); }
    1733                   assertion_list_opt
    1734                                 { $$ = DeclarationNode::newTypeParam( $1, $2 )->addAssertions( $4 ); }
    1735                 | type_specifier identifier_parameter_declarator
    1736                 ;
     1728        type_class no_attr_identifier_or_typedef_name
     1729                { typedefTable.addToEnclosingScope(*($2), TypedefTable::TD); }
     1730          assertion_list_opt
     1731                { $$ = DeclarationNode::newTypeParam( $1, $2 )->addAssertions( $4 ); }
     1732        | type_specifier identifier_parameter_declarator
     1733        ;
    17371734
    17381735type_class:                                                                                             // CFA
    1739                 TYPE
    1740                                 { $$ = DeclarationNode::Type; }
    1741                 | DTYPE
    1742                                 { $$ = DeclarationNode::Ftype; }
    1743                 | FTYPE
    1744                                 { $$ = DeclarationNode::Dtype; }
    1745                 ;
     1736        TYPE
     1737                { $$ = DeclarationNode::Type; }
     1738        | DTYPE
     1739                { $$ = DeclarationNode::Ftype; }
     1740        | FTYPE
     1741                { $$ = DeclarationNode::Dtype; }
     1742        ;
    17461743
    17471744assertion_list_opt:                                                                             // CFA
    1748                 // empty
    1749                                 { $$ = 0; }
    1750                 | assertion_list_opt assertion
    1751                                 { $$ = $1 == 0 ? $2 : $1->appendList( $2 ); }
    1752                 ;
     1745        // empty
     1746                { $$ = 0; }
     1747        | assertion_list_opt assertion
     1748                { $$ = $1 == 0 ? $2 : $1->appendList( $2 ); }
     1749        ;
    17531750
    17541751assertion:                                                                                              // CFA
    1755                 '|' no_attr_identifier_or_typedef_name '(' type_name_list ')'
    1756                                 {
    1757                                         typedefTable.openContext( *($2) );
    1758                                         $$ = DeclarationNode::newContextUse( $2, $4 );
    1759                                 }
    1760                 | '|' '{' push context_declaration_list '}'
    1761                                 { $$ = $4; }
    1762                 | '|' '(' push type_parameter_list pop ')' '{' push context_declaration_list '}' '(' type_name_list ')'
    1763                                 { $$ = 0; }
    1764                 ;
     1752        '|' no_attr_identifier_or_typedef_name '(' type_name_list ')'
     1753                {
     1754                        typedefTable.openContext( *($2) );
     1755                        $$ = DeclarationNode::newContextUse( $2, $4 );
     1756                }
     1757        | '|' '{' push context_declaration_list '}'
     1758                { $$ = $4; }
     1759        | '|' '(' push type_parameter_list pop ')' '{' push context_declaration_list '}' '(' type_name_list ')'
     1760                { $$ = 0; }
     1761        ;
    17651762
    17661763type_name_list:                                                                                 // CFA
    1767                 type_name
    1768                                 { $$ = new TypeValueNode( $1 ); }
    1769                 | assignment_expression
    1770                 | type_name_list ',' type_name
    1771                                 { $$ = (ExpressionNode *)($1->set_link(new TypeValueNode( $3 ))); }
    1772                 | type_name_list ',' assignment_expression
    1773                                 { $$ = (ExpressionNode *)($1->set_link($3)); }
    1774                 ;
     1764        type_name
     1765                { $$ = new TypeValueNode( $1 ); }
     1766        | assignment_expression
     1767        | type_name_list ',' type_name
     1768                { $$ = (ExpressionNode *)($1->set_link(new TypeValueNode( $3 ))); }
     1769        | type_name_list ',' assignment_expression
     1770                { $$ = (ExpressionNode *)($1->set_link($3)); }
     1771        ;
    17751772
    17761773type_declaring_list:                                                                    // CFA
    1777                 TYPE type_declarator
    1778                                 { $$ = $2; }
    1779                 | storage_class_list TYPE type_declarator
    1780                                 { $$ = $3->addQualifiers( $1 ); }
    1781                 | type_declaring_list ',' type_declarator
    1782                                 { $$ = $1->appendList( $3->copyStorageClasses( $1 ) ); }
    1783                 ;
     1774        TYPE type_declarator
     1775                { $$ = $2; }
     1776        | storage_class_list TYPE type_declarator
     1777                { $$ = $3->addQualifiers( $1 ); }
     1778        | type_declaring_list ',' type_declarator
     1779                { $$ = $1->appendList( $3->copyStorageClasses( $1 ) ); }
     1780        ;
    17841781
    17851782type_declarator:                                                                                // CFA
    1786                 type_declarator_name assertion_list_opt
    1787                                 { $$ = $1->addAssertions( $2 ); }
    1788                 | type_declarator_name assertion_list_opt '=' type_name
    1789                                 { $$ = $1->addAssertions( $2 )->addType( $4 ); }
    1790                 ;
     1783        type_declarator_name assertion_list_opt
     1784                { $$ = $1->addAssertions( $2 ); }
     1785        | type_declarator_name assertion_list_opt '=' type_name
     1786                { $$ = $1->addAssertions( $2 )->addType( $4 ); }
     1787        ;
    17911788
    17921789type_declarator_name:                                                                   // CFA
    1793                 no_attr_identifier_or_typedef_name
    1794                                 {
    1795                                         typedefTable.addToEnclosingScope(*($1), TypedefTable::TD);
    1796                                         $$ = DeclarationNode::newTypeDecl( $1, 0 );
    1797                                 }
    1798                 | no_01_identifier_or_typedef_name '(' push type_parameter_list pop ')'
    1799                                 {
    1800                                         typedefTable.addToEnclosingScope(*($1), TypedefTable::TG);
    1801                                         $$ = DeclarationNode::newTypeDecl( $1, $4 );
    1802                                 }
    1803                 ;
     1790        no_attr_identifier_or_typedef_name
     1791                {
     1792                        typedefTable.addToEnclosingScope(*($1), TypedefTable::TD);
     1793                        $$ = DeclarationNode::newTypeDecl( $1, 0 );
     1794                }
     1795        | no_01_identifier_or_typedef_name '(' push type_parameter_list pop ')'
     1796                {
     1797                        typedefTable.addToEnclosingScope(*($1), TypedefTable::TG);
     1798                        $$ = DeclarationNode::newTypeDecl( $1, $4 );
     1799                }
     1800        ;
    18041801
    18051802context_specifier:                                                                              // CFA
    1806                 CONTEXT no_attr_identifier_or_typedef_name '(' push type_parameter_list pop ')' '{' '}'
    1807                                 {
    1808                                         typedefTable.addToEnclosingScope(*($2), TypedefTable::ID );
    1809                                         $$ = DeclarationNode::newContext( $2, $5, 0 );
    1810                                 }
    1811                 | CONTEXT no_attr_identifier_or_typedef_name '(' push type_parameter_list pop ')' '{'
    1812                                 {
    1813                                         typedefTable.enterContext( *($2) );
    1814                                         typedefTable.enterScope();
    1815                                 }
    1816                   context_declaration_list '}'
    1817                                 {
    1818                                         typedefTable.leaveContext();
    1819                                         typedefTable.addToEnclosingScope(*($2), TypedefTable::ID );
    1820                                         $$ = DeclarationNode::newContext( $2, $5, $10 );
    1821                                 }
    1822                 ;
     1803        CONTEXT no_attr_identifier_or_typedef_name '(' push type_parameter_list pop ')' '{' '}'
     1804                {
     1805                        typedefTable.addToEnclosingScope(*($2), TypedefTable::ID );
     1806                        $$ = DeclarationNode::newContext( $2, $5, 0 );
     1807                }
     1808        | CONTEXT no_attr_identifier_or_typedef_name '(' push type_parameter_list pop ')' '{'
     1809                {
     1810                        typedefTable.enterContext( *($2) );
     1811                        typedefTable.enterScope();
     1812                }
     1813          context_declaration_list '}'
     1814                {
     1815                        typedefTable.leaveContext();
     1816                        typedefTable.addToEnclosingScope(*($2), TypedefTable::ID );
     1817                        $$ = DeclarationNode::newContext( $2, $5, $10 );
     1818                }
     1819        ;
    18231820
    18241821context_declaration_list:                                                               // CFA
    1825                 context_declaration
    1826                 | context_declaration_list push context_declaration
    1827                                 { $$ = $1->appendList( $3 ); }
    1828                 ;
     1822        context_declaration
     1823        | context_declaration_list push context_declaration
     1824                { $$ = $1->appendList( $3 ); }
     1825        ;
    18291826
    18301827context_declaration:                                                                    // CFA
    1831                 new_context_declaring_list pop ';'
    1832                 | context_declaring_list pop ';'
    1833                 ;
     1828        new_context_declaring_list pop ';'
     1829        | context_declaring_list pop ';'
     1830        ;
    18341831
    18351832new_context_declaring_list:                                                             // CFA
    1836                 new_variable_specifier
    1837                                 {
    1838                                         typedefTable.addToEnclosingScope2( TypedefTable::ID );
    1839                                         $$ = $1;
    1840                                 }
    1841                 | new_function_specifier
    1842                                 {
    1843                                         typedefTable.addToEnclosingScope2( TypedefTable::ID );
    1844                                         $$ = $1;
    1845                                 }
    1846                 | new_context_declaring_list pop ',' push identifier_or_typedef_name
    1847                                 {
    1848                                         typedefTable.addToEnclosingScope2( *($5), TypedefTable::ID );
    1849                                         $$ = $1->appendList( $1->cloneType( $5 ) );
    1850                                 }
    1851                 ;
     1833        new_variable_specifier
     1834                {
     1835                        typedefTable.addToEnclosingScope2( TypedefTable::ID );
     1836                        $$ = $1;
     1837                }
     1838        | new_function_specifier
     1839                {
     1840                        typedefTable.addToEnclosingScope2( TypedefTable::ID );
     1841                        $$ = $1;
     1842                }
     1843        | new_context_declaring_list pop ',' push identifier_or_typedef_name
     1844                {
     1845                        typedefTable.addToEnclosingScope2( *($5), TypedefTable::ID );
     1846                        $$ = $1->appendList( $1->cloneType( $5 ) );
     1847                }
     1848        ;
    18521849
    18531850context_declaring_list:                                                                 // CFA
    1854                 type_specifier declarator
    1855                                 {
    1856                                         typedefTable.addToEnclosingScope2( TypedefTable::ID );
    1857                                         $$ = $2->addType( $1 );
    1858                                 }
    1859                 | context_declaring_list pop ',' push declarator
    1860                                 {
    1861                                         typedefTable.addToEnclosingScope2( TypedefTable::ID );
    1862                                         $$ = $1->appendList( $1->cloneBaseType( $5 ) );
    1863                                 }
    1864                 ;
     1851        type_specifier declarator
     1852                {
     1853                        typedefTable.addToEnclosingScope2( TypedefTable::ID );
     1854                        $$ = $2->addType( $1 );
     1855                }
     1856        | context_declaring_list pop ',' push declarator
     1857                {
     1858                        typedefTable.addToEnclosingScope2( TypedefTable::ID );
     1859                        $$ = $1->appendList( $1->cloneBaseType( $5 ) );
     1860                }
     1861        ;
    18651862
    18661863//***************************** EXTERNAL DEFINITIONS *****************************
    18671864
    18681865translation_unit:
    1869                 // empty
    1870                                 {}                                                                              // empty input file
    1871                 | external_definition_list
    1872                                 {
    1873                                         if ( theTree ) {
    1874                                                 theTree->appendList( $1 );
    1875                                         } else {
    1876                                                 theTree = $1;
    1877                                         }
    1878                                 }
    1879                 ;
     1866        // empty
     1867                {}                                                                                              // empty input file
     1868        | external_definition_list
     1869                {
     1870                        if ( theTree ) {
     1871                                theTree->appendList( $1 );
     1872                        } else {
     1873                                theTree = $1;
     1874                        }
     1875                }
     1876        ;
    18801877
    18811878external_definition_list:
    1882                 external_definition
    1883                 | external_definition_list push external_definition
    1884                                 { $$ = ($1 != NULL ) ? $1->appendList( $3 ) : $3; }
    1885                 ;
     1879        external_definition
     1880        | external_definition_list push external_definition
     1881                { $$ = ($1 != NULL ) ? $1->appendList( $3 ) : $3; }
     1882        ;
    18861883
    18871884external_definition_list_opt:
    1888                 // empty
    1889                                 { $$ = 0; }
    1890                 | external_definition_list
    1891                 ;
     1885        // empty
     1886                { $$ = 0; }
     1887        | external_definition_list
     1888        ;
    18921889
    18931890external_definition:
    1894                 declaration
    1895                 | function_definition
    1896                 | asm_statement                                                                 // GCC, global assembler statement
    1897                                 {}
    1898                 | EXTERN STRINGliteral
    1899                                 {
    1900                                         linkageStack.push( linkage );
    1901                                         linkage = LinkageSpec::fromString( *$2 );
    1902                                 }
    1903                   '{' external_definition_list_opt '}'                  // C++-style linkage specifier
    1904                                 {
    1905                                         linkage = linkageStack.top();
    1906                                         linkageStack.pop();
    1907                                         $$ = $5;
    1908                                 }
    1909                 | EXTENSION external_definition
    1910                                 { $$ = $2; }
    1911                 ;
     1891        declaration
     1892        | external_function_definition
     1893        | asm_statement                                                                         // GCC, global assembler statement
     1894                {}
     1895        | EXTERN STRINGliteral
     1896                {
     1897                        linkageStack.push( linkage );
     1898                        linkage = LinkageSpec::fromString( *$2 );
     1899                }
     1900          '{' external_definition_list_opt '}'                          // C++-style linkage specifier
     1901                {
     1902                        linkage = linkageStack.top();
     1903                        linkageStack.pop();
     1904                        $$ = $5;
     1905                }
     1906        | EXTENSION external_definition
     1907                { $$ = $2; }
     1908        ;
     1909
     1910external_function_definition:
     1911        function_definition
     1912
     1913                // These rules are a concession to the "implicit int" type_specifier because there is a significant
     1914                // amount of code with functions missing a type-specifier on the return type.  Parsing is possible
     1915                // because function_definition does not appear in the context of an expression (nested functions would
     1916                // preclude this concession). A function prototype declaration must still have a type_specifier.
     1917                // OBSOLESCENT (see 1)
     1918        | function_declarator compound_statement
     1919                {
     1920                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     1921                        typedefTable.leaveScope();
     1922                        $$ = $1->addFunctionBody( $2 );
     1923                }
     1924        | old_function_declarator push old_declaration_list_opt compound_statement
     1925                {
     1926                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     1927                        typedefTable.leaveScope();
     1928                        $$ = $1->addOldDeclList( $3 )->addFunctionBody( $4 );
     1929                }
     1930        ;
    19121931
    19131932function_definition:
    1914                 new_function_declaration compound_statement             // CFA
    1915                                 {
    1916                                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    1917                                         typedefTable.leaveScope();
    1918                                         $$ = $1->addFunctionBody( $2 );
    1919                                 }
    1920 //              | declaration_qualifier_list new_function_specifier compound_statement // CFA
    1921 //                              // declaration_qualifier_list also includes type_qualifier_list, so a semantic check is
    1922 //                              // necessary to preclude them as a type_qualifier cannot appear in this context.
    1923 //                              {
    1924 //                                      typedefTable.addToEnclosingScope( TypedefTable::ID );
    1925 //                                      typedefTable.leaveScope();
    1926 //                                      $$ = $2->addFunctionBody( $3 )->addQualifiers( $1 );
    1927 //                              }
    1928                 | declaration_specifier function_declarator compound_statement
    1929                                 {
    1930                                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    1931                                         typedefTable.leaveScope();
    1932                                         $$ = $2->addFunctionBody( $3 )->addType( $1 );
    1933                                 }
    1934 
    1935                                 // These rules are a concession to the "implicit int" type_specifier because there is a
    1936                                 // significant amount of code with functions missing a type-specifier on the return type.
    1937                                 // Parsing is possible because function_definition does not appear in the context of an
    1938                                 // expression (nested functions would preclude this concession). A function prototype
    1939                                 // declaration must still have a type_specifier. OBSOLESCENT (see 1)
    1940                 | function_declarator compound_statement
    1941                                 {
    1942                                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    1943                                         typedefTable.leaveScope();
    1944                                         $$ = $1->addFunctionBody( $2 );
    1945                                 }
    1946                 | type_qualifier_list function_declarator compound_statement
    1947                                 {
    1948                                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    1949                                         typedefTable.leaveScope();
    1950                                         $$ = $2->addFunctionBody( $3 )->addQualifiers( $1 );
    1951                                 }
    1952                 | declaration_qualifier_list function_declarator compound_statement
    1953                                 {
    1954                                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    1955                                         typedefTable.leaveScope();
    1956                                         $$ = $2->addFunctionBody( $3 )->addQualifiers( $1 );
    1957                                 }
    1958                 | declaration_qualifier_list type_qualifier_list function_declarator compound_statement
    1959                                 {
    1960                                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    1961                                         typedefTable.leaveScope();
    1962                                         $$ = $3->addFunctionBody( $4 )->addQualifiers( $2 )->addQualifiers( $1 );
    1963                                 }
    1964 
    1965                                 // Old-style K&R function definition, OBSOLESCENT (see 4)
    1966                 | declaration_specifier old_function_declarator push old_declaration_list_opt compound_statement
    1967                                 {
    1968                                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    1969                                         typedefTable.leaveScope();
    1970                                         $$ = $2->addOldDeclList( $4 )->addFunctionBody( $5 )->addType( $1 );
    1971                                 }
    1972                 | old_function_declarator push old_declaration_list_opt compound_statement
    1973                                 {
    1974                                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    1975                                         typedefTable.leaveScope();
    1976                                         $$ = $1->addOldDeclList( $3 )->addFunctionBody( $4 );
    1977                                 }
    1978                 | type_qualifier_list old_function_declarator push old_declaration_list_opt compound_statement
    1979                                 {
    1980                                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    1981                                         typedefTable.leaveScope();
    1982                                         $$ = $2->addOldDeclList( $4 )->addFunctionBody( $5 )->addQualifiers( $1 );
    1983                                 }
    1984 
    1985                                 // Old-style K&R function definition with "implicit int" type_specifier, OBSOLESCENT (see 4)
    1986                 | declaration_qualifier_list old_function_declarator push old_declaration_list_opt compound_statement
    1987                                 {
    1988                                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    1989                                         typedefTable.leaveScope();
    1990                                         $$ = $2->addOldDeclList( $4 )->addFunctionBody( $5 )->addQualifiers( $1 );
    1991                                 }
    1992                 | declaration_qualifier_list type_qualifier_list old_function_declarator push old_declaration_list_opt compound_statement
    1993                                 {
    1994                                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    1995                                         typedefTable.leaveScope();
    1996                                         $$ = $3->addOldDeclList( $5 )->addFunctionBody( $6 )->addQualifiers( $2 )->addQualifiers( $1 );
    1997                                 }
    1998                 ;
     1933        new_function_declaration compound_statement                     // CFA
     1934                {
     1935                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     1936                        typedefTable.leaveScope();
     1937                        $$ = $1->addFunctionBody( $2 );
     1938                }
     1939        | declaration_specifier function_declarator compound_statement
     1940                {
     1941                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     1942                        typedefTable.leaveScope();
     1943                        $$ = $2->addFunctionBody( $3 )->addType( $1 );
     1944                }
     1945        | type_qualifier_list function_declarator compound_statement
     1946                {
     1947                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     1948                        typedefTable.leaveScope();
     1949                        $$ = $2->addFunctionBody( $3 )->addQualifiers( $1 );
     1950                }
     1951        | declaration_qualifier_list function_declarator compound_statement
     1952                {
     1953                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     1954                        typedefTable.leaveScope();
     1955                        $$ = $2->addFunctionBody( $3 )->addQualifiers( $1 );
     1956                }
     1957        | declaration_qualifier_list type_qualifier_list function_declarator compound_statement
     1958                {
     1959                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     1960                        typedefTable.leaveScope();
     1961                        $$ = $3->addFunctionBody( $4 )->addQualifiers( $2 )->addQualifiers( $1 );
     1962                }
     1963
     1964                // Old-style K&R function definition, OBSOLESCENT (see 4)
     1965        | declaration_specifier old_function_declarator push old_declaration_list_opt compound_statement
     1966                {
     1967                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     1968                        typedefTable.leaveScope();
     1969                        $$ = $2->addOldDeclList( $4 )->addFunctionBody( $5 )->addType( $1 );
     1970                }
     1971        | type_qualifier_list old_function_declarator push old_declaration_list_opt compound_statement
     1972                {
     1973                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     1974                        typedefTable.leaveScope();
     1975                        $$ = $2->addOldDeclList( $4 )->addFunctionBody( $5 )->addQualifiers( $1 );
     1976                }
     1977
     1978                // Old-style K&R function definition with "implicit int" type_specifier, OBSOLESCENT (see 4)
     1979        | declaration_qualifier_list old_function_declarator push old_declaration_list_opt compound_statement
     1980                {
     1981                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     1982                        typedefTable.leaveScope();
     1983                        $$ = $2->addOldDeclList( $4 )->addFunctionBody( $5 )->addQualifiers( $1 );
     1984                }
     1985        | declaration_qualifier_list type_qualifier_list old_function_declarator push old_declaration_list_opt compound_statement
     1986                {
     1987                        typedefTable.addToEnclosingScope( TypedefTable::ID );
     1988                        typedefTable.leaveScope();
     1989                        $$ = $3->addOldDeclList( $5 )->addFunctionBody( $6 )->addQualifiers( $2 )->addQualifiers( $1 );
     1990                }
     1991        ;
    19991992
    20001993declarator:
    2001                 variable_declarator
    2002                 | function_declarator
    2003                 | typedef_redeclarator
    2004                 ;
     1994        variable_declarator
     1995        | function_declarator
     1996        | typedef_redeclarator
     1997        ;
    20051998
    20061999subrange:
    2007                 constant_expression '~' constant_expression             // CFA, integer subrange
    2008                                 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Range), $1, $3); }
    2009                 ;
     2000        constant_expression '~' constant_expression                     // CFA, integer subrange
     2001                { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Range), $1, $3); }
     2002        ;
    20102003
    20112004asm_name_opt:                                                                                   // GCC
    2012                 // empty
    2013                 | ASM '(' string_literal_list ')' attribute_list_opt
    2014                 ;
     2005        // empty
     2006        | ASM '(' string_literal_list ')' attribute_list_opt
     2007        ;
    20152008
    20162009attribute_list_opt:                                                                             // GCC
    2017                 // empty
    2018                 | attribute_list
    2019                 ;
     2010        // empty
     2011        | attribute_list
     2012        ;
    20202013
    20212014attribute_list:                                                                                 // GCC
    2022                 attribute
    2023                 | attribute_list attribute
    2024                 ;
     2015        attribute
     2016        | attribute_list attribute
     2017        ;
    20252018
    20262019attribute:                                                                                              // GCC
    2027                 ATTRIBUTE '(' '(' attribute_parameter_list ')' ')'
    2028                 ;
     2020        ATTRIBUTE '(' '(' attribute_parameter_list ')' ')'
     2021        ;
    20292022
    20302023attribute_parameter_list:                                                               // GCC
    2031                 attrib
    2032                 | attribute_parameter_list ',' attrib
    2033                 ;
     2024        attrib
     2025        | attribute_parameter_list ',' attrib
     2026        ;
    20342027
    20352028attrib:                                                                                                 // GCC
    2036                 // empty
    2037                 | any_word
    2038                 | any_word '(' comma_expression_opt ')'
    2039                 ;
     2029        // empty
     2030        | any_word
     2031        | any_word '(' comma_expression_opt ')'
     2032        ;
    20402033
    20412034any_word:                                                                                               // GCC
    2042                 identifier_or_typedef_name {}
    2043                 | storage_class_name {}
    2044                 | basic_type_name {}
    2045                 | type_qualifier {}
    2046                 ;
     2035        identifier_or_typedef_name {}
     2036        | storage_class_name {}
     2037        | basic_type_name {}
     2038        | type_qualifier {}
     2039        ;
    20472040
    20482041// ============================================================================
     
    20652058//              valid declaration               invalid definition
    20662059//              -----------------               ------------------
    2067 //              int f;                                          int f {}
    2068 //              int *f;                                         int *f {}
     2060//              int f;                                  int f {}
     2061//              int *f;                                 int *f {}
    20692062//              int f[10];                              int f[10] {}
    2070 //              int (*f)(int);                          int (*f)(int) {}
     2063//              int (*f)(int);                  int (*f)(int) {}
    20712064//
    20722065// To preclude this syntactic anomaly requires separating the grammar rules for variable and function
     
    20782071
    20792072variable_declarator:
    2080                 paren_identifier attribute_list_opt
    2081                 | variable_ptr
    2082                 | variable_array attribute_list_opt
    2083                 | variable_function attribute_list_opt
    2084                 ;
     2073        paren_identifier attribute_list_opt
     2074        | variable_ptr
     2075        | variable_array attribute_list_opt
     2076        | variable_function attribute_list_opt
     2077        ;
    20852078
    20862079paren_identifier:
    2087                 identifier
    2088                                 {
    2089                                         typedefTable.setNextIdentifier( *($1) );
    2090                                         $$ = DeclarationNode::newName( $1 );
    2091                                 }
    2092                 | '(' paren_identifier ')'                                              // redundant parenthesis
    2093                                 { $$ = $2; }
    2094                 ;
     2080        identifier
     2081                {
     2082                        typedefTable.setNextIdentifier( *($1) );
     2083                        $$ = DeclarationNode::newName( $1 );
     2084                }
     2085        | '(' paren_identifier ')'                                                      // redundant parenthesis
     2086                { $$ = $2; }
     2087        ;
    20952088
    20962089variable_ptr:
    2097                 '*' variable_declarator
    2098                                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
    2099                 | '*' type_qualifier_list variable_declarator
    2100                                 { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
    2101                 | '(' variable_ptr ')'
    2102                                 { $$ = $2; }
    2103                 ;
     2090        '*' variable_declarator
     2091                { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
     2092        | '*' type_qualifier_list variable_declarator
     2093                { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
     2094        | '(' variable_ptr ')'
     2095                { $$ = $2; }
     2096        ;
    21042097
    21052098variable_array:
    2106                 paren_identifier array_dimension
    2107                                 { $$ = $1->addArray( $2 ); }
    2108                 | '(' variable_ptr ')' array_dimension
    2109                                 { $$ = $2->addArray( $4 ); }
    2110                 | '(' variable_array ')' multi_array_dimension  // redundant parenthesis
    2111                                 { $$ = $2->addArray( $4 ); }
    2112                 | '(' variable_array ')'                                                // redundant parenthesis
    2113                                 { $$ = $2; }
    2114                 ;
     2099        paren_identifier array_dimension
     2100                { $$ = $1->addArray( $2 ); }
     2101        | '(' variable_ptr ')' array_dimension
     2102                { $$ = $2->addArray( $4 ); }
     2103        | '(' variable_array ')' multi_array_dimension          // redundant parenthesis
     2104                { $$ = $2->addArray( $4 ); }
     2105        | '(' variable_array ')'                                                        // redundant parenthesis
     2106                { $$ = $2; }
     2107        ;
    21152108
    21162109variable_function:
    2117                 '(' variable_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    2118                                 { $$ = $2->addParamList( $6 ); }
    2119                 | '(' variable_function ')'                                             // redundant parenthesis
    2120                                 { $$ = $2; }
    2121                 ;
     2110        '(' variable_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
     2111                { $$ = $2->addParamList( $6 ); }
     2112        | '(' variable_function ')'                                                     // redundant parenthesis
     2113                { $$ = $2; }
     2114        ;
    21222115
    21232116// This pattern parses a function declarator that is not redefining a typedef name. Because functions cannot
     
    21272120
    21282121function_declarator:
    2129                 function_no_ptr attribute_list_opt
    2130                 | function_ptr
    2131                 | function_array attribute_list_opt
    2132                 ;
     2122        function_no_ptr attribute_list_opt
     2123        | function_ptr
     2124        | function_array attribute_list_opt
     2125        ;
    21332126
    21342127function_no_ptr:
    2135                 paren_identifier '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    2136                                 { $$ = $1->addParamList( $4 ); }
    2137                 | '(' function_ptr ')' '(' push parameter_type_list_opt pop ')'
    2138                                 { $$ = $2->addParamList( $6 ); }
    2139                 | '(' function_no_ptr ')'                                               // redundant parenthesis
    2140                                 { $$ = $2; }
    2141                 ;
     2128        paren_identifier '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
     2129                { $$ = $1->addParamList( $4 ); }
     2130        | '(' function_ptr ')' '(' push parameter_type_list_opt pop ')'
     2131                { $$ = $2->addParamList( $6 ); }
     2132        | '(' function_no_ptr ')'                                                       // redundant parenthesis
     2133                { $$ = $2; }
     2134        ;
    21422135
    21432136function_ptr:
    2144                 '*' function_declarator
    2145                                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
    2146                 | '*' type_qualifier_list function_declarator
    2147                                 { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
    2148                 | '(' function_ptr ')'
    2149                                 { $$ = $2; }
    2150                 ;
     2137        '*' function_declarator
     2138                { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
     2139        | '*' type_qualifier_list function_declarator
     2140                { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
     2141        | '(' function_ptr ')'
     2142                { $$ = $2; }
     2143        ;
    21512144
    21522145function_array:
    2153                 '(' function_ptr ')' array_dimension
    2154                                 { $$ = $2->addArray( $4 ); }
    2155                 | '(' function_array ')' multi_array_dimension  // redundant parenthesis
    2156                                 { $$ = $2->addArray( $4 ); }
    2157                 | '(' function_array ')'                                                // redundant parenthesis
    2158                                 { $$ = $2; }
    2159                 ;
     2146        '(' function_ptr ')' array_dimension
     2147                { $$ = $2->addArray( $4 ); }
     2148        | '(' function_array ')' multi_array_dimension          // redundant parenthesis
     2149                { $$ = $2->addArray( $4 ); }
     2150        | '(' function_array ')'                                                        // redundant parenthesis
     2151                { $$ = $2; }
     2152        ;
    21602153
    21612154// This pattern parses an old-style K&R function declarator (OBSOLESCENT, see 4) that is not redefining a
     
    21642157
    21652158old_function_declarator:
    2166                 old_function_no_ptr
    2167                 | old_function_ptr
    2168                 | old_function_array
    2169                 ;
     2159        old_function_no_ptr
     2160        | old_function_ptr
     2161        | old_function_array
     2162        ;
    21702163
    21712164old_function_no_ptr:
    2172                 paren_identifier '(' identifier_list ')'                // function_declarator handles empty parameter
    2173                                 { $$ = $1->addIdList( $3 ); }
    2174                 | '(' old_function_ptr ')' '(' identifier_list ')'
    2175                                 { $$ = $2->addIdList( $5 ); }
    2176                 | '(' old_function_no_ptr ')'                                   // redundant parenthesis
    2177                                 { $$ = $2; }
    2178                 ;
     2165        paren_identifier '(' identifier_list ')'                        // function_declarator handles empty parameter
     2166                { $$ = $1->addIdList( $3 ); }
     2167        | '(' old_function_ptr ')' '(' identifier_list ')'
     2168                { $$ = $2->addIdList( $5 ); }
     2169        | '(' old_function_no_ptr ')'                                           // redundant parenthesis
     2170                { $$ = $2; }
     2171        ;
    21792172
    21802173old_function_ptr:
    2181                 '*' old_function_declarator
    2182                                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
    2183                 | '*' type_qualifier_list old_function_declarator
    2184                                 { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
    2185                 | '(' old_function_ptr ')'
    2186                                 { $$ = $2; }
    2187                 ;
     2174        '*' old_function_declarator
     2175                { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
     2176        | '*' type_qualifier_list old_function_declarator
     2177                { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
     2178        | '(' old_function_ptr ')'
     2179                { $$ = $2; }
     2180        ;
    21882181
    21892182old_function_array:
    2190                 '(' old_function_ptr ')' array_dimension
    2191                                 { $$ = $2->addArray( $4 ); }
    2192                 | '(' old_function_array ')' multi_array_dimension // redundant parenthesis
    2193                                 { $$ = $2->addArray( $4 ); }
    2194                 | '(' old_function_array ')'                                    // redundant parenthesis
    2195                                 { $$ = $2; }
    2196                 ;
     2183        '(' old_function_ptr ')' array_dimension
     2184                { $$ = $2->addArray( $4 ); }
     2185        | '(' old_function_array ')' multi_array_dimension      // redundant parenthesis
     2186                { $$ = $2->addArray( $4 ); }
     2187        | '(' old_function_array ')'                                            // redundant parenthesis
     2188                { $$ = $2; }
     2189        ;
    21972190
    21982191// This pattern parses a declaration for a variable or function prototype that redefines a typedef name, e.g.:
     
    22072200
    22082201typedef_redeclarator:
    2209                 paren_typedef attribute_list_opt
    2210                 | typedef_ptr
    2211                 | typedef_array attribute_list_opt
    2212                 | typedef_function attribute_list_opt
    2213                 ;
     2202        paren_typedef attribute_list_opt
     2203        | typedef_ptr
     2204        | typedef_array attribute_list_opt
     2205        | typedef_function attribute_list_opt
     2206        ;
    22142207
    22152208paren_typedef:
    2216                 TYPEDEFname
    2217                                 {
    2218                                 typedefTable.setNextIdentifier( *($1) );
    2219                                 $$ = DeclarationNode::newName( $1 );
    2220                                 }
    2221                 | '(' paren_typedef ')'
    2222                                 { $$ = $2; }
    2223                 ;
     2209        TYPEDEFname
     2210                {
     2211                        typedefTable.setNextIdentifier( *($1) );
     2212                        $$ = DeclarationNode::newName( $1 );
     2213                }
     2214        | '(' paren_typedef ')'
     2215                { $$ = $2; }
     2216        ;
    22242217
    22252218typedef_ptr:
    2226                 '*' typedef_redeclarator
    2227                                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
    2228                 | '*' type_qualifier_list typedef_redeclarator
    2229                                 { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
    2230                 | '(' typedef_ptr ')'
    2231                                 { $$ = $2; }
    2232                 ;
     2219        '*' typedef_redeclarator
     2220                { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
     2221        | '*' type_qualifier_list typedef_redeclarator
     2222                { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
     2223        | '(' typedef_ptr ')'
     2224                { $$ = $2; }
     2225        ;
    22332226
    22342227typedef_array:
    2235                 paren_typedef array_dimension
    2236                                 { $$ = $1->addArray( $2 ); }
    2237                 | '(' typedef_ptr ')' array_dimension
    2238                                 { $$ = $2->addArray( $4 ); }
    2239                 | '(' typedef_array ')' multi_array_dimension   // redundant parenthesis
    2240                                 { $$ = $2->addArray( $4 ); }
    2241                 | '(' typedef_array ')'                                                 // redundant parenthesis
    2242                                 { $$ = $2; }
    2243                 ;
     2228        paren_typedef array_dimension
     2229                { $$ = $1->addArray( $2 ); }
     2230        | '(' typedef_ptr ')' array_dimension
     2231                { $$ = $2->addArray( $4 ); }
     2232        | '(' typedef_array ')' multi_array_dimension           // redundant parenthesis
     2233                { $$ = $2->addArray( $4 ); }
     2234        | '(' typedef_array ')'                                                         // redundant parenthesis
     2235                { $$ = $2; }
     2236        ;
    22442237
    22452238typedef_function:
    2246                 paren_typedef '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    2247                                 { $$ = $1->addParamList( $4 ); }
    2248                 | '(' typedef_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    2249                                 { $$ = $2->addParamList( $6 ); }
    2250                 | '(' typedef_function ')'                                              // redundant parenthesis
    2251                                 { $$ = $2; }
    2252                 ;
     2239        paren_typedef '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
     2240                { $$ = $1->addParamList( $4 ); }
     2241        | '(' typedef_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
     2242                { $$ = $2->addParamList( $6 ); }
     2243        | '(' typedef_function ')'                                                      // redundant parenthesis
     2244                { $$ = $2; }
     2245        ;
    22532246
    22542247// This pattern parses a declaration for a parameter variable or function prototype that is not redefining a
     
    22582251
    22592252identifier_parameter_declarator:
    2260                 paren_identifier attribute_list_opt
    2261                 | identifier_parameter_ptr
    2262                 | identifier_parameter_array attribute_list_opt
    2263                 | identifier_parameter_function attribute_list_opt
    2264                 ;
     2253        paren_identifier attribute_list_opt
     2254        | identifier_parameter_ptr
     2255        | identifier_parameter_array attribute_list_opt
     2256        | identifier_parameter_function attribute_list_opt
     2257        ;
    22652258
    22662259identifier_parameter_ptr:
    2267                 '*' identifier_parameter_declarator
    2268                                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
    2269                 | '*' type_qualifier_list identifier_parameter_declarator
    2270                                 { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
    2271                 | '(' identifier_parameter_ptr ')'
    2272                                 { $$ = $2; }
    2273                 ;
     2260        '*' identifier_parameter_declarator
     2261                { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
     2262        | '*' type_qualifier_list identifier_parameter_declarator
     2263                { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
     2264        | '(' identifier_parameter_ptr ')'
     2265                { $$ = $2; }
     2266        ;
    22742267
    22752268identifier_parameter_array:
    2276                 paren_identifier array_parameter_dimension
    2277                                 { $$ = $1->addArray( $2 ); }
    2278                 | '(' identifier_parameter_ptr ')' array_dimension
    2279                                 { $$ = $2->addArray( $4 ); }
    2280                 | '(' identifier_parameter_array ')' multi_array_dimension // redundant parenthesis
    2281                                 { $$ = $2->addArray( $4 ); }
    2282                 | '(' identifier_parameter_array ')'                    // redundant parenthesis
    2283                                 { $$ = $2; }
    2284                 ;
     2269        paren_identifier array_parameter_dimension
     2270                { $$ = $1->addArray( $2 ); }
     2271        | '(' identifier_parameter_ptr ')' array_dimension
     2272                { $$ = $2->addArray( $4 ); }
     2273        | '(' identifier_parameter_array ')' multi_array_dimension // redundant parenthesis
     2274                { $$ = $2->addArray( $4 ); }
     2275        | '(' identifier_parameter_array ')'                            // redundant parenthesis
     2276                { $$ = $2; }
     2277        ;
    22852278
    22862279identifier_parameter_function:
    2287                 paren_identifier '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    2288                                 { $$ = $1->addParamList( $4 ); }
    2289                 | '(' identifier_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    2290                                 { $$ = $2->addParamList( $6 ); }
    2291                 | '(' identifier_parameter_function ')'                 // redundant parenthesis
    2292                                 { $$ = $2; }
    2293                 ;
     2280        paren_identifier '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
     2281                { $$ = $1->addParamList( $4 ); }
     2282        | '(' identifier_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
     2283                { $$ = $2->addParamList( $6 ); }
     2284        | '(' identifier_parameter_function ')'                         // redundant parenthesis
     2285                { $$ = $2; }
     2286        ;
    22942287
    22952288// This pattern parses a declaration for a parameter variable or function prototype that is redefining a
     
    23092302//
    23102303//              typedef float T;
    2311 //              int f( int ( T [5] ) );                                         // see abstract_parameter_declarator
     2304//              int f( int ( T [5] ) );                                 // see abstract_parameter_declarator
    23122305//              int g( int ( T ( int ) ) );                             // see abstract_parameter_declarator
    23132306//              int f( int f1( T a[5] ) );                              // see identifier_parameter_declarator
     
    23202313
    23212314typedef_parameter_redeclarator:
    2322                 typedef attribute_list_opt
    2323                 | typedef_parameter_ptr
    2324                 | typedef_parameter_array attribute_list_opt
    2325                 | typedef_parameter_function attribute_list_opt
    2326                 ;
     2315        typedef attribute_list_opt
     2316        | typedef_parameter_ptr
     2317        | typedef_parameter_array attribute_list_opt
     2318        | typedef_parameter_function attribute_list_opt
     2319        ;
    23272320
    23282321typedef:
    2329                 TYPEDEFname
    2330                                 {
    2331                                         typedefTable.setNextIdentifier( *($1) );
    2332                                         $$ = DeclarationNode::newName( $1 );
    2333                                 }
    2334                 ;
     2322        TYPEDEFname
     2323                {
     2324                        typedefTable.setNextIdentifier( *($1) );
     2325                        $$ = DeclarationNode::newName( $1 );
     2326                }
     2327        ;
    23352328
    23362329typedef_parameter_ptr:
    2337                 '*' typedef_parameter_redeclarator
    2338                                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
    2339                 | '*' type_qualifier_list typedef_parameter_redeclarator
    2340                                 { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
    2341                 | '(' typedef_parameter_ptr ')'
    2342                                 { $$ = $2; }
    2343                 ;
     2330        '*' typedef_parameter_redeclarator
     2331                { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
     2332        | '*' type_qualifier_list typedef_parameter_redeclarator
     2333                { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
     2334        | '(' typedef_parameter_ptr ')'
     2335                { $$ = $2; }
     2336        ;
    23442337
    23452338typedef_parameter_array:
    2346                 typedef array_parameter_dimension
    2347                                 { $$ = $1->addArray( $2 ); }
    2348                 | '(' typedef_parameter_ptr ')' array_parameter_dimension
    2349                                 { $$ = $2->addArray( $4 ); }
    2350                 ;
     2339        typedef array_parameter_dimension
     2340                { $$ = $1->addArray( $2 ); }
     2341        | '(' typedef_parameter_ptr ')' array_parameter_dimension
     2342                { $$ = $2->addArray( $4 ); }
     2343        ;
    23512344
    23522345typedef_parameter_function:
    2353                 typedef '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    2354                                 { $$ = $1->addParamList( $4 ); }
    2355                 | '(' typedef_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    2356                                 { $$ = $2->addParamList( $6 ); }
    2357                 ;
     2346        typedef '(' push parameter_type_list_opt pop ')'        // empty parameter list OBSOLESCENT (see 3)
     2347                { $$ = $1->addParamList( $4 ); }
     2348        | '(' typedef_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
     2349                { $$ = $2->addParamList( $6 ); }
     2350        ;
    23582351
    23592352// This pattern parses a declaration of an abstract variable or function prototype, i.e., there is no
     
    23672360
    23682361abstract_declarator:
    2369                 abstract_ptr
    2370                 | abstract_array attribute_list_opt
    2371                 | abstract_function attribute_list_opt
    2372                 ;
     2362        abstract_ptr
     2363        | abstract_array attribute_list_opt
     2364        | abstract_function attribute_list_opt
     2365        ;
    23732366
    23742367abstract_ptr:
    2375                 '*'
    2376                                 { $$ = DeclarationNode::newPointer( 0 ); }
    2377                 | '*' type_qualifier_list
    2378                                 { $$ = DeclarationNode::newPointer( $2 ); }
    2379                 | '*' abstract_declarator
    2380                                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
    2381                 | '*' type_qualifier_list abstract_declarator
    2382                                 { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
    2383                 | '(' abstract_ptr ')'
    2384                                 { $$ = $2; }
    2385                 ;
     2368        '*'
     2369                { $$ = DeclarationNode::newPointer( 0 ); }
     2370        | '*' type_qualifier_list
     2371                { $$ = DeclarationNode::newPointer( $2 ); }
     2372        | '*' abstract_declarator
     2373                { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
     2374        | '*' type_qualifier_list abstract_declarator
     2375                { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
     2376        | '(' abstract_ptr ')'
     2377                { $$ = $2; }
     2378        ;
    23862379
    23872380abstract_array:
    2388                 array_dimension
    2389                 | '(' abstract_ptr ')' array_dimension
    2390                                 { $$ = $2->addArray( $4 ); }
    2391                 | '(' abstract_array ')' multi_array_dimension  // redundant parenthesis
    2392                                 { $$ = $2->addArray( $4 ); }
    2393                 | '(' abstract_array ')'                                                // redundant parenthesis
    2394                                 { $$ = $2; }
    2395                 ;
     2381        array_dimension
     2382        | '(' abstract_ptr ')' array_dimension
     2383                { $$ = $2->addArray( $4 ); }
     2384        | '(' abstract_array ')' multi_array_dimension          // redundant parenthesis
     2385                { $$ = $2->addArray( $4 ); }
     2386        | '(' abstract_array ')'                                                        // redundant parenthesis
     2387                { $$ = $2; }
     2388        ;
    23962389
    23972390abstract_function:
    2398                 '(' push parameter_type_list_opt pop ')'                // empty parameter list OBSOLESCENT (see 3)
    2399                                 { $$ = DeclarationNode::newFunction( 0, 0, $3, 0 ); }
    2400                 | '(' abstract_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    2401                                 { $$ = $2->addParamList( $6 ); }
    2402                 | '(' abstract_function ')'                                             // redundant parenthesis
    2403                                 { $$ = $2; }
    2404                 ;
     2391        '(' push parameter_type_list_opt pop ')'                        // empty parameter list OBSOLESCENT (see 3)
     2392                { $$ = DeclarationNode::newFunction( 0, 0, $3, 0 ); }
     2393        | '(' abstract_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
     2394                { $$ = $2->addParamList( $6 ); }
     2395        | '(' abstract_function ')'                                                     // redundant parenthesis
     2396                { $$ = $2; }
     2397        ;
    24052398
    24062399array_dimension:
    2407                                 // Only the first dimension can be empty.
    2408                 '[' push pop ']'
    2409                                 { $$ = DeclarationNode::newArray( 0, 0, false ); }
    2410                 | '[' push pop ']' multi_array_dimension
    2411                                 { $$ = DeclarationNode::newArray( 0, 0, false )->addArray( $5 ); }
    2412                 | multi_array_dimension
    2413                 ;
     2400                // Only the first dimension can be empty.
     2401        '[' push pop ']'
     2402                { $$ = DeclarationNode::newArray( 0, 0, false ); }
     2403        | '[' push pop ']' multi_array_dimension
     2404                { $$ = DeclarationNode::newArray( 0, 0, false )->addArray( $5 ); }
     2405        | multi_array_dimension
     2406        ;
    24142407
    24152408multi_array_dimension:
    2416                 '[' push assignment_expression pop ']'
    2417                                 { $$ = DeclarationNode::newArray( $3, 0, false ); }
    2418                 | '[' push '*' pop ']'                                                          // C99
    2419                                 { $$ = DeclarationNode::newVarArray( 0 ); }
    2420                 | multi_array_dimension '[' push assignment_expression pop ']'
    2421                                 { $$ = $1->addArray( DeclarationNode::newArray( $4, 0, false ) ); }
    2422                 | multi_array_dimension '[' push '*' pop ']'            // C99
    2423                                 { $$ = $1->addArray( DeclarationNode::newVarArray( 0 ) ); }
    2424                 ;
     2409        '[' push assignment_expression pop ']'
     2410                { $$ = DeclarationNode::newArray( $3, 0, false ); }
     2411        | '[' push '*' pop ']'                                                          // C99
     2412                { $$ = DeclarationNode::newVarArray( 0 ); }
     2413        | multi_array_dimension '[' push assignment_expression pop ']'
     2414                { $$ = $1->addArray( DeclarationNode::newArray( $4, 0, false ) ); }
     2415        | multi_array_dimension '[' push '*' pop ']'            // C99
     2416                { $$ = $1->addArray( DeclarationNode::newVarArray( 0 ) ); }
     2417        ;
    24252418
    24262419// This pattern parses a declaration of a parameter abstract variable or function prototype, i.e., there is no
     
    24342427
    24352428abstract_parameter_declarator:
    2436                 abstract_parameter_ptr
    2437                 | abstract_parameter_array attribute_list_opt
    2438                 | abstract_parameter_function attribute_list_opt
    2439                 ;
     2429        abstract_parameter_ptr
     2430        | abstract_parameter_array attribute_list_opt
     2431        | abstract_parameter_function attribute_list_opt
     2432        ;
    24402433
    24412434abstract_parameter_ptr:
    2442                 '*'
    2443                                 { $$ = DeclarationNode::newPointer( 0 ); }
    2444                 | '*' type_qualifier_list
    2445                                 { $$ = DeclarationNode::newPointer( $2 ); }
    2446                 | '*' abstract_parameter_declarator
    2447                                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
    2448                 | '*' type_qualifier_list abstract_parameter_declarator
    2449                                 { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
    2450                 | '(' abstract_parameter_ptr ')'
    2451                                 { $$ = $2; }
    2452                 ;
     2435        '*'
     2436                { $$ = DeclarationNode::newPointer( 0 ); }
     2437        | '*' type_qualifier_list
     2438                { $$ = DeclarationNode::newPointer( $2 ); }
     2439        | '*' abstract_parameter_declarator
     2440                { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
     2441        | '*' type_qualifier_list abstract_parameter_declarator
     2442                { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
     2443        | '(' abstract_parameter_ptr ')'
     2444                { $$ = $2; }
     2445        ;
    24532446
    24542447abstract_parameter_array:
    2455                 array_parameter_dimension
    2456                 | '(' abstract_parameter_ptr ')' array_parameter_dimension
    2457                                 { $$ = $2->addArray( $4 ); }
    2458                 | '(' abstract_parameter_array ')' multi_array_dimension // redundant parenthesis
    2459                                 { $$ = $2->addArray( $4 ); }
    2460                 | '(' abstract_parameter_array ')'                              // redundant parenthesis
    2461                                 { $$ = $2; }
    2462                 ;
     2448        array_parameter_dimension
     2449        | '(' abstract_parameter_ptr ')' array_parameter_dimension
     2450                { $$ = $2->addArray( $4 ); }
     2451        | '(' abstract_parameter_array ')' multi_array_dimension // redundant parenthesis
     2452                { $$ = $2->addArray( $4 ); }
     2453        | '(' abstract_parameter_array ')'                                      // redundant parenthesis
     2454                { $$ = $2; }
     2455        ;
    24632456
    24642457abstract_parameter_function:
    2465                 '(' push parameter_type_list_opt pop ')'                // empty parameter list OBSOLESCENT (see 3)
    2466                                 { $$ = DeclarationNode::newFunction( 0, 0, $3, 0 ); }
    2467                 | '(' abstract_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    2468                                 { $$ = $2->addParamList( $6 ); }
    2469                 | '(' abstract_parameter_function ')'                   // redundant parenthesis
    2470                                 { $$ = $2; }
    2471                 ;
     2458        '(' push parameter_type_list_opt pop ')'                        // empty parameter list OBSOLESCENT (see 3)
     2459                { $$ = DeclarationNode::newFunction( 0, 0, $3, 0 ); }
     2460        | '(' abstract_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
     2461                { $$ = $2->addParamList( $6 ); }
     2462        | '(' abstract_parameter_function ')'                           // redundant parenthesis
     2463                { $$ = $2; }
     2464        ;
    24722465
    24732466array_parameter_dimension:
    2474                                 // Only the first dimension can be empty or have qualifiers.
    2475                 array_parameter_1st_dimension
    2476                 | array_parameter_1st_dimension multi_array_dimension
    2477                                 { $$ = $1->addArray( $2 ); }
    2478                 | multi_array_dimension
    2479                 ;
     2467                // Only the first dimension can be empty or have qualifiers.
     2468        array_parameter_1st_dimension
     2469        | array_parameter_1st_dimension multi_array_dimension
     2470                { $$ = $1->addArray( $2 ); }
     2471        | multi_array_dimension
     2472        ;
    24802473
    24812474// The declaration of an array parameter has additional syntax over arrays in normal variable declarations:
     
    24862479
    24872480array_parameter_1st_dimension:
    2488                 '[' push pop ']'
    2489                                 { $$ = DeclarationNode::newArray( 0, 0, false ); }
    2490                 // multi_array_dimension handles the '[' '*' ']' case
    2491                 | '[' push type_qualifier_list '*' pop ']'              // remaining C99
    2492                                 { $$ = DeclarationNode::newVarArray( $3 ); }
    2493                 | '[' push type_qualifier_list pop ']'
    2494                                 { $$ = DeclarationNode::newArray( 0, $3, false ); }
    2495                 // multi_array_dimension handles the '[' assignment_expression ']' case
    2496                 | '[' push type_qualifier_list assignment_expression pop ']'
    2497                                 { $$ = DeclarationNode::newArray( $4, $3, false ); }
    2498                 | '[' push STATIC type_qualifier_list_opt assignment_expression pop ']'
    2499                                 { $$ = DeclarationNode::newArray( $5, $4, true ); }
    2500                 | '[' push type_qualifier_list STATIC assignment_expression pop ']'
    2501                                 { $$ = DeclarationNode::newArray( $5, $3, true ); }
    2502                 ;
     2481        '[' push pop ']'
     2482                { $$ = DeclarationNode::newArray( 0, 0, false ); }
     2483        // multi_array_dimension handles the '[' '*' ']' case
     2484        | '[' push type_qualifier_list '*' pop ']'                      // remaining C99
     2485                { $$ = DeclarationNode::newVarArray( $3 ); }
     2486        | '[' push type_qualifier_list pop ']'
     2487                { $$ = DeclarationNode::newArray( 0, $3, false ); }
     2488        // multi_array_dimension handles the '[' assignment_expression ']' case
     2489        | '[' push type_qualifier_list assignment_expression pop ']'
     2490                { $$ = DeclarationNode::newArray( $4, $3, false ); }
     2491        | '[' push STATIC type_qualifier_list_opt assignment_expression pop ']'
     2492                { $$ = DeclarationNode::newArray( $5, $4, true ); }
     2493        | '[' push type_qualifier_list STATIC assignment_expression pop ']'
     2494                { $$ = DeclarationNode::newArray( $5, $3, true ); }
     2495        ;
    25032496
    25042497// This pattern parses a declaration of an abstract variable, i.e., there is no identifier to which the type
     
    25112504
    25122505variable_abstract_declarator:
    2513                 variable_abstract_ptr
    2514                 | variable_abstract_array attribute_list_opt
    2515                 | variable_abstract_function attribute_list_opt
    2516                 ;
     2506        variable_abstract_ptr
     2507        | variable_abstract_array attribute_list_opt
     2508        | variable_abstract_function attribute_list_opt
     2509        ;
    25172510
    25182511variable_abstract_ptr:
    2519                 '*'
    2520                                 { $$ = DeclarationNode::newPointer( 0 ); }
    2521                 | '*' type_qualifier_list
    2522                                 { $$ = DeclarationNode::newPointer( $2 ); }
    2523                 | '*' variable_abstract_declarator
    2524                                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
    2525                 | '*' type_qualifier_list variable_abstract_declarator
    2526                                 { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
    2527                 | '(' variable_abstract_ptr ')'
    2528                                 { $$ = $2; }
    2529                 ;
     2512        '*'
     2513                { $$ = DeclarationNode::newPointer( 0 ); }
     2514        | '*' type_qualifier_list
     2515                { $$ = DeclarationNode::newPointer( $2 ); }
     2516        | '*' variable_abstract_declarator
     2517                { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
     2518        | '*' type_qualifier_list variable_abstract_declarator
     2519                { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
     2520        | '(' variable_abstract_ptr ')'
     2521                { $$ = $2; }
     2522        ;
    25302523
    25312524variable_abstract_array:
    2532                 array_dimension
    2533                 | '(' variable_abstract_ptr ')' array_dimension
    2534                                 { $$ = $2->addArray( $4 ); }
    2535                 | '(' variable_abstract_array ')' multi_array_dimension // redundant parenthesis
    2536                                 { $$ = $2->addArray( $4 ); }
    2537                 | '(' variable_abstract_array ')'                               // redundant parenthesis
    2538                                 { $$ = $2; }
    2539                 ;
     2525        array_dimension
     2526        | '(' variable_abstract_ptr ')' array_dimension
     2527                { $$ = $2->addArray( $4 ); }
     2528        | '(' variable_abstract_array ')' multi_array_dimension // redundant parenthesis
     2529                { $$ = $2->addArray( $4 ); }
     2530        | '(' variable_abstract_array ')'                                       // redundant parenthesis
     2531                { $$ = $2; }
     2532        ;
    25402533
    25412534variable_abstract_function:
    2542                 '(' variable_abstract_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    2543                                 { $$ = $2->addParamList( $6 ); }
    2544                 | '(' variable_abstract_function ')'                    // redundant parenthesis
    2545                                 { $$ = $2; }
    2546                 ;
     2535        '(' variable_abstract_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
     2536                { $$ = $2->addParamList( $6 ); }
     2537        | '(' variable_abstract_function ')'                            // redundant parenthesis
     2538                { $$ = $2; }
     2539        ;
    25472540
    25482541// This pattern parses a new-style declaration for a parameter variable or function prototype that is either
     
    25502543
    25512544new_identifier_parameter_declarator_tuple:                              // CFA
    2552                 new_identifier_parameter_declarator_no_tuple
    2553                 | new_abstract_tuple
    2554                 | type_qualifier_list new_abstract_tuple
    2555                                 { $$ = $2->addQualifiers( $1 ); }
    2556                 ;
     2545        new_identifier_parameter_declarator_no_tuple
     2546        | new_abstract_tuple
     2547        | type_qualifier_list new_abstract_tuple
     2548                { $$ = $2->addQualifiers( $1 ); }
     2549        ;
    25572550
    25582551new_identifier_parameter_declarator_no_tuple:                   // CFA
    2559                 new_identifier_parameter_ptr
    2560                 | new_identifier_parameter_array
    2561                 ;
     2552        new_identifier_parameter_ptr
     2553        | new_identifier_parameter_array
     2554        ;
    25622555
    25632556new_identifier_parameter_ptr:                                                   // CFA
    2564                 '*' type_specifier
    2565                                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
    2566                 | type_qualifier_list '*' type_specifier
    2567                                 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
    2568                 | '*' new_abstract_function
    2569                                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
    2570                 | type_qualifier_list '*' new_abstract_function
    2571                                 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
    2572                 | '*' new_identifier_parameter_declarator_tuple
    2573                                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
    2574                 | type_qualifier_list '*' new_identifier_parameter_declarator_tuple
    2575                                 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
    2576                 ;
     2557        '*' type_specifier
     2558                { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
     2559        | type_qualifier_list '*' type_specifier
     2560                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
     2561        | '*' new_abstract_function
     2562                { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
     2563        | type_qualifier_list '*' new_abstract_function
     2564                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
     2565        | '*' new_identifier_parameter_declarator_tuple
     2566                { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
     2567        | type_qualifier_list '*' new_identifier_parameter_declarator_tuple
     2568                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
     2569        ;
    25772570
    25782571new_identifier_parameter_array:                                                 // CFA
    2579                                 // Only the first dimension can be empty or have qualifiers. Empty dimension must be factored
    2580                                 // out due to shift/reduce conflict with new-style empty (void) function return type.
    2581                 '[' push pop ']' type_specifier
    2582                                 { $$ = $5->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
    2583                 | new_array_parameter_1st_dimension type_specifier
    2584                                 { $$ = $2->addNewArray( $1 ); }
    2585                 | '[' push pop ']' multi_array_dimension type_specifier
    2586                                 { $$ = $6->addNewArray( $5 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
    2587                 | new_array_parameter_1st_dimension multi_array_dimension type_specifier
    2588                                 { $$ = $3->addNewArray( $2 )->addNewArray( $1 ); }
    2589                 | multi_array_dimension type_specifier
    2590                                 { $$ = $2->addNewArray( $1 ); }
    2591                 | '[' push pop ']' new_identifier_parameter_ptr
    2592                                 { $$ = $5->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
    2593                 | new_array_parameter_1st_dimension new_identifier_parameter_ptr
    2594                                 { $$ = $2->addNewArray( $1 ); }
    2595                 | '[' push pop ']' multi_array_dimension new_identifier_parameter_ptr
    2596                                 { $$ = $6->addNewArray( $5 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
    2597                 | new_array_parameter_1st_dimension multi_array_dimension new_identifier_parameter_ptr
    2598                                 { $$ = $3->addNewArray( $2 )->addNewArray( $1 ); }
    2599                 | multi_array_dimension new_identifier_parameter_ptr
    2600                                 { $$ = $2->addNewArray( $1 ); }
    2601                 ;
     2572                // Only the first dimension can be empty or have qualifiers. Empty dimension must be factored out due
     2573                // to shift/reduce conflict with new-style empty (void) function return type.
     2574        '[' push pop ']' type_specifier
     2575                { $$ = $5->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     2576        | new_array_parameter_1st_dimension type_specifier
     2577                { $$ = $2->addNewArray( $1 ); }
     2578        | '[' push pop ']' multi_array_dimension type_specifier
     2579                { $$ = $6->addNewArray( $5 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     2580        | new_array_parameter_1st_dimension multi_array_dimension type_specifier
     2581                { $$ = $3->addNewArray( $2 )->addNewArray( $1 ); }
     2582        | multi_array_dimension type_specifier
     2583                { $$ = $2->addNewArray( $1 ); }
     2584        | '[' push pop ']' new_identifier_parameter_ptr
     2585                { $$ = $5->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     2586        | new_array_parameter_1st_dimension new_identifier_parameter_ptr
     2587                { $$ = $2->addNewArray( $1 ); }
     2588        | '[' push pop ']' multi_array_dimension new_identifier_parameter_ptr
     2589                { $$ = $6->addNewArray( $5 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     2590        | new_array_parameter_1st_dimension multi_array_dimension new_identifier_parameter_ptr
     2591                { $$ = $3->addNewArray( $2 )->addNewArray( $1 ); }
     2592        | multi_array_dimension new_identifier_parameter_ptr
     2593                { $$ = $2->addNewArray( $1 ); }
     2594        ;
    26022595
    26032596new_array_parameter_1st_dimension:
    2604                 '[' push type_qualifier_list '*' pop ']'                // remaining C99
    2605                                 { $$ = DeclarationNode::newVarArray( $3 ); }
    2606                 | '[' push type_qualifier_list assignment_expression pop ']'
    2607                                 { $$ = DeclarationNode::newArray( $4, $3, false ); }
    2608                 | '[' push declaration_qualifier_list assignment_expression pop ']'
    2609                                 // declaration_qualifier_list must be used because of shift/reduce conflict with
    2610                                 // assignment_expression, so a semantic check is necessary to preclude them as a
    2611                                 // type_qualifier cannot appear in this context.
    2612                                 { $$ = DeclarationNode::newArray( $4, $3, true ); }
    2613                 | '[' push declaration_qualifier_list type_qualifier_list assignment_expression pop ']'
    2614                                 { $$ = DeclarationNode::newArray( $5, $4->addQualifiers( $3 ), true ); }
    2615                 ;
     2597        '[' push type_qualifier_list '*' pop ']'                        // remaining C99
     2598                { $$ = DeclarationNode::newVarArray( $3 ); }
     2599        | '[' push type_qualifier_list assignment_expression pop ']'
     2600                { $$ = DeclarationNode::newArray( $4, $3, false ); }
     2601        | '[' push declaration_qualifier_list assignment_expression pop ']'
     2602                // declaration_qualifier_list must be used because of shift/reduce conflict with
     2603                // assignment_expression, so a semantic check is necessary to preclude them as a type_qualifier cannot
     2604                // appear in this context.
     2605                { $$ = DeclarationNode::newArray( $4, $3, true ); }
     2606        | '[' push declaration_qualifier_list type_qualifier_list assignment_expression pop ']'
     2607                { $$ = DeclarationNode::newArray( $5, $4->addQualifiers( $3 ), true ); }
     2608        ;
    26162609
    26172610// This pattern parses a new-style declaration of an abstract variable or function prototype, i.e., there is
     
    26372630
    26382631new_abstract_declarator_tuple:                                                  // CFA
    2639                 new_abstract_tuple
    2640                 | type_qualifier_list new_abstract_tuple
    2641                                 { $$ = $2->addQualifiers( $1 ); }
    2642                 | new_abstract_declarator_no_tuple
    2643                 ;
     2632        new_abstract_tuple
     2633        | type_qualifier_list new_abstract_tuple
     2634                { $$ = $2->addQualifiers( $1 ); }
     2635        | new_abstract_declarator_no_tuple
     2636        ;
    26442637
    26452638new_abstract_declarator_no_tuple:                                               // CFA
    2646                 new_abstract_ptr
    2647                 | new_abstract_array
    2648                 ;
     2639        new_abstract_ptr
     2640        | new_abstract_array
     2641        ;
    26492642
    26502643new_abstract_ptr:                                                                               // CFA
    2651                 '*' type_specifier
    2652                                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
    2653                 | type_qualifier_list '*' type_specifier
    2654                                 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
    2655                 | '*' new_abstract_function
    2656                                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
    2657                 | type_qualifier_list '*' new_abstract_function
    2658                                 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
    2659                 | '*' new_abstract_declarator_tuple
    2660                                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
    2661                 | type_qualifier_list '*' new_abstract_declarator_tuple
    2662                                 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
    2663                 ;
     2644        '*' type_specifier
     2645                { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
     2646        | type_qualifier_list '*' type_specifier
     2647                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
     2648        | '*' new_abstract_function
     2649                { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
     2650        | type_qualifier_list '*' new_abstract_function
     2651                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
     2652        | '*' new_abstract_declarator_tuple
     2653                { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
     2654        | type_qualifier_list '*' new_abstract_declarator_tuple
     2655                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
     2656        ;
    26642657
    26652658new_abstract_array:                                                                             // CFA
    2666                                 // Only the first dimension can be empty. Empty dimension must be factored out due to
    2667                                 // shift/reduce conflict with empty (void) function return type.
    2668                 '[' push pop ']' type_specifier
    2669                                 { $$ = $5->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
    2670                 | '[' push pop ']' multi_array_dimension type_specifier
    2671                                 { $$ = $6->addNewArray( $5 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
    2672                 | multi_array_dimension type_specifier
    2673                                 { $$ = $2->addNewArray( $1 ); }
    2674                 | '[' push pop ']' new_abstract_ptr
    2675                                 { $$ = $5->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
    2676                 | '[' push pop ']' multi_array_dimension new_abstract_ptr
    2677                                 { $$ = $6->addNewArray( $5 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
    2678                 | multi_array_dimension new_abstract_ptr
    2679                                 { $$ = $2->addNewArray( $1 ); }
    2680                 ;
     2659                // Only the first dimension can be empty. Empty dimension must be factored out due to shift/reduce
     2660                // conflict with empty (void) function return type.
     2661        '[' push pop ']' type_specifier
     2662                { $$ = $5->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     2663        | '[' push pop ']' multi_array_dimension type_specifier
     2664                { $$ = $6->addNewArray( $5 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     2665        | multi_array_dimension type_specifier
     2666                { $$ = $2->addNewArray( $1 ); }
     2667        | '[' push pop ']' new_abstract_ptr
     2668                { $$ = $5->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     2669        | '[' push pop ']' multi_array_dimension new_abstract_ptr
     2670                { $$ = $6->addNewArray( $5 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     2671        | multi_array_dimension new_abstract_ptr
     2672                { $$ = $2->addNewArray( $1 ); }
     2673        ;
    26812674
    26822675new_abstract_tuple:                                                                             // CFA
    2683                 '[' push new_abstract_parameter_list pop ']'
    2684                                 { $$ = DeclarationNode::newTuple( $3 ); }
    2685                 ;
     2676        '[' push new_abstract_parameter_list pop ']'
     2677                { $$ = DeclarationNode::newTuple( $3 ); }
     2678        ;
    26862679
    26872680new_abstract_function:                                                                  // CFA
    2688                 '[' push pop ']' '(' new_parameter_type_list_opt ')'
    2689                                 { $$ = DeclarationNode::newFunction( 0, DeclarationNode::newTuple( 0 ), $6, 0 ); }
    2690                 | new_abstract_tuple '(' push new_parameter_type_list_opt pop ')'
    2691                                 { $$ = DeclarationNode::newFunction( 0, $1, $4, 0 ); }
    2692                 | new_function_return '(' push new_parameter_type_list_opt pop ')'
    2693                                 { $$ = DeclarationNode::newFunction( 0, $1, $4, 0 ); }
    2694                 ;
     2681        '[' push pop ']' '(' new_parameter_type_list_opt ')'
     2682                { $$ = DeclarationNode::newFunction( 0, DeclarationNode::newTuple( 0 ), $6, 0 ); }
     2683        | new_abstract_tuple '(' push new_parameter_type_list_opt pop ')'
     2684                { $$ = DeclarationNode::newFunction( 0, $1, $4, 0 ); }
     2685        | new_function_return '(' push new_parameter_type_list_opt pop ')'
     2686                { $$ = DeclarationNode::newFunction( 0, $1, $4, 0 ); }
     2687        ;
    26952688
    26962689// 1) ISO/IEC 9899:1999 Section 6.7.2(2) : "At least one type specifier shall be given in the declaration
     
    27112704
    27122705comma_opt:                                                                                              // redundant comma
    2713                 // empty
    2714                 | ','
    2715                 ;
     2706        // empty
     2707        | ','
     2708        ;
    27162709
    27172710assignment_opt:
    2718                 // empty
    2719                                 { $$ = 0; }
    2720                 | '=' assignment_expression
    2721                                 { $$ = $2; }
    2722                 ;
     2711        // empty
     2712                { $$ = 0; }
     2713        | '=' assignment_expression
     2714                { $$ = $2; }
     2715        ;
    27232716
    27242717%%
Note: See TracChangeset for help on using the changeset viewer.