Changeset 7fdb94e


Ignore:
Timestamp:
May 21, 2018, 10:48:05 PM (4 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, with_gc
Children:
b12c036
Parents:
4358c1e
Message:

rewrite TypedefTable?

Location:
src/Parser
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/DeclarationNode.cc

    r4358c1e r7fdb94e  
    1010// Created On       : Sat May 16 12:34:05 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed May 16 09:37:17 2018
    13 // Update Count     : 1070
     12// Last Modified On : Mon May 21 20:36:45 2018
     13// Update Count     : 1073
    1414//
    1515
     
    179179        newnode->type->function.body = body;
    180180
    181         // ignore unnamed routine declarations: void p( int (*)(int) );
    182         if ( newnode->name ) {
    183                 typedefTable.addToEnclosingScope( *newnode->name, TypedefTable::ID );
    184         } // if
    185 
    186181        if ( ret ) {
    187182                newnode->type->base = ret->type;
     
    285280        newnode->name = name;
    286281        newnode->enumeratorValue.reset( constant );
    287         typedefTable.addToEnclosingScope( *newnode->name, TypedefTable::ID );
    288282        return newnode;
    289283} // DeclarationNode::newEnumConstant
  • src/Parser/TypedefTable.cc

    r4358c1e r7fdb94e  
    77// TypedefTable.cc --
    88//
    9 // Author           : Rodolfo G. Esteves
     9// Author           : Peter A. Buhr
    1010// Created On       : Sat May 16 15:20:13 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Aug 15 18:24:42 2016
    13 // Update Count     : 25
     12// Last Modified On : Mon May 21 20:55:24 2018
     13// Update Count     : 117
    1414//
    1515
    16 #include <ext/alloc_traits.h>    // for __alloc_traits<>::value_type
     16
     17#include "TypedefTable.h"
    1718#include <cassert>               // for assert
    18 #include <list>                  // for list, _List_iterator, list<>::iterator
    19 #include <map>                   // for _Rb_tree_iterator, _Rb_tree_const_it...
    20 #include <memory>                // for allocator_traits<>::value_type
    21 #include <utility>               // for pair
    22 
    23 #include "Parser/ParserTypes.h"  // for typedefTable
    24 #include "Parser/parser.hh"      // for IDENTIFIER
    25 #include "TypedefTable.h"
    26 
    27 using namespace std;
    2819
    2920#if 0
    3021#include <iostream>
    31 
    3222#define debugPrint( x ) cerr << x
    3323#else
     
    3525#endif
    3626
    37 TypedefTable::TypedefTable() : currentScope( 0 ) {}
     27using namespace std;
    3828
    39 bool TypedefTable::exists( const string &identifier ) {
    40         return table.count( identifier ) > 0;
    41 }
     29TypedefTable::~TypedefTable() {
     30        if ( ! SemanticErrorThrow && kindTable.currentScope() != 0 ) {
     31                // std::cerr << "scope failure " << kindTable.currentScope() << endl;
     32        } // if
     33} // TypedefTable::~TypedefTable
    4234
    43 int TypedefTable::isKind( const string &identifier ) const {
    44         tableType::const_iterator id_pos = table.find( identifier );
     35bool TypedefTable::exists( const string & identifier ) {
     36        return kindTable.find( identifier ) != kindTable.end();
     37} // TypedefTable::exists
     38
     39int TypedefTable::isKind( const string & identifier ) const {
    4540        // Name lookup defaults to identifier, and then the identifier's kind is set by the parser.
    46         if ( id_pos == table.end() ) return IDENTIFIER;
    47         return id_pos->second.begin()->kind;
    48 }
     41        KindTable::const_iterator posn = kindTable.find( identifier );
     42        if ( posn == kindTable.end() ) return IDENTIFIER;
     43        return posn->second;
     44} // TypedefTable::isKind
    4945
    50 void TypedefTable::changeKind( const string &identifier, kind_t kind ) {
    51         tableType::iterator id_pos = table.find( identifier );
    52         if ( id_pos == table.end() ) return;
    53         id_pos->second.begin()->kind = kind;
    54 }
     46void TypedefTable::changeKind( const string & identifier, kind_t kind ) {
     47        KindTable::iterator posn = kindTable.find( identifier );
     48        if ( posn != kindTable.end() ) posn->second = kind;
     49} // TypedefTable::changeKind
    5550
    5651// SKULLDUGGERY: Generate a typedef for the aggregate name so the aggregate does not have to be qualified by
    57 // "struct". Only generate the typedef, if the name is not in use. The typedef is implicitly (silently) removed
    58 // if the name is explicitly used.
    59 void TypedefTable::makeTypedef( const string &name ) {
     52// "struct". Only generate the typedef, if the name is not in use. The typedef is implicitly (silently) removed if the
     53// name is explicitly used.
     54void TypedefTable::makeTypedef( const string & name ) {
    6055        if ( ! typedefTable.exists( name ) ) {
    6156                typedefTable.addToEnclosingScope( name, TypedefTable::TD );
    6257        } // if
    63 }
     58} // TypedefTable::makeTypedef
    6459
    65 void TypedefTable::addToScope( const std::string &identifier, kind_t kind, int scope ) {
    66         if ( currentTrait != "" && scope == contextScope ) {
    67                 DeferredEntry entry = { identifier, kind };
    68                 contexts[currentTrait].push_back( entry );
    69         } else {
    70                 debugPrint( "Adding " << identifier << " as kind " << kind << " scope " << scope << " from scope " << currentScope << endl );
    71                 Entry newEntry = { scope, kind };
    72                 tableType::iterator curPos = table.find( identifier );
    73                 if ( curPos == table.end()) {
    74                         list< Entry > newList;
    75                         newList.push_front( newEntry );
    76                         table[identifier] = newList;
    77                 } else {
    78                         list< Entry >::iterator listPos = (*curPos ).second.begin();
    79                         while ( listPos != (*curPos ).second.end() && listPos->scope > scope ) {
    80                                 listPos++;
    81                         } // while
    82                         (*curPos ).second.insert( listPos, newEntry );
    83                 } // if
     60void TypedefTable::addToEnclosingScope( const std::string & identifier, kind_t kind ) {
     61        assert( kindTable.currentScope() >= 1 );
     62        auto scope = kindTable.currentScope() - 1;
     63        debugPrint( "Adding " << identifier << " as kind " << kind << " scope " << scope << endl );
     64        auto ret = kindTable.insertAt( scope, identifier, kind );
     65        if ( ! ret.second ) { // already an element there
     66                ret.first->second = kind; // update existing element with new kind
    8467        } // if
    85 }
    86 
    87 void TypedefTable::addToCurrentScope( const std::string &identifier, kind_t kind ) {
    88         addToScope( identifier, kind, currentScope );
    89 }
    90 
    91 void TypedefTable::addToCurrentScope( kind_t kind ) {
    92         addToCurrentScope( nextIdentifiers.top(), kind );
    93 }
    94 
    95 void TypedefTable::addToEnclosingScope( const std::string &identifier, kind_t kind ) {
    96         assert( currentScope >= 1 );
    97         addToScope( identifier, kind, currentScope - 1 );
    98 }
    99 
    100 void TypedefTable::addToEnclosingScope( kind_t kind ) {
    101         addToEnclosingScope( nextIdentifiers.top(), kind );
    102 }
    103 
    104 void TypedefTable::addToEnclosingScope2( const std::string &identifier, kind_t kind ) {
    105         assert( currentScope >= 2 );
    106         addToScope( identifier, kind, currentScope - 2 );
    107 }
    108 
    109 void TypedefTable::addToEnclosingScope2( kind_t kind ) {
    110         addToEnclosingScope2( nextIdentifiers.top(), kind );
    111 }
    112 
    113 void TypedefTable::setNextIdentifier( const std::string &identifier ) {
    114         nextIdentifiers.top() = identifier;
    115 }
    116 
    117 void TypedefTable::openTrait( const std::string &contextName ) {
    118         map< string, deferListType >::iterator i = contexts.find( contextName );
    119         if ( i != contexts.end() ) {
    120                 deferListType &entries = i->second;
    121                 for ( deferListType::iterator i = entries.begin(); i != entries.end(); i++) {
    122                         addToEnclosingScope( i->identifier, i->kind );
    123                 } // for
    124         } // if
    125 }
     68} // TypedefTable::addToEnclosingScope
    12669
    12770void TypedefTable::enterScope() {
    128         currentScope += 1;
    129         deferListStack.push( deferListType() );
    130         nextIdentifiers.push( "" );
    131         debugPrint( "Entering scope " << currentScope << ", nextIdentifiers size is " << nextIdentifiers.size() << endl );
    132 }
     71        kindTable.beginScope();
     72        debugPrint( "Entering scope " << kindTable.currentScope() << endl );
     73} // TypedefTable::enterScope
    13374
    13475void TypedefTable::leaveScope() {
    135         debugPrint( "Leaving scope " << currentScope << endl );
    136         for ( tableType::iterator i = table.begin(); i != table.end(); ) {
    137                 list< Entry > &declList = (*i).second;
    138                 while ( ! declList.empty() && declList.front().scope == currentScope ) {
    139                         declList.pop_front();
    140                 }
    141                 if ( declList.empty() ) {                                               // standard idom for erasing during traversal
    142                         table.erase( i++ );
    143                 } else
    144                         ++i;
    145         } // for
    146         currentScope -= 1;
    147         for ( deferListType::iterator i = deferListStack.top().begin(); i != deferListStack.top().end(); i++ ) {
    148                 addToCurrentScope( i->identifier, i->kind );
    149         } // for
    150         deferListStack.pop();
    151         debugPrint( "nextIdentifiers size is " << nextIdentifiers.size() << " top is " << nextIdentifiers.top() << endl );
    152         nextIdentifiers.pop();
    153 }
     76        debugPrint( "Leaving scope " << kindTable.currentScope() << endl );
     77        kindTable.endScope();
     78} // TypedefTable::leaveScope
    15479
    155 void TypedefTable::enterTrait( const std::string &contextName ) {
    156         currentTrait = contextName;
    157         contextScope = currentScope;
    158 }
    159 
    160 void TypedefTable::leaveTrait() {
    161         currentTrait = "";
    162 }
    163 
    164 void TypedefTable::print( void ) const {
    165         for ( tableType::const_iterator i = table.begin(); i != table.end(); i++) {
    166                 debugPrint( (*i ).first << ": " );
    167                 list< Entry > declList = (*i).second;
    168                 for ( list< Entry >::const_iterator j = declList.begin(); j != declList.end(); j++ ) {
    169                         debugPrint( "(" << (*j).scope << " " << (*j).kind << ") " );
    170                 }
    171                 debugPrint( endl );
    172         } // for
    173 }
     80// void TypedefTable::print( void ) const {
     81//      for ( KindTable::const_iterator i = table.begin(); i != table.end(); i++) {
     82//              debugPrint( (*i ).first << ": " );
     83//              list< Entry > declList = (*i).second;
     84//              for ( list< Entry >::const_iterator j = declList.begin(); j != declList.end(); j++ ) {
     85//                      debugPrint( "(" << (*j).scope << " " << (*j).kind << ") " );
     86//              }
     87//              debugPrint( endl );
     88//      } // for
     89// }
    17490
    17591// Local Variables: //
  • src/Parser/TypedefTable.h

    r4358c1e r7fdb94e  
    77// TypedefTable.h --
    88//
    9 // Author           : Rodolfo G. Esteves
     9// Author           : Peter A. Buhr
    1010// Created On       : Sat May 16 15:24:36 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 22 09:33:14 2017
    13 // Update Count     : 34
     12// Last Modified On : Mon May 21 20:28:01 2018
     13// Update Count     : 76
    1414//
    1515
    1616#pragma once
    1717
    18 #include <list>       // for list
    19 #include <map>        // for map, map<>::value_compare
    20 #include <stack>      // for stack
    21 #include <string>     // for string
     18#include <string>                                                                               // for string
    2219
     20#include "Common/ScopedMap.h"                                                   // for ScopedMap
    2321#include "ParserTypes.h"
    24 #include "parser.hh"  // for IDENTIFIER, TYPEDEFname, TYPEGENname
     22#include "parser.hh"                                                                    // for IDENTIFIER, TYPEDEFname, TYPEGENname
    2523
    2624class TypedefTable {
     
    2826        enum kind_t { ID = IDENTIFIER, TD = TYPEDEFname, TG = TYPEGENname };
    2927  private:
    30         struct Entry {
    31                 int scope;
    32                 kind_t kind;
    33         };
     28        typedef ScopedMap< std::string, kind_t > KindTable;
     29        KindTable kindTable;   
     30  public:
     31        ~TypedefTable();
    3432
    35         struct DeferredEntry {
    36                 std::string identifier;
    37                 kind_t kind;
    38         };
    39 
    40         typedef std::map< std::string, std::list< Entry > > tableType;
    41         tableType table;
    42 
    43         int currentScope;
    44         std::string currentTrait;
    45         int contextScope;
    46 
    47         typedef std::list< DeferredEntry > deferListType;
    48         std::stack< deferListType > deferListStack;
    49         std::map< std::string, deferListType > contexts;
    50 
    51         std::stack< std::string > nextIdentifiers;
    52 
    53         void addToScope( const std::string &identifier, kind_t kind, int scope );
    54   public:
    55         TypedefTable();
    56 
    57         bool exists( const std::string &identifier );
    58         int isKind( const std::string &identifier ) const;
    59         void changeKind( const std::string &identifier, kind_t kind );
    60 
    61         void makeTypedef( const std::string &name );
    62 
    63         // "addToCurrentScope" adds the identifier/type pair to the current scope. This does less than you think it does,
    64         // since each declaration is within its own scope.  Mostly useful for type parameters.
    65         void addToCurrentScope( const std::string &identifier, kind_t kind );
    66         void addToCurrentScope( kind_t kind );                  // use nextIdentifiers.top()
    67 
    68         // "addToEnclosingScope" adds the identifier/type pair to the scope that encloses the current one.  This is the
    69         // right way to handle type and typedef names
    70         void addToEnclosingScope( const std::string &identifier, kind_t kind );
    71         void addToEnclosingScope( kind_t kind );                // use nextIdentifiers.top()
    72 
    73         // "addToEnclosingScope2" adds the identifier/type pair to the scope that encloses the scope enclosing the the
    74         // current one.  This is the right way to handle assertion names
    75         void addToEnclosingScope2( const std::string &identifier, kind_t kind );
    76         void addToEnclosingScope2( kind_t kind );               // use nextIdentifiers.top()
    77 
    78         // set the next identifier to be used by an "add" operation without an identifier parameter within the current scope
    79         void setNextIdentifier( const std::string &identifier );
    80 
    81         // dump the definitions from a pre-defined context into the current scope
    82         void openTrait( const std::string &contextName );
     33        bool exists( const std::string & identifier );
     34        int isKind( const std::string & identifier ) const;
     35        void changeKind( const std::string & identifier, kind_t kind );
     36        void makeTypedef( const std::string & name );
     37        void addToEnclosingScope( const std::string & identifier, kind_t kind );
    8338
    8439        void enterScope();
    8540        void leaveScope();
    86         void enterTrait( const std::string &contextName );
    87         void leaveTrait();
    88 
    89         void print() const;
    90 };
     41}; // TypedefTable
    9142
    9243// Local Variables: //
  • src/Parser/parser.yy

    r4358c1e r7fdb94e  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri May 11 17:51:38 2018
    13 // Update Count     : 3261
     12// Last Modified On : Mon May 21 21:44:01 2018
     13// Update Count     : 3350
    1414//
    1515
     
    119119// Does the forall bind to the struct or the routine, and how would it be possible to explicitly specify the binding.
    120120//   forall( otype T ) struct S { int T; } forall( otype W ) bar( W ) {}
     121// Currently, the forall is associated with the routine, and the generic type has to be separately defined:
     122//   forall( otype T ) struct S { int T; };
     123//   forall( otype W ) bar( W ) {}
    121124
    122125void rebindForall( DeclarationNode * declSpec, DeclarationNode * funcDecl ) {
    123         if ( declSpec->type->kind == TypeData::Aggregate ) { // return is aggregate definition
     126        if ( declSpec->type->kind == TypeData::Aggregate ) { // ignore aggregate definition
    124127                funcDecl->type->forall = declSpec->type->aggregate.params; // move forall from aggregate to function type
    125128                declSpec->type->aggregate.params = nullptr;
     
    301304%type<decl> exception_declaration external_definition external_definition_list external_definition_list_opt
    302305
    303 %type<decl> field_declaration field_declaration_list field_declarator field_declaring_list
     306%type<decl> field_declaration field_declaration_list_opt field_declarator_opt field_declaring_list
    304307%type<en> field field_list field_name fraction_constants_opt
    305308
     
    361364
    362365// initializers
    363 %type<in>  initializer initializer_list initializer_opt
     366%type<in>  initializer initializer_list_opt initializer_opt
    364367
    365368// designators
     
    412415// actions during the parser update this data structure when the class of identifiers change.
    413416//
    414 // Because the Cforall language is block-scoped, there is the possibility that an identifier can change its class in a
    415 // local scope; it must revert to its original class at the end of the block.  Since type names can be local to a
    416 // particular declaration, each declaration is itself a scope.  This requires distinguishing between type names that are
    417 // local to the current declaration scope and those that persist past the end of the declaration (i.e., names defined in
    418 // "typedef" or "otype" declarations).
    419 //
    420 // The non-terminals "push" and "pop" derive the empty string; their only use is to denote the opening and closing of
    421 // scopes.  Every push must have a matching pop, although it is regrettable the matching pairs do not always occur
    422 // within the same rule.  These non-terminals may appear in more contexts than strictly necessary from a semantic point
    423 // of view.  Unfortunately, these extra rules are necessary to prevent parsing conflicts -- the parser may not have
    424 // enough context and look-ahead information to decide whether a new scope is necessary, so the effect of these extra
    425 // rules is to open a new scope unconditionally.  As the grammar evolves, it may be neccesary to add or move around
    426 // "push" and "pop" nonterminals to resolve conflicts of this sort.
     417// Because the Cforall language is block-scoped, an identifier can change its class in a local scope; it must revert to
     418// its original class at the end of the block.  Since type names can be local to a particular declaration, each
     419// declaration is itself a scope.  This requires distinguishing between type names that are local to the current
     420// declaration scope and those that persist past the end of the declaration (i.e., names defined in "typedef" or "otype"
     421// declarations).
     422//
     423// The non-terminals "push" and "pop" denote the opening and closing of scopes.  Every push must have a matching pop,
     424// although it is regrettable the matching pairs do not always occur within the same rule.  These non-terminals may
     425// appear in more contexts than strictly necessary from a semantic point of view.
    427426
    428427push:
     
    498497                { $$ = new ExpressionNode( build_func( new ExpressionNode( build_postfix_name( $5 ) ), $2 ) ); }
    499498        | type_name '.' no_attr_identifier                                      // CFA, nested type
    500                 { SemanticError( yylloc, "Qualified names are currently unimplemented." ); $$ = nullptr; }
    501 //              { $$ = nullptr; }
    502         | type_name '.' '[' push field_list pop ']'                     // CFA, nested type / tuple field selector
    503                 { SemanticError( yylloc, "Qualified names are currently unimplemented." ); $$ = nullptr; }
    504 //              { $$ = nullptr; }
     499                { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
     500        | type_name '.' '[' field_list ']'                                      // CFA, nested type / tuple field selector
     501                { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
    505502        | GENERIC '(' assignment_expression ',' generic_assoc_list ')' // C11
    506503                { SemanticError( yylloc, "_Generic is currently unimplemented." ); $$ = nullptr; }
     
    519516postfix_expression:
    520517        primary_expression
    521         | postfix_expression '[' push assignment_expression pop ']'
     518        | postfix_expression '[' assignment_expression ']'
    522519                // CFA, comma_expression disallowed in this context because it results in a common user error: subscripting a
    523520                // matrix with x[i,j] instead of x[i][j]. While this change is not backwards compatible, there seems to be
    524521                // little advantage to this feature and many disadvantages. It is possible to write x[(i,j)] in CFA, which is
    525522                // equivalent to the old x[i,j].
    526                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, $4 ) ); }
     523                { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, $3 ) ); }
    527524        | postfix_expression '{' argument_expression_list '}' // CFA, constructor call
    528525                {
     
    539536        | postfix_expression FLOATING_FRACTIONconstant          // CFA, tuple index
    540537                { $$ = new ExpressionNode( build_fieldSel( $1, build_field_name_FLOATING_FRACTIONconstant( *$2 ) ) ); }
    541         | postfix_expression '.' '[' push field_list pop ']' // CFA, tuple field selector
    542                 { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $5 ) ) ); }
     538        | postfix_expression '.' '[' field_list ']'                     // CFA, tuple field selector
     539                { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); }
    543540        | postfix_expression ARROW no_attr_identifier
    544541                {
     
    547544        | postfix_expression ARROW INTEGERconstant                      // CFA, tuple index
    548545                { $$ = new ExpressionNode( build_pfieldSel( $1, build_constantInteger( *$3 ) ) ); }
    549         | postfix_expression ARROW '[' push field_list pop ']' // CFA, tuple field selector
    550                 { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $5 ) ) ); }
     546        | postfix_expression ARROW '[' field_list ']'           // CFA, tuple field selector
     547                { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $4 ) ) ); }
    551548        | postfix_expression ICR
    552549                { $$ = new ExpressionNode( build_unary_ptr( OperKinds::IncrPost, $1 ) ); }
    553550        | postfix_expression DECR
    554551                { $$ = new ExpressionNode( build_unary_ptr( OperKinds::DecrPost, $1 ) ); }
    555         | '(' type_no_function ')' '{' initializer_list comma_opt '}' // C99, compound-literal
     552        | '(' type_no_function ')' '{' initializer_list_opt comma_opt '}' // C99, compound-literal
    556553                { $$ = new ExpressionNode( build_compoundLiteral( $2, new InitializerNode( $5, true ) ) ); }
    557         | '(' type_no_function ')' '@' '{' initializer_list comma_opt '}' // CFA, explicit C compound-literal
     554        | '(' type_no_function ')' '@' '{' initializer_list_opt comma_opt '}' // CFA, explicit C compound-literal
    558555                { $$ = new ExpressionNode( build_compoundLiteral( $2, (new InitializerNode( $6, true ))->set_maybeConstructed( false ) ) ); }
    559556        | '^' primary_expression '{' argument_expression_list '}' // CFA
     
    588585        | FLOATING_DECIMALconstant field
    589586                { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), maybeMoveBuild<Expression>( $2 ) ) ); }
    590         | FLOATING_DECIMALconstant '[' push field_list pop ']'
    591                 { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), build_tuple( $4 ) ) ); }
     587        | FLOATING_DECIMALconstant '[' field_list ']'
     588                { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), build_tuple( $3 ) ) ); }
    592589        | field_name '.' field
    593590                { $$ = new ExpressionNode( build_fieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); }
    594         | field_name '.' '[' push field_list pop ']'
    595                 { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $5 ) ) ); }
     591        | field_name '.' '[' field_list ']'
     592                { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); }
    596593        | field_name ARROW field
    597594                { $$ = new ExpressionNode( build_pfieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); }
    598         | field_name ARROW '[' push field_list pop ']'
    599                 { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $5 ) ) ); }
     595        | field_name ARROW '[' field_list ']'
     596                { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $4 ) ) ); }
    600597        ;
    601598
     
    807804        | unary_expression assignment_operator assignment_expression
    808805                { $$ = new ExpressionNode( build_binary_val( $2, $1, $3 ) ); }
    809         | unary_expression '=' '{' initializer_list comma_opt '}'
     806        | unary_expression '=' '{' initializer_list_opt comma_opt '}'
    810807                { SemanticError( yylloc, "Initializer assignment is currently unimplemented." ); $$ = nullptr; }
    811808        ;
     
    840837//      '[' push assignment_expression pop ']'
    841838//              { $$ = new ExpressionNode( build_tuple( $3 ) ); }
    842         '[' push ',' tuple_expression_list pop ']'
    843                 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $4 ) ) ); }
    844         | '[' push assignment_expression ',' tuple_expression_list pop ']'
    845                 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)$3->set_last( $5 ) ) ); }
     839        '[' ',' tuple_expression_list ']'
     840                { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $3 ) ) ); }
     841        | '[' assignment_expression ',' tuple_expression_list ']'
     842                { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)$2->set_last( $4 ) ) ); }
    846843        ;
    847844
     
    10741071        | RETURN comma_expression_opt ';'
    10751072                { $$ = new StatementNode( build_return( $2 ) ); }
    1076         | RETURN '{' initializer_list comma_opt '}'
     1073        | RETURN '{' initializer_list_opt comma_opt '}'
    10771074                { SemanticError( yylloc, "Initializer return is currently unimplemented." ); $$ = nullptr; }
    10781075        | THROW assignment_expression_opt ';'                           // handles rethrow
     
    11681165
    11691166handler_predicate_opt:
    1170         //empty
     1167        // empty
    11711168                { $$ = nullptr; }
    11721169        | ';' conditional_expression                            { $$ = $2; }
     
    11871184        | type_specifier_nobody declarator
    11881185                {
    1189                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    11901186                        $$ = $2->addType( $1 );
    11911187                }
     
    11941190        | cfa_abstract_declarator_tuple no_attr_identifier      // CFA
    11951191                {
    1196                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    11971192                        $$ = $1->addName( $2 );
    11981193                }
     
    13441339cfa_variable_declaration:                                                               // CFA
    13451340        cfa_variable_specifier initializer_opt
    1346                 {
    1347                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    1348                         $$ = $1->addInitializer( $2 );
    1349                 }
     1341                { $$ = $1->addInitializer( $2 ); }
    13501342        | declaration_qualifier_list cfa_variable_specifier initializer_opt
    13511343                // declaration_qualifier_list also includes type_qualifier_list, so a semantic check is necessary to preclude
    13521344                // them as a type_qualifier cannot appear in that context.
    1353                 {
    1354                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    1355                         $$ = $2->addQualifiers( $1 )->addInitializer( $3 );;
    1356                 }
     1345                { $$ = $2->addQualifiers( $1 )->addInitializer( $3 ); }
    13571346        | cfa_variable_declaration pop ',' push identifier_or_type_name initializer_opt
    1358                 {
    1359                         typedefTable.addToEnclosingScope( *$5, TypedefTable::ID );
    1360                         $$ = $1->appendList( $1->cloneType( $5 )->addInitializer( $6 ) );
    1361                 }
     1347                { $$ = $1->appendList( $1->cloneType( $5 )->addInitializer( $6 ) ); }
    13621348        ;
    13631349
     
    13661352                // storage-class
    13671353        cfa_abstract_declarator_no_tuple identifier_or_type_name asm_name_opt
    1368                 {
    1369                         typedefTable.setNextIdentifier( *$2 );
    1370                         $$ = $1->addName( $2 )->addAsmName( $3 );
    1371                 }
     1354                { $$ = $1->addName( $2 )->addAsmName( $3 ); }
    13721355        | cfa_abstract_tuple identifier_or_type_name asm_name_opt
    1373                 {
    1374                         typedefTable.setNextIdentifier( *$2 );
    1375                         $$ = $1->addName( $2 )->addAsmName( $3 );
    1376                 }
     1356                { $$ = $1->addName( $2 )->addAsmName( $3 ); }
    13771357        | type_qualifier_list cfa_abstract_tuple identifier_or_type_name asm_name_opt
    1378                 {
    1379                         typedefTable.setNextIdentifier( *$3 );
    1380                         $$ = $2->addQualifiers( $1 )->addName( $3 )->addAsmName( $4 );
    1381                 }
     1358                { $$ = $2->addQualifiers( $1 )->addName( $3 )->addAsmName( $4 ); }
    13821359        ;
    13831360
    13841361cfa_function_declaration:                                                               // CFA
    13851362        cfa_function_specifier
    1386                 {
    1387                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    1388                         $$ = $1;
    1389                 }
     1363                { $$ = $1; }
    13901364        | type_qualifier_list cfa_function_specifier
    1391                 {
    1392                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    1393                         $$ = $2->addQualifiers( $1 );
    1394                 }
     1365                { $$ = $2->addQualifiers( $1 ); }
    13951366        | declaration_qualifier_list cfa_function_specifier
    1396                 {
    1397                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    1398                         $$ = $2->addQualifiers( $1 );
    1399                 }
     1367                { $$ = $2->addQualifiers( $1 ); }
    14001368        | declaration_qualifier_list type_qualifier_list cfa_function_specifier
    1401                 {
    1402                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    1403                         $$ = $3->addQualifiers( $1 )->addQualifiers( $2 );
    1404                 }
    1405         | cfa_function_declaration pop ',' push identifier_or_type_name '(' push cfa_parameter_type_list_opt pop ')'
     1369                { $$ = $3->addQualifiers( $1 )->addQualifiers( $2 ); }
     1370        | cfa_function_declaration ',' identifier_or_type_name '(' cfa_parameter_type_list_opt ')'
    14061371                {
    14071372                        // Append the return type at the start (left-hand-side) to each identifier in the list.
    14081373                        DeclarationNode * ret = new DeclarationNode;
    14091374                        ret->type = maybeClone( $1->type->base );
    1410                         $$ = $1->appendList( DeclarationNode::newFunction( $5, ret, $8, nullptr ) );
     1375                        $$ = $1->appendList( DeclarationNode::newFunction( $3, ret, $5, nullptr ) );
    14111376                }
    14121377        ;
     
    14351400                // type_specifier can resolve to just TYPEDEFname (e.g., typedef int T; int f( T );). Therefore this must be
    14361401                // flattened to allow lookahead to the '(' without having to reduce identifier_or_type_name.
    1437         cfa_abstract_tuple identifier_or_type_name '(' push cfa_parameter_type_list_opt pop ')'
     1402        cfa_abstract_tuple identifier_or_type_name '(' cfa_parameter_type_list_opt ')'
    14381403                // To obtain LR(1 ), this rule must be factored out from function return type (see cfa_abstract_declarator).
    1439                 {
    1440                         $$ = DeclarationNode::newFunction( $2, $1, $5, 0 );
    1441                 }
    1442         | cfa_function_return identifier_or_type_name '(' push cfa_parameter_type_list_opt pop ')'
    1443                 {
    1444                         $$ = DeclarationNode::newFunction( $2, $1, $5, 0 );
    1445                 }
     1404                { $$ = DeclarationNode::newFunction( $2, $1, $4, 0 ); }
     1405        | cfa_function_return identifier_or_type_name '(' cfa_parameter_type_list_opt ')'
     1406                { $$ = DeclarationNode::newFunction( $2, $1, $4, 0 ); }
    14461407        ;
    14471408
    14481409cfa_function_return:                                                                    // CFA
    1449         '[' push cfa_parameter_list pop ']'
    1450                 { $$ = DeclarationNode::newTuple( $3 ); }
    1451         | '[' push cfa_parameter_list pop ',' push cfa_abstract_parameter_list pop ']'
     1410        '[' cfa_parameter_list ']'
     1411                { $$ = DeclarationNode::newTuple( $2 ); }
     1412        | '[' cfa_parameter_list ',' cfa_abstract_parameter_list ']'
    14521413                // To obtain LR(1 ), the last cfa_abstract_parameter_list is added into this flattened rule to lookahead to the
    14531414                // ']'.
    1454                 { $$ = DeclarationNode::newTuple( $3->appendList( $7 ) ); }
     1415                { $$ = DeclarationNode::newTuple( $2->appendList( $4 ) ); }
    14551416        ;
    14561417
     
    14581419        TYPEDEF cfa_variable_specifier
    14591420                {
    1460                         typedefTable.addToEnclosingScope( TypedefTable::TD );
     1421                        typedefTable.addToEnclosingScope( *$2->name, TypedefTable::TD );
    14611422                        $$ = $2->addTypedef();
    14621423                }
    14631424        | TYPEDEF cfa_function_specifier
    14641425                {
    1465                         typedefTable.addToEnclosingScope( TypedefTable::TD );
     1426                        typedefTable.addToEnclosingScope( *$2->name, TypedefTable::TD );
    14661427                        $$ = $2->addTypedef();
    14671428                }
     
    14791440        TYPEDEF type_specifier declarator
    14801441                {
    1481                         typedefTable.addToEnclosingScope( TypedefTable::TD );
     1442                        typedefTable.addToEnclosingScope( *$3->name, TypedefTable::TD );
    14821443                        $$ = $3->addType( $2 )->addTypedef();
    14831444                }
    14841445        | typedef_declaration pop ',' push declarator
    14851446                {
    1486                         typedefTable.addToEnclosingScope( TypedefTable::TD );
     1447                        typedefTable.addToEnclosingScope( *$5->name, TypedefTable::TD );
    14871448                        $$ = $1->appendList( $1->cloneBaseType( $5 )->addTypedef() );
    14881449                }
    14891450        | type_qualifier_list TYPEDEF type_specifier declarator // remaining OBSOLESCENT (see 2 )
    14901451                {
    1491                         typedefTable.addToEnclosingScope( TypedefTable::TD );
     1452                        typedefTable.addToEnclosingScope( *$4->name, TypedefTable::TD );
    14921453                        $$ = $4->addType( $3 )->addQualifiers( $1 )->addTypedef();
    14931454                }
    14941455        | type_specifier TYPEDEF declarator
    14951456                {
    1496                         typedefTable.addToEnclosingScope( TypedefTable::TD );
     1457                        typedefTable.addToEnclosingScope( *$3->name, TypedefTable::TD );
    14971458                        $$ = $3->addType( $1 )->addTypedef();
    14981459                }
    14991460        | type_specifier TYPEDEF type_qualifier_list declarator
    15001461                {
    1501                         typedefTable.addToEnclosingScope( TypedefTable::TD );
     1462                        typedefTable.addToEnclosingScope( *$4->name, TypedefTable::TD );
    15021463                        $$ = $4->addQualifiers( $1 )->addTypedef()->addType( $1 );
    15031464                }
     
    15081469        TYPEDEF no_attr_identifier '=' assignment_expression
    15091470                {
    1510                         typedefTable.addToEnclosingScope( *$2, TypedefTable::TD );
    1511                         $$ = DeclarationNode::newName( 0 );                     // unimplemented
     1471                        // $$ = DeclarationNode::newName( 0 );                  // unimplemented
     1472                        SemanticError( yylloc, "Typedef expression is currently unimplemented." ); $$ = nullptr;
    15121473                }
    15131474        | typedef_expression pop ',' push no_attr_identifier '=' assignment_expression
    15141475                {
    1515                         typedefTable.addToEnclosingScope( *$5, TypedefTable::TD );
    1516                         $$ = DeclarationNode::newName( 0 );                     // unimplemented
     1476                        // $$ = DeclarationNode::newName( 0 );                  // unimplemented
     1477                        SemanticError( yylloc, "Typedef expression is currently unimplemented." ); $$ = nullptr;
    15171478                }
    15181479        ;
     
    15421503c_declaration:
    15431504        declaration_specifier declaring_list
    1544                 {
    1545                         $$ = distAttr( $1, $2 );
    1546                 }
     1505                { $$ = distAttr( $1, $2 ); }
    15471506        | typedef_declaration
    15481507        | typedef_expression                                                            // GCC, naming expression type
     
    15541513                // storage-class
    15551514        declarator asm_name_opt initializer_opt
    1556                 {
    1557                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    1558                         $$ = $1->addAsmName( $2 )->addInitializer( $3 );
    1559                 }
     1515                { $$ = $1->addAsmName( $2 )->addInitializer( $3 ); }
    15601516        | declaring_list ',' attribute_list_opt declarator asm_name_opt initializer_opt
    1561                 {
    1562                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    1563                         $$ = $1->appendList( $4->addQualifiers( $3 )->addAsmName( $5 )->addInitializer( $6 ) );
    1564                 }
     1517                { $$ = $1->appendList( $4->addQualifiers( $3 )->addAsmName( $5 )->addInitializer( $6 ) ); }
    15651518        ;
    15661519
     
    18541807
    18551808aggregate_type:                                                                                 // struct, union
    1856         aggregate_key attribute_list_opt '{' field_declaration_list '}'
     1809        aggregate_key attribute_list_opt '{' field_declaration_list_opt '}'
    18571810                { $$ = DeclarationNode::newAggregate( $1, new string( DeclarationNode::anonymous.newName() ), nullptr, $4, true )->addQualifiers( $2 ); }
    18581811        | aggregate_key attribute_list_opt no_attr_identifier_or_type_name
     
    18621815                        forall = false;                                                         // reset
    18631816                }
    1864           '{' field_declaration_list '}'
     1817          '{' field_declaration_list_opt '}'
    18651818                { $$ = DeclarationNode::newAggregate( $1, $3, nullptr, $6, true )->addQualifiers( $2 ); }
    1866         | aggregate_key attribute_list_opt '(' type_list ')' '{' field_declaration_list '}' // CFA
     1819        | aggregate_key attribute_list_opt '(' type_list ')' '{' field_declaration_list_opt '}' // CFA
    18671820                { $$ = DeclarationNode::newAggregate( $1, new string( DeclarationNode::anonymous.newName() ), $4, $7, false )->addQualifiers( $2 ); }
    18681821        | aggregate_type_nobody
     
    19091862        ;
    19101863
    1911 field_declaration_list:
     1864field_declaration_list_opt:
    19121865        // empty
    19131866                { $$ = nullptr; }
    1914         | field_declaration_list field_declaration
     1867        | field_declaration_list_opt field_declaration
    19151868                { $$ = $1 ? $1->appendList( $2 ) : $2; }
    19161869        ;
     
    19451898
    19461899field_declaring_list:
    1947         field_declarator
    1948         | field_declaring_list ',' attribute_list_opt field_declarator
     1900        field_declarator_opt
     1901        | field_declaring_list ',' attribute_list_opt field_declarator_opt
    19491902                { $$ = $1->appendList( $4->addQualifiers( $3 ) ); }
    19501903        ;
    19511904
    1952 field_declarator:
     1905field_declarator_opt:
    19531906        // empty
    19541907                { $$ = DeclarationNode::newName( 0 ); /* XXX */ } // CFA, no field name
     
    20171970        | cfa_abstract_parameter_list
    20181971        | cfa_parameter_list
    2019         | cfa_parameter_list pop ',' push cfa_abstract_parameter_list
    2020                 { $$ = $1->appendList( $5 ); }
    2021         | cfa_abstract_parameter_list pop ',' push ELLIPSIS
     1972        | cfa_parameter_list ',' cfa_abstract_parameter_list
     1973                { $$ = $1->appendList( $3 ); }
     1974        | cfa_abstract_parameter_list ',' ELLIPSIS
    20221975                { $$ = $1->addVarArgs(); }
    2023         | cfa_parameter_list pop ',' push ELLIPSIS
     1976        | cfa_parameter_list ',' ELLIPSIS
    20241977                { $$ = $1->addVarArgs(); }
    20251978        ;
     
    20291982                // factored out from cfa_parameter_list, flattening the rules to get lookahead to the ']'.
    20301983        cfa_parameter_declaration
    2031         | cfa_abstract_parameter_list pop ',' push cfa_parameter_declaration
    2032                 { $$ = $1->appendList( $5 ); }
    2033         | cfa_parameter_list pop ',' push cfa_parameter_declaration
    2034                 { $$ = $1->appendList( $5 ); }
    2035         | cfa_parameter_list pop ',' push cfa_abstract_parameter_list pop ',' push cfa_parameter_declaration
    2036                 { $$ = $1->appendList( $5 )->appendList( $9 ); }
     1984        | cfa_abstract_parameter_list ',' cfa_parameter_declaration
     1985                { $$ = $1->appendList( $3 ); }
     1986        | cfa_parameter_list ',' cfa_parameter_declaration
     1987                { $$ = $1->appendList( $3 ); }
     1988        | cfa_parameter_list ',' cfa_abstract_parameter_list ',' cfa_parameter_declaration
     1989                { $$ = $1->appendList( $3 )->appendList( $5 ); }
    20371990        ;
    20381991
    20391992cfa_abstract_parameter_list:                                                    // CFA, new & old style abstract
    20401993        cfa_abstract_parameter_declaration
    2041         | cfa_abstract_parameter_list pop ',' push cfa_abstract_parameter_declaration
    2042                 { $$ = $1->appendList( $5 ); }
     1994        | cfa_abstract_parameter_list ',' cfa_abstract_parameter_declaration
     1995                { $$ = $1->appendList( $3 ); }
    20431996        ;
    20441997
     
    20902043                // No SUE declaration in parameter list.
    20912044        declaration_specifier_nobody identifier_parameter_declarator default_initialize_opt
    2092                 {
    2093                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    2094                         $$ = $2->addType( $1 )->addInitializer( $3 ? new InitializerNode( $3 ) : nullptr );
    2095                 }
     2045                { $$ = $2->addType( $1 )->addInitializer( $3 ? new InitializerNode( $3 ) : nullptr ); }
    20962046        | declaration_specifier_nobody type_parameter_redeclarator default_initialize_opt
    2097                 {
    2098                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    2099                         $$ = $2->addType( $1 )->addInitializer( $3 ? new InitializerNode( $3 ) : nullptr );
    2100                 }
     2047                { $$ = $2->addType( $1 )->addInitializer( $3 ? new InitializerNode( $3 ) : nullptr ); }
    21012048        ;
    21022049
     
    21562103initializer:
    21572104        assignment_expression                                           { $$ = new InitializerNode( $1 ); }
    2158         | '{' initializer_list comma_opt '}'            { $$ = new InitializerNode( $2, true ); }
    2159         ;
    2160 
    2161 initializer_list:
     2105        | '{' initializer_list_opt comma_opt '}'        { $$ = new InitializerNode( $2, true ); }
     2106        ;
     2107
     2108initializer_list_opt:
    21622109        // empty
    21632110                { $$ = nullptr; }
    21642111        | initializer
    21652112        | designation initializer                                       { $$ = $2->set_designators( $1 ); }
    2166         | initializer_list ',' initializer                      { $$ = (InitializerNode *)( $1->set_last( $3 ) ); }
    2167         | initializer_list ',' designation initializer
     2113        | initializer_list_opt ',' initializer          { $$ = (InitializerNode *)( $1->set_last( $3 ) ); }
     2114        | initializer_list_opt ',' designation initializer
    21682115                { $$ = (InitializerNode *)( $1->set_last( $4->set_designators( $3 ) ) ); }
    21692116        ;
     
    21952142        '.' no_attr_identifier                                                          // C99, field name
    21962143                { $$ = new ExpressionNode( build_varref( $2 ) ); }
    2197         | '[' push assignment_expression pop ']'                        // C99, single array element
     2144        | '[' assignment_expression ']'                                         // C99, single array element
    21982145                // assignment_expression used instead of constant_expression because of shift/reduce conflicts with tuple.
     2146                { $$ = $2; }
     2147        | '[' subrange ']'                                                                      // CFA, multiple array elements
     2148                { $$ = $2; }
     2149        | '[' constant_expression ELLIPSIS constant_expression ']' // GCC, multiple array elements
     2150                { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild< Expression >( $2 ), maybeMoveBuild< Expression >( $4 ) ) ); }
     2151        | '.' '[' field_list ']'                                                        // CFA, tuple field selector
    21992152                { $$ = $3; }
    2200         | '[' push subrange pop ']'                                                     // CFA, multiple array elements
    2201                 { $$ = $3; }
    2202         | '[' push constant_expression ELLIPSIS constant_expression pop ']' // GCC, multiple array elements
    2203                 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild< Expression >( $3 ), maybeMoveBuild< Expression >( $5 ) ) ); }
    2204         | '.' '[' push field_list pop ']'                                       // CFA, tuple field selector
    2205                 { $$ = $4; }
    22062153        ;
    22072154
     
    22732220assertion:                                                                                              // CFA
    22742221        '|' no_attr_identifier_or_type_name '(' type_list ')'
    2275                 {
    2276                         typedefTable.openTrait( *$2 );
    2277                         $$ = DeclarationNode::newTraitUse( $2, $4 );
    2278                 }
     2222                { $$ = DeclarationNode::newTraitUse( $2, $4 ); }
    22792223        | '|' '{' push trait_declaration_list '}'
    22802224                { $$ = $4; }
    22812225        | '|' '(' push type_parameter_list pop ')' '{' push trait_declaration_list '}' '(' type_list ')'
    2282                 { $$ = nullptr; }
     2226                { SemanticError( yylloc, "Generic data-type assertion is currently unimplemented." ); $$ = nullptr; }
    22832227        ;
    22842228
     
    23242268trait_specifier:                                                                                // CFA
    23252269        TRAIT no_attr_identifier_or_type_name '(' push type_parameter_list pop ')' '{' '}'
    2326                 {
    2327                         typedefTable.addToEnclosingScope( *$2, TypedefTable::ID );
    2328                         $$ = DeclarationNode::newTrait( $2, $5, 0 );
    2329                 }
     2270                { $$ = DeclarationNode::newTrait( $2, $5, 0 ); }
    23302271        | TRAIT no_attr_identifier_or_type_name '(' push type_parameter_list pop ')' '{'
    2331                 {
    2332                         typedefTable.enterTrait( *$2 );
    2333                         typedefTable.enterScope();
    2334                 }
     2272                { typedefTable.enterScope(); }
    23352273          trait_declaration_list '}'
    2336                 {
    2337                         typedefTable.leaveTrait();
    2338                         typedefTable.addToEnclosingScope( *$2, TypedefTable::ID );
    2339                         $$ = DeclarationNode::newTrait( $2, $5, $10 );
    2340                 }
     2274                { $$ = DeclarationNode::newTrait( $2, $5, $10 ); }
    23412275        ;
    23422276
     
    23542288cfa_trait_declaring_list:                                                               // CFA
    23552289        cfa_variable_specifier
    2356                 {
    2357                         typedefTable.addToEnclosingScope2( TypedefTable::ID );
    2358                         $$ = $1;
    2359                 }
     2290                { $$ = $1; }
    23602291        | cfa_function_specifier
    2361                 {
    2362                         typedefTable.addToEnclosingScope2( TypedefTable::ID );
    2363                         $$ = $1;
    2364                 }
     2292                { $$ = $1; }
    23652293        | cfa_trait_declaring_list pop ',' push identifier_or_type_name
    2366                 {
    2367                         typedefTable.addToEnclosingScope2( *$5, TypedefTable::ID );
    2368                         $$ = $1->appendList( $1->cloneType( $5 ) );
    2369                 }
     2294                { $$ = $1->appendList( $1->cloneType( $5 ) ); }
    23702295        ;
    23712296
    23722297trait_declaring_list:                                                                   // CFA
    23732298        type_specifier declarator
    2374                 {
    2375                         typedefTable.addToEnclosingScope2( TypedefTable::ID );
    2376                         $$ = $2->addType( $1 );
    2377                 }
     2299                { $$ = $2->addType( $1 ); }
    23782300        | trait_declaring_list pop ',' push declarator
    2379                 {
    2380                         typedefTable.addToEnclosingScope2( TypedefTable::ID );
    2381                         $$ = $1->appendList( $1->cloneBaseType( $5 ) );
    2382                 }
     2301                { $$ = $1->appendList( $1->cloneBaseType( $5 ) ); }
    23832302        ;
    23842303
     
    24882407        | function_declarator compound_statement
    24892408                {
    2490                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    24912409                        typedefTable.leaveScope();
    24922410                        $$ = $1->addFunctionBody( $2 );
     
    24942412        | KR_function_declarator KR_declaration_list_opt compound_statement
    24952413                {
    2496                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    24972414                        typedefTable.leaveScope();
    24982415                        $$ = $1->addOldDeclList( $2 )->addFunctionBody( $3 );
     
    25102427        cfa_function_declaration with_clause_opt compound_statement     // CFA
    25112428                {
    2512                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    25132429                        typedefTable.leaveScope();
    25142430                        // Add the function body to the last identifier in the function definition list, i.e., foo3:
     
    25202436                {
    25212437                        rebindForall( $1, $2 );
    2522                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    25232438                        typedefTable.leaveScope();
    25242439                        $$ = $2->addFunctionBody( $4, $3 )->addType( $1 );
    25252440                }
     2441        | declaration_specifier variable_type_redeclarator with_clause_opt compound_statement
     2442                {
     2443                        rebindForall( $1, $2 );
     2444                        typedefTable.leaveScope();
     2445                        $$ = $2->addFunctionBody( $4, $3 )->addType( $1 );
     2446                }
    25262447                // handles default int return type, OBSOLESCENT (see 1)
    25272448        | type_qualifier_list function_declarator with_clause_opt compound_statement
    25282449                {
    2529                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    25302450                        typedefTable.leaveScope();
    25312451                        $$ = $2->addFunctionBody( $4, $3 )->addQualifiers( $1 );
     
    25342454        | declaration_qualifier_list function_declarator with_clause_opt compound_statement
    25352455                {
    2536                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    25372456                        typedefTable.leaveScope();
    25382457                        $$ = $2->addFunctionBody( $4, $3 )->addQualifiers( $1 );
     
    25412460        | declaration_qualifier_list type_qualifier_list function_declarator with_clause_opt compound_statement
    25422461                {
    2543                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    25442462                        typedefTable.leaveScope();
    25452463                        $$ = $3->addFunctionBody( $5, $4 )->addQualifiers( $2 )->addQualifiers( $1 );
     
    25502468                {
    25512469                        rebindForall( $1, $2 );
    2552                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    25532470                        typedefTable.leaveScope();
    25542471                        $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addType( $1 );
     
    25572474        | type_qualifier_list KR_function_declarator KR_declaration_list_opt with_clause_opt compound_statement
    25582475                {
    2559                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    25602476                        typedefTable.leaveScope();
    25612477                        $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addQualifiers( $1 );
     
    25642480        | declaration_qualifier_list KR_function_declarator KR_declaration_list_opt with_clause_opt compound_statement
    25652481                {
    2566                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    25672482                        typedefTable.leaveScope();
    25682483                        $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addQualifiers( $1 );
     
    25712486        | declaration_qualifier_list type_qualifier_list KR_function_declarator KR_declaration_list_opt with_clause_opt compound_statement
    25722487                {
    2573                         typedefTable.addToEnclosingScope( TypedefTable::ID );
    25742488                        typedefTable.leaveScope();
    25752489                        $$ = $3->addOldDeclList( $4 )->addFunctionBody( $6, $5 )->addQualifiers( $2 )->addQualifiers( $1 );
     
    26842598paren_identifier:
    26852599        identifier
    2686                 {
    2687                         typedefTable.setNextIdentifier( *$1 );
    2688                         $$ = DeclarationNode::newName( $1 );
    2689                 }
     2600                { $$ = DeclarationNode::newName( $1 ); }
    26902601        | '(' paren_identifier ')'                                                      // redundant parenthesis
    26912602                { $$ = $2; }
     
    27742685        paren_identifier '(' identifier_list ')'                        // function_declarator handles empty parameter
    27752686                { $$ = $1->addIdList( $3 ); }
    2776         | '(' KR_function_ptr ')' '(' push parameter_type_list_opt pop ')'
    2777                 { $$ = $2->addParamList( $6 ); }
     2687        | '(' KR_function_ptr ')' '(' parameter_type_list_opt ')'
     2688                { $$ = $2->addParamList( $5 ); }
    27782689        | '(' KR_function_no_ptr ')'                                            // redundant parenthesis
    27792690                { $$ = $2; }
     
    28202731paren_type:
    28212732        typedef
     2733                { // hide type name by variable name
     2734                        typedefTable.addToEnclosingScope( *$1->name, TypedefTable::ID );
     2735                }
    28222736        | '(' paren_type ')'
    28232737                { $$ = $2; }
     
    28912805
    28922806identifier_parameter_function:
    2893         paren_identifier '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    2894                 { $$ = $1->addParamList( $4 ); }
    2895         | '(' identifier_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    2896                 { $$ = $2->addParamList( $6 ); }
     2807        paren_identifier '(' parameter_type_list_opt ')'        // empty parameter list OBSOLESCENT (see 3)
     2808                { $$ = $1->addParamList( $3 ); }
     2809        | '(' identifier_parameter_ptr ')' '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
     2810                { $$ = $2->addParamList( $5 ); }
    28972811        | '(' identifier_parameter_function ')'                         // redundant parenthesis
    28982812                { $$ = $2; }
     
    29222836typedef:
    29232837        TYPEDEFname
    2924                 {
    2925                         typedefTable.setNextIdentifier( *$1 );
    2926                         $$ = DeclarationNode::newName( $1 );
    2927                 }
     2838                { $$ = DeclarationNode::newName( $1 ); }
    29282839        | TYPEGENname
    2929                 {
    2930                         typedefTable.setNextIdentifier( *$1 );
    2931                         $$ = DeclarationNode::newName( $1 );
    2932                 }
     2840                { $$ = DeclarationNode::newName( $1 ); }
    29332841        ;
    29342842
     
    29502858
    29512859type_parameter_function:
    2952         typedef '(' push parameter_type_list_opt pop ')'        // empty parameter list OBSOLESCENT (see 3)
    2953                 { $$ = $1->addParamList( $4 ); }
    2954         | '(' type_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    2955                 { $$ = $2->addParamList( $6 ); }
     2860        typedef '(' parameter_type_list_opt ')'                         // empty parameter list OBSOLESCENT (see 3)
     2861                { $$ = $1->addParamList( $3 ); }
     2862        | '(' type_parameter_ptr ')' '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
     2863                { $$ = $2->addParamList( $5 ); }
    29562864        ;
    29572865
     
    30002908
    30012909abstract_function:
    3002         '(' push parameter_type_list_opt pop ')'                        // empty parameter list OBSOLESCENT (see 3)
    3003                 { $$ = DeclarationNode::newFunction( nullptr, nullptr, $3, nullptr ); }
    3004         | '(' abstract_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    3005                 { $$ = $2->addParamList( $6 ); }
     2910        '(' parameter_type_list_opt ')'                                         // empty parameter list OBSOLESCENT (see 3)
     2911                { $$ = DeclarationNode::newFunction( nullptr, nullptr, $2, nullptr ); }
     2912        | '(' abstract_ptr ')' '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
     2913                { $$ = $2->addParamList( $5 ); }
    30062914        | '(' abstract_function ')'                                                     // redundant parenthesis
    30072915                { $$ = $2; }
     
    30182926
    30192927multi_array_dimension:
    3020         '[' push assignment_expression pop ']'
    3021                 { $$ = DeclarationNode::newArray( $3, 0, false ); }
    3022         | '[' push '*' pop ']'                                                          // C99
     2928        '[' assignment_expression ']'
     2929                { $$ = DeclarationNode::newArray( $2, 0, false ); }
     2930        | '[' '*' ']'                                                                           // C99
    30232931                { $$ = DeclarationNode::newVarArray( 0 ); }
    3024         | multi_array_dimension '[' push assignment_expression pop ']'
    3025                 { $$ = $1->addArray( DeclarationNode::newArray( $4, 0, false ) ); }
    3026         | multi_array_dimension '[' push '*' pop ']'            // C99
     2932        | multi_array_dimension '[' assignment_expression ']'
     2933                { $$ = $1->addArray( DeclarationNode::newArray( $3, 0, false ) ); }
     2934        | multi_array_dimension '[' '*' ']'                                     // C99
    30272935                { $$ = $1->addArray( DeclarationNode::newVarArray( 0 ) ); }
    30282936        ;
     
    30912999
    30923000abstract_parameter_function:
    3093         '(' push parameter_type_list_opt pop ')'                        // empty parameter list OBSOLESCENT (see 3)
    3094                 { $$ = DeclarationNode::newFunction( nullptr, nullptr, $3, nullptr ); }
    3095         | '(' abstract_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    3096                 { $$ = $2->addParamList( $6 ); }
     3001        '(' parameter_type_list_opt ')'                                         // empty parameter list OBSOLESCENT (see 3)
     3002                { $$ = DeclarationNode::newFunction( nullptr, nullptr, $2, nullptr ); }
     3003        | '(' abstract_parameter_ptr ')' '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
     3004                { $$ = $2->addParamList( $5 ); }
    30973005        | '(' abstract_parameter_function ')'                           // redundant parenthesis
    30983006                { $$ = $2; }
     
    31163024                { $$ = DeclarationNode::newArray( 0, 0, false ); }
    31173025        // multi_array_dimension handles the '[' '*' ']' case
    3118         | '[' push type_qualifier_list '*' pop ']'                      // remaining C99
    3119                 { $$ = DeclarationNode::newVarArray( $3 ); }
    3120         | '[' push type_qualifier_list pop ']'
    3121                 { $$ = DeclarationNode::newArray( 0, $3, false ); }
     3026        | '[' type_qualifier_list '*' ']'                                       // remaining C99
     3027                { $$ = DeclarationNode::newVarArray( $2 ); }
     3028        | '[' type_qualifier_list ']'
     3029                { $$ = DeclarationNode::newArray( 0, $2, false ); }
    31223030        // multi_array_dimension handles the '[' assignment_expression ']' case
    3123         | '[' push type_qualifier_list assignment_expression pop ']'
    3124                 { $$ = DeclarationNode::newArray( $4, $3, false ); }
    3125         | '[' push STATIC type_qualifier_list_opt assignment_expression pop ']'
    3126                 { $$ = DeclarationNode::newArray( $5, $4, true ); }
    3127         | '[' push type_qualifier_list STATIC assignment_expression pop ']'
    3128                 { $$ = DeclarationNode::newArray( $5, $3, true ); }
     3031        | '[' type_qualifier_list assignment_expression ']'
     3032                { $$ = DeclarationNode::newArray( $3, $2, false ); }
     3033        | '[' STATIC type_qualifier_list_opt assignment_expression ']'
     3034                { $$ = DeclarationNode::newArray( $4, $3, true ); }
     3035        | '[' type_qualifier_list STATIC assignment_expression ']'
     3036                { $$ = DeclarationNode::newArray( $4, $2, true ); }
    31293037        ;
    31303038
     
    31703078
    31713079variable_abstract_function:
    3172         '(' variable_abstract_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    3173                 { $$ = $2->addParamList( $6 ); }
     3080        '(' variable_abstract_ptr ')' '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
     3081                { $$ = $2->addParamList( $5 ); }
    31743082        | '(' variable_abstract_function ')'                            // redundant parenthesis
    31753083                { $$ = $2; }
     
    32343142
    32353143cfa_array_parameter_1st_dimension:
    3236         '[' push type_qualifier_list '*' pop ']'                        // remaining C99
    3237                 { $$ = DeclarationNode::newVarArray( $3 ); }
    3238         | '[' push type_qualifier_list assignment_expression pop ']'
    3239                 { $$ = DeclarationNode::newArray( $4, $3, false ); }
    3240         | '[' push declaration_qualifier_list assignment_expression pop ']'
     3144        '[' type_qualifier_list '*' ']'                                         // remaining C99
     3145                { $$ = DeclarationNode::newVarArray( $2 ); }
     3146        | '[' type_qualifier_list assignment_expression ']'
     3147                { $$ = DeclarationNode::newArray( $3, $2, false ); }
     3148        | '[' declaration_qualifier_list assignment_expression ']'
    32413149                // declaration_qualifier_list must be used because of shift/reduce conflict with
    32423150                // assignment_expression, so a semantic check is necessary to preclude them as a type_qualifier cannot
    32433151                // appear in this context.
    3244                 { $$ = DeclarationNode::newArray( $4, $3, true ); }
    3245         | '[' push declaration_qualifier_list type_qualifier_list assignment_expression pop ']'
    3246                 { $$ = DeclarationNode::newArray( $5, $4->addQualifiers( $3 ), true ); }
     3152                { $$ = DeclarationNode::newArray( $3, $2, true ); }
     3153        | '[' declaration_qualifier_list type_qualifier_list assignment_expression ']'
     3154                { $$ = DeclarationNode::newArray( $4, $3->addQualifiers( $3 ), true ); }
    32473155        ;
    32483156
     
    33133221
    33143222cfa_abstract_tuple:                                                                             // CFA
    3315         '[' push cfa_abstract_parameter_list pop ']'
    3316                 { $$ = DeclarationNode::newTuple( $3 ); }
     3223        '[' cfa_abstract_parameter_list ']'
     3224                { $$ = DeclarationNode::newTuple( $2 ); }
    33173225        ;
    33183226
     
    33203228//      '[' ']' '(' cfa_parameter_type_list_opt ')'
    33213229//              { $$ = DeclarationNode::newFunction( nullptr, DeclarationNode::newTuple( nullptr ), $4, nullptr ); }
    3322         cfa_abstract_tuple '(' push cfa_parameter_type_list_opt pop ')'
    3323                 { $$ = DeclarationNode::newFunction( nullptr, $1, $4, nullptr ); }
    3324         | cfa_function_return '(' push cfa_parameter_type_list_opt pop ')'
    3325                 { $$ = DeclarationNode::newFunction( nullptr, $1, $4, nullptr ); }
     3230        cfa_abstract_tuple '(' cfa_parameter_type_list_opt ')'
     3231                { $$ = DeclarationNode::newFunction( nullptr, $1, $3, nullptr ); }
     3232        | cfa_function_return '(' cfa_parameter_type_list_opt ')'
     3233                { $$ = DeclarationNode::newFunction( nullptr, $1, $3, nullptr ); }
    33263234        ;
    33273235
Note: See TracChangeset for help on using the changeset viewer.