Index: src/Parser/DeclarationNode.cc
===================================================================
--- src/Parser/DeclarationNode.cc	(revision 4358c1e0834c47bfa838495f2b075911cb513d38)
+++ src/Parser/DeclarationNode.cc	(revision 7fdb94e149275ab27bb762fdf43b65253f25b3a8)
@@ -10,6 +10,6 @@
 // Created On       : Sat May 16 12:34:05 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed May 16 09:37:17 2018
-// Update Count     : 1070
+// Last Modified On : Mon May 21 20:36:45 2018
+// Update Count     : 1073
 //
 
@@ -179,9 +179,4 @@
 	newnode->type->function.body = body;
 
-	// ignore unnamed routine declarations: void p( int (*)(int) );
-	if ( newnode->name ) {
-		typedefTable.addToEnclosingScope( *newnode->name, TypedefTable::ID );
-	} // if
-
 	if ( ret ) {
 		newnode->type->base = ret->type;
@@ -285,5 +280,4 @@
 	newnode->name = name;
 	newnode->enumeratorValue.reset( constant );
-	typedefTable.addToEnclosingScope( *newnode->name, TypedefTable::ID );
 	return newnode;
 } // DeclarationNode::newEnumConstant
Index: src/Parser/TypedefTable.cc
===================================================================
--- src/Parser/TypedefTable.cc	(revision 4358c1e0834c47bfa838495f2b075911cb513d38)
+++ src/Parser/TypedefTable.cc	(revision 7fdb94e149275ab27bb762fdf43b65253f25b3a8)
@@ -7,27 +7,17 @@
 // TypedefTable.cc -- 
 //
-// Author           : Rodolfo G. Esteves
+// Author           : Peter A. Buhr
 // Created On       : Sat May 16 15:20:13 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Mon Aug 15 18:24:42 2016
-// Update Count     : 25
+// Last Modified On : Mon May 21 20:55:24 2018
+// Update Count     : 117
 //
 
-#include <ext/alloc_traits.h>    // for __alloc_traits<>::value_type
+
+#include "TypedefTable.h"
 #include <cassert>               // for assert
-#include <list>                  // for list, _List_iterator, list<>::iterator
-#include <map>                   // for _Rb_tree_iterator, _Rb_tree_const_it...
-#include <memory>                // for allocator_traits<>::value_type
-#include <utility>               // for pair
-
-#include "Parser/ParserTypes.h"  // for typedefTable
-#include "Parser/parser.hh"      // for IDENTIFIER
-#include "TypedefTable.h"
-
-using namespace std;
 
 #if 0
 #include <iostream>
-
 #define debugPrint( x ) cerr << x
 #else
@@ -35,141 +25,67 @@
 #endif
 
-TypedefTable::TypedefTable() : currentScope( 0 ) {}
+using namespace std;
 
-bool TypedefTable::exists( const string &identifier ) {
-	return table.count( identifier ) > 0;
-}
+TypedefTable::~TypedefTable() {
+	if ( ! SemanticErrorThrow && kindTable.currentScope() != 0 ) {
+		// std::cerr << "scope failure " << kindTable.currentScope() << endl;
+	} // if
+} // TypedefTable::~TypedefTable
 
-int TypedefTable::isKind( const string &identifier ) const {
-	tableType::const_iterator id_pos = table.find( identifier );
+bool TypedefTable::exists( const string & identifier ) {
+	return kindTable.find( identifier ) != kindTable.end();
+} // TypedefTable::exists
+
+int TypedefTable::isKind( const string & identifier ) const {
 	// Name lookup defaults to identifier, and then the identifier's kind is set by the parser.
-	if ( id_pos == table.end() ) return IDENTIFIER;
-	return id_pos->second.begin()->kind;
-}
+	KindTable::const_iterator posn = kindTable.find( identifier );
+	if ( posn == kindTable.end() ) return IDENTIFIER;
+	return posn->second;
+} // TypedefTable::isKind
 
-void TypedefTable::changeKind( const string &identifier, kind_t kind ) {
-	tableType::iterator id_pos = table.find( identifier );
-	if ( id_pos == table.end() ) return;
-	id_pos->second.begin()->kind = kind;
-}
+void TypedefTable::changeKind( const string & identifier, kind_t kind ) {
+	KindTable::iterator posn = kindTable.find( identifier );
+	if ( posn != kindTable.end() ) posn->second = kind;
+} // TypedefTable::changeKind
 
 // SKULLDUGGERY: Generate a typedef for the aggregate name so the aggregate does not have to be qualified by
-// "struct". Only generate the typedef, if the name is not in use. The typedef is implicitly (silently) removed
-// if the name is explicitly used.
-void TypedefTable::makeTypedef( const string &name ) {
+// "struct". Only generate the typedef, if the name is not in use. The typedef is implicitly (silently) removed if the
+// name is explicitly used.
+void TypedefTable::makeTypedef( const string & name ) {
 	if ( ! typedefTable.exists( name ) ) {
 		typedefTable.addToEnclosingScope( name, TypedefTable::TD );
 	} // if
-}
+} // TypedefTable::makeTypedef
 
-void TypedefTable::addToScope( const std::string &identifier, kind_t kind, int scope ) {
-	if ( currentTrait != "" && scope == contextScope ) {
-		DeferredEntry entry = { identifier, kind };
-		contexts[currentTrait].push_back( entry );
-	} else {
-		debugPrint( "Adding " << identifier << " as kind " << kind << " scope " << scope << " from scope " << currentScope << endl );
-		Entry newEntry = { scope, kind };
-		tableType::iterator curPos = table.find( identifier );
-		if ( curPos == table.end()) {
-			list< Entry > newList;
-			newList.push_front( newEntry );
-			table[identifier] = newList;
-		} else {
-			list< Entry >::iterator listPos = (*curPos ).second.begin();
-			while ( listPos != (*curPos ).second.end() && listPos->scope > scope ) {
-				listPos++;
-			} // while
-			(*curPos ).second.insert( listPos, newEntry );
-		} // if
+void TypedefTable::addToEnclosingScope( const std::string & identifier, kind_t kind ) {
+	assert( kindTable.currentScope() >= 1 );
+	auto scope = kindTable.currentScope() - 1;
+	debugPrint( "Adding " << identifier << " as kind " << kind << " scope " << scope << endl );
+	auto ret = kindTable.insertAt( scope, identifier, kind );
+	if ( ! ret.second ) { // already an element there
+		ret.first->second = kind; // update existing element with new kind
 	} // if
-}
-
-void TypedefTable::addToCurrentScope( const std::string &identifier, kind_t kind ) {
-	addToScope( identifier, kind, currentScope );
-}
-
-void TypedefTable::addToCurrentScope( kind_t kind ) {
-	addToCurrentScope( nextIdentifiers.top(), kind );
-}
-
-void TypedefTable::addToEnclosingScope( const std::string &identifier, kind_t kind ) {
-	assert( currentScope >= 1 );
-	addToScope( identifier, kind, currentScope - 1 );
-}
-
-void TypedefTable::addToEnclosingScope( kind_t kind ) {
-	addToEnclosingScope( nextIdentifiers.top(), kind );
-}
-
-void TypedefTable::addToEnclosingScope2( const std::string &identifier, kind_t kind ) {
-	assert( currentScope >= 2 );
-	addToScope( identifier, kind, currentScope - 2 );
-}
-
-void TypedefTable::addToEnclosingScope2( kind_t kind ) {
-	addToEnclosingScope2( nextIdentifiers.top(), kind );
-}
-
-void TypedefTable::setNextIdentifier( const std::string &identifier ) {
-	nextIdentifiers.top() = identifier;
-}
-
-void TypedefTable::openTrait( const std::string &contextName ) {
-	map< string, deferListType >::iterator i = contexts.find( contextName );
-	if ( i != contexts.end() ) {
-		deferListType &entries = i->second;
-		for ( deferListType::iterator i = entries.begin(); i != entries.end(); i++) {
-			addToEnclosingScope( i->identifier, i->kind );
-		} // for
-	} // if
-}
+} // TypedefTable::addToEnclosingScope
 
 void TypedefTable::enterScope() {
-	currentScope += 1;
-	deferListStack.push( deferListType() );
-	nextIdentifiers.push( "" );
-	debugPrint( "Entering scope " << currentScope << ", nextIdentifiers size is " << nextIdentifiers.size() << endl );
-}
+	kindTable.beginScope();
+	debugPrint( "Entering scope " << kindTable.currentScope() << endl );
+} // TypedefTable::enterScope
 
 void TypedefTable::leaveScope() {
-	debugPrint( "Leaving scope " << currentScope << endl );
-	for ( tableType::iterator i = table.begin(); i != table.end(); ) {
-		list< Entry > &declList = (*i).second;
-		while ( ! declList.empty() && declList.front().scope == currentScope ) {
-			declList.pop_front();
-		}
-		if ( declList.empty() ) {						// standard idom for erasing during traversal
-			table.erase( i++ );
-		} else
-			++i;
-	} // for
-	currentScope -= 1;
-	for ( deferListType::iterator i = deferListStack.top().begin(); i != deferListStack.top().end(); i++ ) {
-		addToCurrentScope( i->identifier, i->kind );
-	} // for
-	deferListStack.pop();
-	debugPrint( "nextIdentifiers size is " << nextIdentifiers.size() << " top is " << nextIdentifiers.top() << endl );
-	nextIdentifiers.pop();
-}
+	debugPrint( "Leaving scope " << kindTable.currentScope() << endl );
+	kindTable.endScope();
+} // TypedefTable::leaveScope
 
-void TypedefTable::enterTrait( const std::string &contextName ) {
-	currentTrait = contextName;
-	contextScope = currentScope;
-}
-
-void TypedefTable::leaveTrait() {
-	currentTrait = "";
-}
-
-void TypedefTable::print( void ) const {
-	for ( tableType::const_iterator i = table.begin(); i != table.end(); i++) {
-		debugPrint( (*i ).first << ": " );
-		list< Entry > declList = (*i).second;
-		for ( list< Entry >::const_iterator j = declList.begin(); j != declList.end(); j++ ) {
-			debugPrint( "(" << (*j).scope << " " << (*j).kind << ") " );
-		}
-		debugPrint( endl );
-	} // for
-}
+// void TypedefTable::print( void ) const {
+// 	for ( KindTable::const_iterator i = table.begin(); i != table.end(); i++) {
+// 		debugPrint( (*i ).first << ": " );
+// 		list< Entry > declList = (*i).second;
+// 		for ( list< Entry >::const_iterator j = declList.begin(); j != declList.end(); j++ ) {
+// 			debugPrint( "(" << (*j).scope << " " << (*j).kind << ") " );
+// 		}
+// 		debugPrint( endl );
+// 	} // for
+// }
 
 // Local Variables: //
Index: src/Parser/TypedefTable.h
===================================================================
--- src/Parser/TypedefTable.h	(revision 4358c1e0834c47bfa838495f2b075911cb513d38)
+++ src/Parser/TypedefTable.h	(revision 7fdb94e149275ab27bb762fdf43b65253f25b3a8)
@@ -7,20 +7,18 @@
 // TypedefTable.h --
 //
-// Author           : Rodolfo G. Esteves
+// Author           : Peter A. Buhr
 // Created On       : Sat May 16 15:24:36 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Jul 22 09:33:14 2017
-// Update Count     : 34
+// Last Modified On : Mon May 21 20:28:01 2018
+// Update Count     : 76
 //
 
 #pragma once
 
-#include <list>       // for list
-#include <map>        // for map, map<>::value_compare
-#include <stack>      // for stack
-#include <string>     // for string
+#include <string>										// for string
 
+#include "Common/ScopedMap.h"							// for ScopedMap
 #include "ParserTypes.h"
-#include "parser.hh"  // for IDENTIFIER, TYPEDEFname, TYPEGENname
+#include "parser.hh"									// for IDENTIFIER, TYPEDEFname, TYPEGENname
 
 class TypedefTable {
@@ -28,65 +26,18 @@
 	enum kind_t { ID = IDENTIFIER, TD = TYPEDEFname, TG = TYPEGENname };
   private:
-	struct Entry {
-		int scope;
-		kind_t kind;
-	};
+	typedef ScopedMap< std::string, kind_t > KindTable;
+	KindTable kindTable;	
+  public:
+	~TypedefTable();
 
-	struct DeferredEntry {
-		std::string identifier;
-		kind_t kind;
-	};
-
-	typedef std::map< std::string, std::list< Entry > > tableType;
-	tableType table;
-
-	int currentScope;
-	std::string currentTrait;
-	int contextScope;
-
-	typedef std::list< DeferredEntry > deferListType;
-	std::stack< deferListType > deferListStack;
-	std::map< std::string, deferListType > contexts;
-
-	std::stack< std::string > nextIdentifiers;
-
-	void addToScope( const std::string &identifier, kind_t kind, int scope );
-  public:
-	TypedefTable();
-
-	bool exists( const std::string &identifier );
-	int isKind( const std::string &identifier ) const;
-	void changeKind( const std::string &identifier, kind_t kind );
-
-	void makeTypedef( const std::string &name );
-
-	// "addToCurrentScope" adds the identifier/type pair to the current scope. This does less than you think it does,
-	// since each declaration is within its own scope.  Mostly useful for type parameters.
-	void addToCurrentScope( const std::string &identifier, kind_t kind );
-	void addToCurrentScope( kind_t kind );			// use nextIdentifiers.top()
-
-	// "addToEnclosingScope" adds the identifier/type pair to the scope that encloses the current one.  This is the
-	// right way to handle type and typedef names
-	void addToEnclosingScope( const std::string &identifier, kind_t kind );
-	void addToEnclosingScope( kind_t kind );		// use nextIdentifiers.top()
-
-	// "addToEnclosingScope2" adds the identifier/type pair to the scope that encloses the scope enclosing the the
-	// current one.  This is the right way to handle assertion names
-	void addToEnclosingScope2( const std::string &identifier, kind_t kind );
-	void addToEnclosingScope2( kind_t kind );		// use nextIdentifiers.top()
-
-	// set the next identifier to be used by an "add" operation without an identifier parameter within the current scope
-	void setNextIdentifier( const std::string &identifier );
-
-	// dump the definitions from a pre-defined context into the current scope
-	void openTrait( const std::string &contextName );
+	bool exists( const std::string & identifier );
+	int isKind( const std::string & identifier ) const;
+	void changeKind( const std::string & identifier, kind_t kind );
+	void makeTypedef( const std::string & name );
+	void addToEnclosingScope( const std::string & identifier, kind_t kind );
 
 	void enterScope();
 	void leaveScope();
-	void enterTrait( const std::string &contextName );
-	void leaveTrait();
-
-	void print() const;
-};
+}; // TypedefTable
 
 // Local Variables: //
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 4358c1e0834c47bfa838495f2b075911cb513d38)
+++ src/Parser/parser.yy	(revision 7fdb94e149275ab27bb762fdf43b65253f25b3a8)
@@ -10,6 +10,6 @@
 // Created On       : Sat Sep  1 20:22:55 2001
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Fri May 11 17:51:38 2018
-// Update Count     : 3261
+// Last Modified On : Mon May 21 21:44:01 2018
+// Update Count     : 3350
 //
 
@@ -119,7 +119,10 @@
 // Does the forall bind to the struct or the routine, and how would it be possible to explicitly specify the binding.
 //   forall( otype T ) struct S { int T; } forall( otype W ) bar( W ) {}
+// Currently, the forall is associated with the routine, and the generic type has to be separately defined:
+//   forall( otype T ) struct S { int T; };
+//   forall( otype W ) bar( W ) {}
 
 void rebindForall( DeclarationNode * declSpec, DeclarationNode * funcDecl ) {
-	if ( declSpec->type->kind == TypeData::Aggregate ) { // return is aggregate definition
+	if ( declSpec->type->kind == TypeData::Aggregate ) { // ignore aggregate definition
 		funcDecl->type->forall = declSpec->type->aggregate.params; // move forall from aggregate to function type
 		declSpec->type->aggregate.params = nullptr;
@@ -301,5 +304,5 @@
 %type<decl> exception_declaration external_definition external_definition_list external_definition_list_opt
 
-%type<decl> field_declaration field_declaration_list field_declarator field_declaring_list
+%type<decl> field_declaration field_declaration_list_opt field_declarator_opt field_declaring_list
 %type<en> field field_list field_name fraction_constants_opt
 
@@ -361,5 +364,5 @@
 
 // initializers
-%type<in>  initializer initializer_list initializer_opt
+%type<in>  initializer initializer_list_opt initializer_opt
 
 // designators
@@ -412,17 +415,13 @@
 // actions during the parser update this data structure when the class of identifiers change.
 //
-// Because the Cforall language is block-scoped, there is the possibility that an identifier can change its class in a
-// local scope; it must revert to its original class at the end of the block.  Since type names can be local to a
-// particular declaration, each declaration is itself a scope.  This requires distinguishing between type names that are
-// local to the current declaration scope and those that persist past the end of the declaration (i.e., names defined in
-// "typedef" or "otype" declarations).
-//
-// The non-terminals "push" and "pop" derive the empty string; their only use is to denote the opening and closing of
-// scopes.  Every push must have a matching pop, although it is regrettable the matching pairs do not always occur
-// within the same rule.  These non-terminals may appear in more contexts than strictly necessary from a semantic point
-// of view.  Unfortunately, these extra rules are necessary to prevent parsing conflicts -- the parser may not have
-// enough context and look-ahead information to decide whether a new scope is necessary, so the effect of these extra
-// rules is to open a new scope unconditionally.  As the grammar evolves, it may be neccesary to add or move around
-// "push" and "pop" nonterminals to resolve conflicts of this sort.
+// Because the Cforall language is block-scoped, an identifier can change its class in a local scope; it must revert to
+// its original class at the end of the block.  Since type names can be local to a particular declaration, each
+// declaration is itself a scope.  This requires distinguishing between type names that are local to the current
+// declaration scope and those that persist past the end of the declaration (i.e., names defined in "typedef" or "otype"
+// declarations).
+//
+// The non-terminals "push" and "pop" denote the opening and closing of scopes.  Every push must have a matching pop,
+// although it is regrettable the matching pairs do not always occur within the same rule.  These non-terminals may
+// appear in more contexts than strictly necessary from a semantic point of view.
 
 push:
@@ -498,9 +497,7 @@
 		{ $$ = new ExpressionNode( build_func( new ExpressionNode( build_postfix_name( $5 ) ), $2 ) ); }
 	| type_name '.' no_attr_identifier					// CFA, nested type
-		{ SemanticError( yylloc, "Qualified names are currently unimplemented." ); $$ = nullptr; }
-//		{ $$ = nullptr; }
-	| type_name '.' '[' push field_list pop ']'			// CFA, nested type / tuple field selector
-		{ SemanticError( yylloc, "Qualified names are currently unimplemented." ); $$ = nullptr; }
-//		{ $$ = nullptr; }
+		{ SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
+	| type_name '.' '[' field_list ']'					// CFA, nested type / tuple field selector
+		{ SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
 	| GENERIC '(' assignment_expression ',' generic_assoc_list ')' // C11
 		{ SemanticError( yylloc, "_Generic is currently unimplemented." ); $$ = nullptr; }
@@ -519,10 +516,10 @@
 postfix_expression:
 	primary_expression
-	| postfix_expression '[' push assignment_expression pop ']'
+	| postfix_expression '[' assignment_expression ']'
 		// CFA, comma_expression disallowed in this context because it results in a common user error: subscripting a
 		// matrix with x[i,j] instead of x[i][j]. While this change is not backwards compatible, there seems to be
 		// little advantage to this feature and many disadvantages. It is possible to write x[(i,j)] in CFA, which is
 		// equivalent to the old x[i,j].
-		{ $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, $4 ) ); }
+		{ $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, $3 ) ); }
 	| postfix_expression '{' argument_expression_list '}' // CFA, constructor call
 		{
@@ -539,6 +536,6 @@
 	| postfix_expression FLOATING_FRACTIONconstant		// CFA, tuple index
 		{ $$ = new ExpressionNode( build_fieldSel( $1, build_field_name_FLOATING_FRACTIONconstant( *$2 ) ) ); }
-	| postfix_expression '.' '[' push field_list pop ']' // CFA, tuple field selector
-		{ $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $5 ) ) ); }
+	| postfix_expression '.' '[' field_list ']'			// CFA, tuple field selector
+		{ $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); }
 	| postfix_expression ARROW no_attr_identifier
 		{
@@ -547,13 +544,13 @@
 	| postfix_expression ARROW INTEGERconstant			// CFA, tuple index
 		{ $$ = new ExpressionNode( build_pfieldSel( $1, build_constantInteger( *$3 ) ) ); }
-	| postfix_expression ARROW '[' push field_list pop ']' // CFA, tuple field selector
-		{ $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $5 ) ) ); }
+	| postfix_expression ARROW '[' field_list ']'		// CFA, tuple field selector
+		{ $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $4 ) ) ); }
 	| postfix_expression ICR
 	  	{ $$ = new ExpressionNode( build_unary_ptr( OperKinds::IncrPost, $1 ) ); }
 	| postfix_expression DECR
 	  	{ $$ = new ExpressionNode( build_unary_ptr( OperKinds::DecrPost, $1 ) ); }
-	| '(' type_no_function ')' '{' initializer_list comma_opt '}' // C99, compound-literal
+	| '(' type_no_function ')' '{' initializer_list_opt comma_opt '}' // C99, compound-literal
 		{ $$ = new ExpressionNode( build_compoundLiteral( $2, new InitializerNode( $5, true ) ) ); }
-	| '(' type_no_function ')' '@' '{' initializer_list comma_opt '}' // CFA, explicit C compound-literal
+	| '(' type_no_function ')' '@' '{' initializer_list_opt comma_opt '}' // CFA, explicit C compound-literal
 		{ $$ = new ExpressionNode( build_compoundLiteral( $2, (new InitializerNode( $6, true ))->set_maybeConstructed( false ) ) ); }
 	| '^' primary_expression '{' argument_expression_list '}' // CFA
@@ -588,14 +585,14 @@
 	| FLOATING_DECIMALconstant field
 		{ $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), maybeMoveBuild<Expression>( $2 ) ) ); }
-	| FLOATING_DECIMALconstant '[' push field_list pop ']'
-		{ $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), build_tuple( $4 ) ) ); }
+	| FLOATING_DECIMALconstant '[' field_list ']'
+		{ $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), build_tuple( $3 ) ) ); }
 	| field_name '.' field
 		{ $$ = new ExpressionNode( build_fieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); }
-	| field_name '.' '[' push field_list pop ']'
-		{ $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $5 ) ) ); }
+	| field_name '.' '[' field_list ']'
+		{ $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); }
 	| field_name ARROW field
 		{ $$ = new ExpressionNode( build_pfieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); }
-	| field_name ARROW '[' push field_list pop ']'
-		{ $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $5 ) ) ); }
+	| field_name ARROW '[' field_list ']'
+		{ $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $4 ) ) ); }
 	;
 
@@ -807,5 +804,5 @@
 	| unary_expression assignment_operator assignment_expression
 		{ $$ = new ExpressionNode( build_binary_val( $2, $1, $3 ) ); }
-	| unary_expression '=' '{' initializer_list comma_opt '}'
+	| unary_expression '=' '{' initializer_list_opt comma_opt '}'
 		{ SemanticError( yylloc, "Initializer assignment is currently unimplemented." ); $$ = nullptr; }
 	;
@@ -840,8 +837,8 @@
 //	'[' push assignment_expression pop ']'
 //		{ $$ = new ExpressionNode( build_tuple( $3 ) ); }
-	'[' push ',' tuple_expression_list pop ']'
-		{ $$ = new ExpressionNode( build_tuple( (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $4 ) ) ); }
-	| '[' push assignment_expression ',' tuple_expression_list pop ']'
-		{ $$ = new ExpressionNode( build_tuple( (ExpressionNode *)$3->set_last( $5 ) ) ); }
+	'[' ',' tuple_expression_list ']'
+		{ $$ = new ExpressionNode( build_tuple( (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $3 ) ) ); }
+	| '[' assignment_expression ',' tuple_expression_list ']'
+		{ $$ = new ExpressionNode( build_tuple( (ExpressionNode *)$2->set_last( $4 ) ) ); }
 	;
 
@@ -1074,5 +1071,5 @@
 	| RETURN comma_expression_opt ';'
 		{ $$ = new StatementNode( build_return( $2 ) ); }
-	| RETURN '{' initializer_list comma_opt '}'
+	| RETURN '{' initializer_list_opt comma_opt '}'
 		{ SemanticError( yylloc, "Initializer return is currently unimplemented." ); $$ = nullptr; }
 	| THROW assignment_expression_opt ';'				// handles rethrow
@@ -1168,5 +1165,5 @@
 
 handler_predicate_opt:
-	//empty
+	// empty
 		{ $$ = nullptr; }
 	| ';' conditional_expression				{ $$ = $2; }
@@ -1187,5 +1184,4 @@
 	| type_specifier_nobody declarator
 		{
-			typedefTable.addToEnclosingScope( TypedefTable::ID );
 			$$ = $2->addType( $1 );
 		}
@@ -1194,5 +1190,4 @@
 	| cfa_abstract_declarator_tuple no_attr_identifier	// CFA
 		{
-			typedefTable.addToEnclosingScope( TypedefTable::ID );
 			$$ = $1->addName( $2 );
 		}
@@ -1344,20 +1339,11 @@
 cfa_variable_declaration:								// CFA
 	cfa_variable_specifier initializer_opt
-		{
-			typedefTable.addToEnclosingScope( TypedefTable::ID );
-			$$ = $1->addInitializer( $2 );
-		}
+		{ $$ = $1->addInitializer( $2 ); }
 	| declaration_qualifier_list cfa_variable_specifier initializer_opt
 		// declaration_qualifier_list also includes type_qualifier_list, so a semantic check is necessary to preclude
 		// them as a type_qualifier cannot appear in that context.
-		{
-			typedefTable.addToEnclosingScope( TypedefTable::ID );
-			$$ = $2->addQualifiers( $1 )->addInitializer( $3 );;
-		}
+		{ $$ = $2->addQualifiers( $1 )->addInitializer( $3 ); }
 	| cfa_variable_declaration pop ',' push identifier_or_type_name initializer_opt
-		{
-			typedefTable.addToEnclosingScope( *$5, TypedefTable::ID );
-			$$ = $1->appendList( $1->cloneType( $5 )->addInitializer( $6 ) );
-		}
+		{ $$ = $1->appendList( $1->cloneType( $5 )->addInitializer( $6 ) ); }
 	;
 
@@ -1366,47 +1352,26 @@
 		// storage-class
 	cfa_abstract_declarator_no_tuple identifier_or_type_name asm_name_opt
-		{
-			typedefTable.setNextIdentifier( *$2 );
-			$$ = $1->addName( $2 )->addAsmName( $3 );
-		}
+		{ $$ = $1->addName( $2 )->addAsmName( $3 ); }
 	| cfa_abstract_tuple identifier_or_type_name asm_name_opt
-		{
-			typedefTable.setNextIdentifier( *$2 );
-			$$ = $1->addName( $2 )->addAsmName( $3 );
-		}
+		{ $$ = $1->addName( $2 )->addAsmName( $3 ); }
 	| type_qualifier_list cfa_abstract_tuple identifier_or_type_name asm_name_opt
-		{
-			typedefTable.setNextIdentifier( *$3 );
-			$$ = $2->addQualifiers( $1 )->addName( $3 )->addAsmName( $4 );
-		}
+		{ $$ = $2->addQualifiers( $1 )->addName( $3 )->addAsmName( $4 ); }
 	;
 
 cfa_function_declaration:								// CFA
 	cfa_function_specifier
-		{
-			typedefTable.addToEnclosingScope( TypedefTable::ID );
-			$$ = $1;
-		}
+		{ $$ = $1; }
 	| type_qualifier_list cfa_function_specifier
-		{
-			typedefTable.addToEnclosingScope( TypedefTable::ID );
-			$$ = $2->addQualifiers( $1 );
-		}
+		{ $$ = $2->addQualifiers( $1 ); }
 	| declaration_qualifier_list cfa_function_specifier
-		{
-			typedefTable.addToEnclosingScope( TypedefTable::ID );
-			$$ = $2->addQualifiers( $1 );
-		}
+		{ $$ = $2->addQualifiers( $1 ); }
 	| declaration_qualifier_list type_qualifier_list cfa_function_specifier
-		{
-			typedefTable.addToEnclosingScope( TypedefTable::ID );
-			$$ = $3->addQualifiers( $1 )->addQualifiers( $2 );
-		}
-	| cfa_function_declaration pop ',' push identifier_or_type_name '(' push cfa_parameter_type_list_opt pop ')'
+		{ $$ = $3->addQualifiers( $1 )->addQualifiers( $2 ); }
+	| cfa_function_declaration ',' identifier_or_type_name '(' cfa_parameter_type_list_opt ')'
 		{
 			// Append the return type at the start (left-hand-side) to each identifier in the list.
 			DeclarationNode * ret = new DeclarationNode;
 			ret->type = maybeClone( $1->type->base );
-			$$ = $1->appendList( DeclarationNode::newFunction( $5, ret, $8, nullptr ) );
+			$$ = $1->appendList( DeclarationNode::newFunction( $3, ret, $5, nullptr ) );
 		}
 	;
@@ -1435,22 +1400,18 @@
 		// type_specifier can resolve to just TYPEDEFname (e.g., typedef int T; int f( T );). Therefore this must be
 		// flattened to allow lookahead to the '(' without having to reduce identifier_or_type_name.
-	cfa_abstract_tuple identifier_or_type_name '(' push cfa_parameter_type_list_opt pop ')'
+	cfa_abstract_tuple identifier_or_type_name '(' cfa_parameter_type_list_opt ')'
 		// To obtain LR(1 ), this rule must be factored out from function return type (see cfa_abstract_declarator).
-		{
-			$$ = DeclarationNode::newFunction( $2, $1, $5, 0 );
-		}
-	| cfa_function_return identifier_or_type_name '(' push cfa_parameter_type_list_opt pop ')'
-		{
-			$$ = DeclarationNode::newFunction( $2, $1, $5, 0 );
-		}
+		{ $$ = DeclarationNode::newFunction( $2, $1, $4, 0 ); }
+	| cfa_function_return identifier_or_type_name '(' cfa_parameter_type_list_opt ')'
+		{ $$ = DeclarationNode::newFunction( $2, $1, $4, 0 ); }
 	;
 
 cfa_function_return:									// CFA
-	'[' push cfa_parameter_list pop ']'
-		{ $$ = DeclarationNode::newTuple( $3 ); }
-	| '[' push cfa_parameter_list pop ',' push cfa_abstract_parameter_list pop ']'
+	'[' cfa_parameter_list ']'
+		{ $$ = DeclarationNode::newTuple( $2 ); }
+	| '[' cfa_parameter_list ',' cfa_abstract_parameter_list ']'
 		// To obtain LR(1 ), the last cfa_abstract_parameter_list is added into this flattened rule to lookahead to the
 		// ']'.
-		{ $$ = DeclarationNode::newTuple( $3->appendList( $7 ) ); }
+		{ $$ = DeclarationNode::newTuple( $2->appendList( $4 ) ); }
 	;
 
@@ -1458,10 +1419,10 @@
 	TYPEDEF cfa_variable_specifier
 		{
-			typedefTable.addToEnclosingScope( TypedefTable::TD );
+			typedefTable.addToEnclosingScope( *$2->name, TypedefTable::TD );
 			$$ = $2->addTypedef();
 		}
 	| TYPEDEF cfa_function_specifier
 		{
-			typedefTable.addToEnclosingScope( TypedefTable::TD );
+			typedefTable.addToEnclosingScope( *$2->name, TypedefTable::TD );
 			$$ = $2->addTypedef();
 		}
@@ -1479,25 +1440,25 @@
 	TYPEDEF type_specifier declarator
 		{
-			typedefTable.addToEnclosingScope( TypedefTable::TD );
+			typedefTable.addToEnclosingScope( *$3->name, TypedefTable::TD );
 			$$ = $3->addType( $2 )->addTypedef();
 		}
 	| typedef_declaration pop ',' push declarator
 		{
-			typedefTable.addToEnclosingScope( TypedefTable::TD );
+			typedefTable.addToEnclosingScope( *$5->name, TypedefTable::TD );
 			$$ = $1->appendList( $1->cloneBaseType( $5 )->addTypedef() );
 		}
 	| type_qualifier_list TYPEDEF type_specifier declarator // remaining OBSOLESCENT (see 2 )
 		{
-			typedefTable.addToEnclosingScope( TypedefTable::TD );
+			typedefTable.addToEnclosingScope( *$4->name, TypedefTable::TD );
 			$$ = $4->addType( $3 )->addQualifiers( $1 )->addTypedef();
 		}
 	| type_specifier TYPEDEF declarator
 		{
-			typedefTable.addToEnclosingScope( TypedefTable::TD );
+			typedefTable.addToEnclosingScope( *$3->name, TypedefTable::TD );
 			$$ = $3->addType( $1 )->addTypedef();
 		}
 	| type_specifier TYPEDEF type_qualifier_list declarator
 		{
-			typedefTable.addToEnclosingScope( TypedefTable::TD );
+			typedefTable.addToEnclosingScope( *$4->name, TypedefTable::TD );
 			$$ = $4->addQualifiers( $1 )->addTypedef()->addType( $1 );
 		}
@@ -1508,11 +1469,11 @@
 	TYPEDEF no_attr_identifier '=' assignment_expression
 		{
-			typedefTable.addToEnclosingScope( *$2, TypedefTable::TD );
-			$$ = DeclarationNode::newName( 0 );			// unimplemented
+			// $$ = DeclarationNode::newName( 0 );			// unimplemented
+			SemanticError( yylloc, "Typedef expression is currently unimplemented." ); $$ = nullptr;
 		}
 	| typedef_expression pop ',' push no_attr_identifier '=' assignment_expression
 		{
-			typedefTable.addToEnclosingScope( *$5, TypedefTable::TD );
-			$$ = DeclarationNode::newName( 0 );			// unimplemented
+			// $$ = DeclarationNode::newName( 0 );			// unimplemented
+			SemanticError( yylloc, "Typedef expression is currently unimplemented." ); $$ = nullptr;
 		}
 	;
@@ -1542,7 +1503,5 @@
 c_declaration:
 	declaration_specifier declaring_list
-		{
-			$$ = distAttr( $1, $2 );
-		}
+		{ $$ = distAttr( $1, $2 ); }
 	| typedef_declaration
 	| typedef_expression								// GCC, naming expression type
@@ -1554,13 +1513,7 @@
 		// storage-class
 	declarator asm_name_opt initializer_opt
-		{
-			typedefTable.addToEnclosingScope( TypedefTable::ID );
-			$$ = $1->addAsmName( $2 )->addInitializer( $3 );
-		}
+		{ $$ = $1->addAsmName( $2 )->addInitializer( $3 ); }
 	| declaring_list ',' attribute_list_opt declarator asm_name_opt initializer_opt
-		{
-			typedefTable.addToEnclosingScope( TypedefTable::ID );
-			$$ = $1->appendList( $4->addQualifiers( $3 )->addAsmName( $5 )->addInitializer( $6 ) );
-		}
+		{ $$ = $1->appendList( $4->addQualifiers( $3 )->addAsmName( $5 )->addInitializer( $6 ) ); }
 	;
 
@@ -1854,5 +1807,5 @@
 
 aggregate_type:											// struct, union
-	aggregate_key attribute_list_opt '{' field_declaration_list '}'
+	aggregate_key attribute_list_opt '{' field_declaration_list_opt '}'
 		{ $$ = DeclarationNode::newAggregate( $1, new string( DeclarationNode::anonymous.newName() ), nullptr, $4, true )->addQualifiers( $2 ); }
 	| aggregate_key attribute_list_opt no_attr_identifier_or_type_name
@@ -1862,7 +1815,7 @@
 			forall = false;								// reset
 		}
-	  '{' field_declaration_list '}'
+	  '{' field_declaration_list_opt '}'
 		{ $$ = DeclarationNode::newAggregate( $1, $3, nullptr, $6, true )->addQualifiers( $2 ); }
-	| aggregate_key attribute_list_opt '(' type_list ')' '{' field_declaration_list '}' // CFA
+	| aggregate_key attribute_list_opt '(' type_list ')' '{' field_declaration_list_opt '}' // CFA
 		{ $$ = DeclarationNode::newAggregate( $1, new string( DeclarationNode::anonymous.newName() ), $4, $7, false )->addQualifiers( $2 ); }
 	| aggregate_type_nobody
@@ -1909,8 +1862,8 @@
 	;
 
-field_declaration_list:
+field_declaration_list_opt:
 	// empty
 		{ $$ = nullptr; }
-	| field_declaration_list field_declaration
+	| field_declaration_list_opt field_declaration
 		{ $$ = $1 ? $1->appendList( $2 ) : $2; }
 	;
@@ -1945,10 +1898,10 @@
 
 field_declaring_list:
-	field_declarator
-	| field_declaring_list ',' attribute_list_opt field_declarator
+	field_declarator_opt
+	| field_declaring_list ',' attribute_list_opt field_declarator_opt
 		{ $$ = $1->appendList( $4->addQualifiers( $3 ) ); }
 	;
 
-field_declarator:
+field_declarator_opt:
 	// empty
 		{ $$ = DeclarationNode::newName( 0 ); /* XXX */ } // CFA, no field name
@@ -2017,9 +1970,9 @@
 	| cfa_abstract_parameter_list
 	| cfa_parameter_list
-	| cfa_parameter_list pop ',' push cfa_abstract_parameter_list
-		{ $$ = $1->appendList( $5 ); }
-	| cfa_abstract_parameter_list pop ',' push ELLIPSIS
+	| cfa_parameter_list ',' cfa_abstract_parameter_list
+		{ $$ = $1->appendList( $3 ); }
+	| cfa_abstract_parameter_list ',' ELLIPSIS
 		{ $$ = $1->addVarArgs(); }
-	| cfa_parameter_list pop ',' push ELLIPSIS
+	| cfa_parameter_list ',' ELLIPSIS
 		{ $$ = $1->addVarArgs(); }
 	;
@@ -2029,16 +1982,16 @@
 		// factored out from cfa_parameter_list, flattening the rules to get lookahead to the ']'.
 	cfa_parameter_declaration
-	| cfa_abstract_parameter_list pop ',' push cfa_parameter_declaration
-		{ $$ = $1->appendList( $5 ); }
-	| cfa_parameter_list pop ',' push cfa_parameter_declaration
-		{ $$ = $1->appendList( $5 ); }
-	| cfa_parameter_list pop ',' push cfa_abstract_parameter_list pop ',' push cfa_parameter_declaration
-		{ $$ = $1->appendList( $5 )->appendList( $9 ); }
+	| cfa_abstract_parameter_list ',' cfa_parameter_declaration
+		{ $$ = $1->appendList( $3 ); }
+	| cfa_parameter_list ',' cfa_parameter_declaration
+		{ $$ = $1->appendList( $3 ); }
+	| cfa_parameter_list ',' cfa_abstract_parameter_list ',' cfa_parameter_declaration
+		{ $$ = $1->appendList( $3 )->appendList( $5 ); }
 	;
 
 cfa_abstract_parameter_list:							// CFA, new & old style abstract
 	cfa_abstract_parameter_declaration
-	| cfa_abstract_parameter_list pop ',' push cfa_abstract_parameter_declaration
-		{ $$ = $1->appendList( $5 ); }
+	| cfa_abstract_parameter_list ',' cfa_abstract_parameter_declaration
+		{ $$ = $1->appendList( $3 ); }
 	;
 
@@ -2090,13 +2043,7 @@
 		// No SUE declaration in parameter list.
 	declaration_specifier_nobody identifier_parameter_declarator default_initialize_opt
-		{
-			typedefTable.addToEnclosingScope( TypedefTable::ID );
-			$$ = $2->addType( $1 )->addInitializer( $3 ? new InitializerNode( $3 ) : nullptr );
-		}
+		{ $$ = $2->addType( $1 )->addInitializer( $3 ? new InitializerNode( $3 ) : nullptr ); }
 	| declaration_specifier_nobody type_parameter_redeclarator default_initialize_opt
-		{
-			typedefTable.addToEnclosingScope( TypedefTable::ID );
-			$$ = $2->addType( $1 )->addInitializer( $3 ? new InitializerNode( $3 ) : nullptr );
-		}
+		{ $$ = $2->addType( $1 )->addInitializer( $3 ? new InitializerNode( $3 ) : nullptr ); }
 	;
 
@@ -2156,14 +2103,14 @@
 initializer:
 	assignment_expression						{ $$ = new InitializerNode( $1 ); }
-	| '{' initializer_list comma_opt '}'		{ $$ = new InitializerNode( $2, true ); }
-	;
-
-initializer_list:
+	| '{' initializer_list_opt comma_opt '}'	{ $$ = new InitializerNode( $2, true ); }
+	;
+
+initializer_list_opt:
 	// empty
 		{ $$ = nullptr; }
 	| initializer
 	| designation initializer					{ $$ = $2->set_designators( $1 ); }
-	| initializer_list ',' initializer			{ $$ = (InitializerNode *)( $1->set_last( $3 ) ); }
-	| initializer_list ',' designation initializer
+	| initializer_list_opt ',' initializer		{ $$ = (InitializerNode *)( $1->set_last( $3 ) ); }
+	| initializer_list_opt ',' designation initializer
 		{ $$ = (InitializerNode *)( $1->set_last( $4->set_designators( $3 ) ) ); }
 	;
@@ -2195,13 +2142,13 @@
 	'.' no_attr_identifier								// C99, field name
 		{ $$ = new ExpressionNode( build_varref( $2 ) ); }
-	| '[' push assignment_expression pop ']'			// C99, single array element
+	| '[' assignment_expression ']'						// C99, single array element
 		// assignment_expression used instead of constant_expression because of shift/reduce conflicts with tuple.
+		{ $$ = $2; }
+	| '[' subrange ']'									// CFA, multiple array elements
+		{ $$ = $2; }
+	| '[' constant_expression ELLIPSIS constant_expression ']' // GCC, multiple array elements
+		{ $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild< Expression >( $2 ), maybeMoveBuild< Expression >( $4 ) ) ); }
+	| '.' '[' field_list ']'							// CFA, tuple field selector
 		{ $$ = $3; }
-	| '[' push subrange pop ']'							// CFA, multiple array elements
-		{ $$ = $3; }
-	| '[' push constant_expression ELLIPSIS constant_expression pop ']' // GCC, multiple array elements
-		{ $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild< Expression >( $3 ), maybeMoveBuild< Expression >( $5 ) ) ); }
-	| '.' '[' push field_list pop ']'					// CFA, tuple field selector
-		{ $$ = $4; }
 	;
 
@@ -2273,12 +2220,9 @@
 assertion:												// CFA
 	'|' no_attr_identifier_or_type_name '(' type_list ')'
-		{
-			typedefTable.openTrait( *$2 );
-			$$ = DeclarationNode::newTraitUse( $2, $4 );
-		}
+		{ $$ = DeclarationNode::newTraitUse( $2, $4 ); }
 	| '|' '{' push trait_declaration_list '}'
 		{ $$ = $4; }
 	| '|' '(' push type_parameter_list pop ')' '{' push trait_declaration_list '}' '(' type_list ')'
-		{ $$ = nullptr; }
+		{ SemanticError( yylloc, "Generic data-type assertion is currently unimplemented." ); $$ = nullptr; }
 	;
 
@@ -2324,19 +2268,9 @@
 trait_specifier:										// CFA
 	TRAIT no_attr_identifier_or_type_name '(' push type_parameter_list pop ')' '{' '}'
-		{
-			typedefTable.addToEnclosingScope( *$2, TypedefTable::ID );
-			$$ = DeclarationNode::newTrait( $2, $5, 0 );
-		}
+		{ $$ = DeclarationNode::newTrait( $2, $5, 0 ); }
 	| TRAIT no_attr_identifier_or_type_name '(' push type_parameter_list pop ')' '{'
-		{
-			typedefTable.enterTrait( *$2 );
-			typedefTable.enterScope();
-		}
+		{ typedefTable.enterScope(); }
 	  trait_declaration_list '}'
-		{
-			typedefTable.leaveTrait();
-			typedefTable.addToEnclosingScope( *$2, TypedefTable::ID );
-			$$ = DeclarationNode::newTrait( $2, $5, $10 );
-		}
+		{ $$ = DeclarationNode::newTrait( $2, $5, $10 ); }
 	;
 
@@ -2354,31 +2288,16 @@
 cfa_trait_declaring_list:								// CFA
 	cfa_variable_specifier
-		{
-			typedefTable.addToEnclosingScope2( TypedefTable::ID );
-			$$ = $1;
-		}
+		{ $$ = $1; }
 	| cfa_function_specifier
-		{
-			typedefTable.addToEnclosingScope2( TypedefTable::ID );
-			$$ = $1;
-		}
+		{ $$ = $1; }
 	| cfa_trait_declaring_list pop ',' push identifier_or_type_name
-		{
-			typedefTable.addToEnclosingScope2( *$5, TypedefTable::ID );
-			$$ = $1->appendList( $1->cloneType( $5 ) );
-		}
+		{ $$ = $1->appendList( $1->cloneType( $5 ) ); }
 	;
 
 trait_declaring_list:									// CFA
 	type_specifier declarator
-		{
-			typedefTable.addToEnclosingScope2( TypedefTable::ID );
-			$$ = $2->addType( $1 );
-		}
+		{ $$ = $2->addType( $1 ); }
 	| trait_declaring_list pop ',' push declarator
-		{
-			typedefTable.addToEnclosingScope2( TypedefTable::ID );
-			$$ = $1->appendList( $1->cloneBaseType( $5 ) );
-		}
+		{ $$ = $1->appendList( $1->cloneBaseType( $5 ) ); }
 	;
 
@@ -2488,5 +2407,4 @@
 	| function_declarator compound_statement
 		{
-			typedefTable.addToEnclosingScope( TypedefTable::ID );
 			typedefTable.leaveScope();
 			$$ = $1->addFunctionBody( $2 );
@@ -2494,5 +2412,4 @@
 	| KR_function_declarator KR_declaration_list_opt compound_statement
 		{
-			typedefTable.addToEnclosingScope( TypedefTable::ID );
 			typedefTable.leaveScope();
 			$$ = $1->addOldDeclList( $2 )->addFunctionBody( $3 );
@@ -2510,5 +2427,4 @@
 	cfa_function_declaration with_clause_opt compound_statement	// CFA
 		{
-			typedefTable.addToEnclosingScope( TypedefTable::ID );
 			typedefTable.leaveScope();
 			// Add the function body to the last identifier in the function definition list, i.e., foo3:
@@ -2520,12 +2436,16 @@
 		{
 			rebindForall( $1, $2 );
-			typedefTable.addToEnclosingScope( TypedefTable::ID );
 			typedefTable.leaveScope();
 			$$ = $2->addFunctionBody( $4, $3 )->addType( $1 );
 		}
+	| declaration_specifier variable_type_redeclarator with_clause_opt compound_statement
+		{
+			rebindForall( $1, $2 );
+			typedefTable.leaveScope();
+			$$ = $2->addFunctionBody( $4, $3 )->addType( $1 );
+		}
 		// handles default int return type, OBSOLESCENT (see 1)
 	| type_qualifier_list function_declarator with_clause_opt compound_statement
 		{
-			typedefTable.addToEnclosingScope( TypedefTable::ID );
 			typedefTable.leaveScope();
 			$$ = $2->addFunctionBody( $4, $3 )->addQualifiers( $1 );
@@ -2534,5 +2454,4 @@
 	| declaration_qualifier_list function_declarator with_clause_opt compound_statement
 		{
-			typedefTable.addToEnclosingScope( TypedefTable::ID );
 			typedefTable.leaveScope();
 			$$ = $2->addFunctionBody( $4, $3 )->addQualifiers( $1 );
@@ -2541,5 +2460,4 @@
 	| declaration_qualifier_list type_qualifier_list function_declarator with_clause_opt compound_statement
 		{
-			typedefTable.addToEnclosingScope( TypedefTable::ID );
 			typedefTable.leaveScope();
 			$$ = $3->addFunctionBody( $5, $4 )->addQualifiers( $2 )->addQualifiers( $1 );
@@ -2550,5 +2468,4 @@
 		{
 			rebindForall( $1, $2 );
-			typedefTable.addToEnclosingScope( TypedefTable::ID );
 			typedefTable.leaveScope();
 			$$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addType( $1 );
@@ -2557,5 +2474,4 @@
 	| type_qualifier_list KR_function_declarator KR_declaration_list_opt with_clause_opt compound_statement
 		{
-			typedefTable.addToEnclosingScope( TypedefTable::ID );
 			typedefTable.leaveScope();
 			$$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addQualifiers( $1 );
@@ -2564,5 +2480,4 @@
 	| declaration_qualifier_list KR_function_declarator KR_declaration_list_opt with_clause_opt compound_statement
 		{
-			typedefTable.addToEnclosingScope( TypedefTable::ID );
 			typedefTable.leaveScope();
 			$$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addQualifiers( $1 );
@@ -2571,5 +2486,4 @@
 	| declaration_qualifier_list type_qualifier_list KR_function_declarator KR_declaration_list_opt with_clause_opt compound_statement
 		{
-			typedefTable.addToEnclosingScope( TypedefTable::ID );
 			typedefTable.leaveScope();
 			$$ = $3->addOldDeclList( $4 )->addFunctionBody( $6, $5 )->addQualifiers( $2 )->addQualifiers( $1 );
@@ -2684,8 +2598,5 @@
 paren_identifier:
 	identifier
-		{
-			typedefTable.setNextIdentifier( *$1 );
-			$$ = DeclarationNode::newName( $1 );
-		}
+		{ $$ = DeclarationNode::newName( $1 ); }
 	| '(' paren_identifier ')'							// redundant parenthesis
 		{ $$ = $2; }
@@ -2774,6 +2685,6 @@
 	paren_identifier '(' identifier_list ')'			// function_declarator handles empty parameter
 		{ $$ = $1->addIdList( $3 ); }
-	| '(' KR_function_ptr ')' '(' push parameter_type_list_opt pop ')'
-		{ $$ = $2->addParamList( $6 ); }
+	| '(' KR_function_ptr ')' '(' parameter_type_list_opt ')'
+		{ $$ = $2->addParamList( $5 ); }
 	| '(' KR_function_no_ptr ')'						// redundant parenthesis
 		{ $$ = $2; }
@@ -2820,4 +2731,7 @@
 paren_type:
 	typedef
+		{ // hide type name by variable name
+			typedefTable.addToEnclosingScope( *$1->name, TypedefTable::ID );
+		}
 	| '(' paren_type ')'
 		{ $$ = $2; }
@@ -2891,8 +2805,8 @@
 
 identifier_parameter_function:
-	paren_identifier '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
-		{ $$ = $1->addParamList( $4 ); }
-	| '(' identifier_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
-		{ $$ = $2->addParamList( $6 ); }
+	paren_identifier '(' parameter_type_list_opt ')'	// empty parameter list OBSOLESCENT (see 3)
+		{ $$ = $1->addParamList( $3 ); }
+	| '(' identifier_parameter_ptr ')' '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
+		{ $$ = $2->addParamList( $5 ); }
 	| '(' identifier_parameter_function ')'				// redundant parenthesis
 		{ $$ = $2; }
@@ -2922,13 +2836,7 @@
 typedef:
 	TYPEDEFname
-		{
-			typedefTable.setNextIdentifier( *$1 );
-			$$ = DeclarationNode::newName( $1 );
-		}
+		{ $$ = DeclarationNode::newName( $1 ); }
 	| TYPEGENname
-		{
-			typedefTable.setNextIdentifier( *$1 );
-			$$ = DeclarationNode::newName( $1 );
-		}
+		{ $$ = DeclarationNode::newName( $1 ); }
 	;
 
@@ -2950,8 +2858,8 @@
 
 type_parameter_function:
-	typedef '(' push parameter_type_list_opt pop ')'	// empty parameter list OBSOLESCENT (see 3)
-		{ $$ = $1->addParamList( $4 ); }
-	| '(' type_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
-		{ $$ = $2->addParamList( $6 ); }
+	typedef '(' parameter_type_list_opt ')'				// empty parameter list OBSOLESCENT (see 3)
+		{ $$ = $1->addParamList( $3 ); }
+	| '(' type_parameter_ptr ')' '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
+		{ $$ = $2->addParamList( $5 ); }
 	;
 
@@ -3000,8 +2908,8 @@
 
 abstract_function:
-	'(' push parameter_type_list_opt pop ')'			// empty parameter list OBSOLESCENT (see 3)
-		{ $$ = DeclarationNode::newFunction( nullptr, nullptr, $3, nullptr ); }
-	| '(' abstract_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
-		{ $$ = $2->addParamList( $6 ); }
+	'(' parameter_type_list_opt ')'						// empty parameter list OBSOLESCENT (see 3)
+		{ $$ = DeclarationNode::newFunction( nullptr, nullptr, $2, nullptr ); }
+	| '(' abstract_ptr ')' '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
+		{ $$ = $2->addParamList( $5 ); }
 	| '(' abstract_function ')'							// redundant parenthesis
 		{ $$ = $2; }
@@ -3018,11 +2926,11 @@
 
 multi_array_dimension:
-	'[' push assignment_expression pop ']'
-		{ $$ = DeclarationNode::newArray( $3, 0, false ); }
-	| '[' push '*' pop ']'								// C99
+	'[' assignment_expression ']'
+		{ $$ = DeclarationNode::newArray( $2, 0, false ); }
+	| '[' '*' ']'										// C99
 		{ $$ = DeclarationNode::newVarArray( 0 ); }
-	| multi_array_dimension '[' push assignment_expression pop ']'
-		{ $$ = $1->addArray( DeclarationNode::newArray( $4, 0, false ) ); }
-	| multi_array_dimension '[' push '*' pop ']'		// C99
+	| multi_array_dimension '[' assignment_expression ']'
+		{ $$ = $1->addArray( DeclarationNode::newArray( $3, 0, false ) ); }
+	| multi_array_dimension '[' '*' ']'					// C99
 		{ $$ = $1->addArray( DeclarationNode::newVarArray( 0 ) ); }
 	;
@@ -3091,8 +2999,8 @@
 
 abstract_parameter_function:
-	'(' push parameter_type_list_opt pop ')'			// empty parameter list OBSOLESCENT (see 3)
-		{ $$ = DeclarationNode::newFunction( nullptr, nullptr, $3, nullptr ); }
-	| '(' abstract_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
-		{ $$ = $2->addParamList( $6 ); }
+	'(' parameter_type_list_opt ')'						// empty parameter list OBSOLESCENT (see 3)
+		{ $$ = DeclarationNode::newFunction( nullptr, nullptr, $2, nullptr ); }
+	| '(' abstract_parameter_ptr ')' '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
+		{ $$ = $2->addParamList( $5 ); }
 	| '(' abstract_parameter_function ')'				// redundant parenthesis
 		{ $$ = $2; }
@@ -3116,15 +3024,15 @@
 		{ $$ = DeclarationNode::newArray( 0, 0, false ); }
 	// multi_array_dimension handles the '[' '*' ']' case
-	| '[' push type_qualifier_list '*' pop ']'			// remaining C99
-		{ $$ = DeclarationNode::newVarArray( $3 ); }
-	| '[' push type_qualifier_list pop ']'
-		{ $$ = DeclarationNode::newArray( 0, $3, false ); }
+	| '[' type_qualifier_list '*' ']'					// remaining C99
+		{ $$ = DeclarationNode::newVarArray( $2 ); }
+	| '[' type_qualifier_list ']'
+		{ $$ = DeclarationNode::newArray( 0, $2, false ); }
 	// multi_array_dimension handles the '[' assignment_expression ']' case
-	| '[' push type_qualifier_list assignment_expression pop ']'
-		{ $$ = DeclarationNode::newArray( $4, $3, false ); }
-	| '[' push STATIC type_qualifier_list_opt assignment_expression pop ']'
-		{ $$ = DeclarationNode::newArray( $5, $4, true ); }
-	| '[' push type_qualifier_list STATIC assignment_expression pop ']'
-		{ $$ = DeclarationNode::newArray( $5, $3, true ); }
+	| '[' type_qualifier_list assignment_expression ']'
+		{ $$ = DeclarationNode::newArray( $3, $2, false ); }
+	| '[' STATIC type_qualifier_list_opt assignment_expression ']'
+		{ $$ = DeclarationNode::newArray( $4, $3, true ); }
+	| '[' type_qualifier_list STATIC assignment_expression ']'
+		{ $$ = DeclarationNode::newArray( $4, $2, true ); }
 	;
 
@@ -3170,6 +3078,6 @@
 
 variable_abstract_function:
-	'(' variable_abstract_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
-		{ $$ = $2->addParamList( $6 ); }
+	'(' variable_abstract_ptr ')' '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
+		{ $$ = $2->addParamList( $5 ); }
 	| '(' variable_abstract_function ')'				// redundant parenthesis
 		{ $$ = $2; }
@@ -3234,15 +3142,15 @@
 
 cfa_array_parameter_1st_dimension:
-	'[' push type_qualifier_list '*' pop ']'			// remaining C99
-		{ $$ = DeclarationNode::newVarArray( $3 ); }
-	| '[' push type_qualifier_list assignment_expression pop ']'
-		{ $$ = DeclarationNode::newArray( $4, $3, false ); }
-	| '[' push declaration_qualifier_list assignment_expression pop ']'
+	'[' type_qualifier_list '*' ']'						// remaining C99
+		{ $$ = DeclarationNode::newVarArray( $2 ); }
+	| '[' type_qualifier_list assignment_expression ']'
+		{ $$ = DeclarationNode::newArray( $3, $2, false ); }
+	| '[' declaration_qualifier_list assignment_expression ']'
 		// declaration_qualifier_list must be used because of shift/reduce conflict with
 		// assignment_expression, so a semantic check is necessary to preclude them as a type_qualifier cannot
 		// appear in this context.
-		{ $$ = DeclarationNode::newArray( $4, $3, true ); }
-	| '[' push declaration_qualifier_list type_qualifier_list assignment_expression pop ']'
-		{ $$ = DeclarationNode::newArray( $5, $4->addQualifiers( $3 ), true ); }
+		{ $$ = DeclarationNode::newArray( $3, $2, true ); }
+	| '[' declaration_qualifier_list type_qualifier_list assignment_expression ']'
+		{ $$ = DeclarationNode::newArray( $4, $3->addQualifiers( $3 ), true ); }
 	;
 
@@ -3313,6 +3221,6 @@
 
 cfa_abstract_tuple:										// CFA
-	'[' push cfa_abstract_parameter_list pop ']'
-		{ $$ = DeclarationNode::newTuple( $3 ); }
+	'[' cfa_abstract_parameter_list ']'
+		{ $$ = DeclarationNode::newTuple( $2 ); }
 	;
 
@@ -3320,8 +3228,8 @@
 //	'[' ']' '(' cfa_parameter_type_list_opt ')'
 //		{ $$ = DeclarationNode::newFunction( nullptr, DeclarationNode::newTuple( nullptr ), $4, nullptr ); }
-	cfa_abstract_tuple '(' push cfa_parameter_type_list_opt pop ')'
-		{ $$ = DeclarationNode::newFunction( nullptr, $1, $4, nullptr ); }
-	| cfa_function_return '(' push cfa_parameter_type_list_opt pop ')'
-		{ $$ = DeclarationNode::newFunction( nullptr, $1, $4, nullptr ); }
+	cfa_abstract_tuple '(' cfa_parameter_type_list_opt ')'
+		{ $$ = DeclarationNode::newFunction( nullptr, $1, $3, nullptr ); }
+	| cfa_function_return '(' cfa_parameter_type_list_opt ')'
+		{ $$ = DeclarationNode::newFunction( nullptr, $1, $3, nullptr ); }
 	;
 
