Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 647d633294d7c8a3d0e1372bff5560a51ee2ad58)
+++ src/Parser/parser.yy	(revision 56b47b9033a5f40a29685dbaf425681c7d4f5e1c)
@@ -10,6 +10,6 @@
 // Created On       : Sat Sep  1 20:22:55 2001
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Mon Mar  4 08:44:25 2024
-// Update Count     : 6562
+// Last Modified On : Wed Mar  6 10:51:55 2024
+// Update Count     : 6588
 //
 
@@ -938,7 +938,15 @@
 	| ALIGNOF '(' type_no_function ')'					// GCC, type alignment
 		{ $$ = new ExpressionNode( new ast::AlignofExpr( yylloc, maybeMoveBuildType( $3 ) ) ); }
+
+		// Cannot use rule "type", which includes cfa_abstract_function, for sizeof/alignof, because of S/R problems on
+		// look ahead, so the cfa_abstract_function is factored out.
+	| SIZEOF '(' cfa_abstract_function ')'
+		{ $$ = new ExpressionNode( new ast::SizeofExpr( yylloc, maybeMoveBuildType( $3 ) ) ); }
+	| ALIGNOF '(' cfa_abstract_function ')'				// GCC, type alignment
+		{ $$ = new ExpressionNode( new ast::AlignofExpr( yylloc, maybeMoveBuildType( $3 ) ) ); }
+
 	| OFFSETOF '(' type_no_function ',' identifier ')'
 		{ $$ = new ExpressionNode( build_offsetOf( yylloc, $3, build_varref( yylloc, $5 ) ) ); }
-	| TYPEID '(' type_no_function ')'
+	| TYPEID '(' type ')'
 		{
 			SemanticError( yylloc, "typeid name is currently unimplemented." ); $$ = nullptr;
@@ -1238,5 +1246,6 @@
 		{ assert( $1 ); $1->set_last( $2 ); $$ = $1; }
 	| statement_list_nodecl error						// invalid syntax rule
-		{ SemanticError( yylloc, "syntax error, declarations only allowed at the start of the switch body, i.e., after the '{'." ); $$ = nullptr; }
+		{ SemanticError( yylloc, "syntax error, declarations only allowed at the start of the switch body,"
+						 " i.e., after the '{'." ); $$ = nullptr; }
 	;
 
@@ -1246,9 +1255,27 @@
 	;
 
-// if, switch, and choose require parenthesis around the conditional because it can be followed by a statement.
-// For example, without parenthesis:
-//
-//    if x + y + z; => "if ( x + y ) + z" or "if ( x ) + y + z"
-//    switch ( S ) { ... } => switch ( S ) { compound literal... } ... or 
+// "if", "switch", and "choose" require parenthesis around the conditional. See the following ambiguities without
+// parenthesis:
+//
+//   if x + y + z; => "if ( x + y ) + z" or "if ( x ) + y + z"
+//
+//   switch O { }
+// 
+//     O{} => object-constructor for conditional, switch body ???
+//     O{} => O for conditional followed by switch body
+// 
+//     C++ has this problem, as it has the same constructor syntax.
+// 
+//   switch sizeof ( T ) { }
+// 
+//     sizeof ( T ) => sizeof of T for conditional followed by switch body
+//     sizeof ( T ) => sizeof of compound literal (T){ }, closing parenthesis ???
+// 
+//     Note the two grammar rules for sizeof (alignof)
+// 
+//       | SIZEOF unary_expression
+//       | SIZEOF '(' type_no_function ')'
+// 
+//     where the first DOES NOT require parenthesis! And C++ inherits this problem from C.
 
 selection_statement:
@@ -2200,4 +2227,9 @@
 	| ATOMIC
 		{ $$ = DeclarationNode::newTypeQualifier( ast::CV::Atomic ); }
+
+		// forall must be a CV qualifier because it can appear in places where SC qualifiers are disallowed.
+		//
+		//   void foo( forall( T ) T (*)( T ) ); // forward declaration
+		//   void bar( static int ); // static disallowed (gcc/CFA)
 	| forall
 		{ $$ = DeclarationNode::newForall( $1 ); }
@@ -2464,4 +2496,6 @@
 	;
 
+// ************************** AGGREGATE *******************************
+
 aggregate_type:											// struct, union
 	aggregate_key attribute_list_opt
@@ -2544,5 +2578,4 @@
 	| EXCEPTION											// CFA
 		{ $$ = ast::AggregateDecl::Exception; }
-	  //		{ SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = ast::AggregateDecl::NoAggregate; }
 	;
 
@@ -2683,7 +2716,5 @@
 	;
 
-// ***********
-// Enumeration
-// ***********
+// ************************** ENUMERATION *******************************
 
 enum_type:
@@ -2785,7 +2816,5 @@
 	;
 
-// *******************
-// Function parameters
-// *******************
+// ************************** FUNCTION PARAMETERS *******************************
 
 parameter_list_ellipsis_opt:
@@ -2868,5 +2897,5 @@
 	| type_qualifier_list cfa_abstract_tuple identifier_or_type_name default_initializer_opt
 		{ $$ = $2->addName( $3 )->addQualifiers( $1 ); }
-	| cfa_function_specifier
+	| cfa_function_specifier							// int f( "int fp()" );
 	;
 
@@ -2878,5 +2907,5 @@
 	| type_qualifier_list cfa_abstract_tuple
 		{ $$ = $2->addQualifiers( $1 ); }
-	| cfa_abstract_function
+	| cfa_abstract_function								// int f( "int ()" );
 	;
 
@@ -3036,7 +3065,7 @@
 		{ $$ = ast::TypeDecl::Dtype; }
 	| '*'
-		{ $$ = ast::TypeDecl::DStype; }						// dtype + sized
-	// | '(' '*' ')'
-	// 	{ $$ = ast::TypeDecl::Ftype; }
+		{ $$ = ast::TypeDecl::DStype; }					// Dtype + sized
+	// | '(' '*' ')'									// Gregor made me do it
+	//  	{ $$ = ast::TypeDecl::Ftype; }
 	| ELLIPSIS
 		{ $$ = ast::TypeDecl::Ttype; }
@@ -3244,5 +3273,5 @@
 			$$ = $6;
 		}
-	// global distribution
+		// global distribution
 	| type_qualifier_list
 		{
@@ -3369,4 +3398,6 @@
 	;
 
+// **************************** ASM *****************************
+
 asm_name_opt:											// GCC
 	// empty
@@ -3379,4 +3410,6 @@
 		}
 	;
+
+// **************************** ATTRIBUTE *****************************
 
 attribute_list_opt:										// GCC
@@ -3826,5 +3859,5 @@
 
 type_parameter_function:
-	typedef_name '(' parameter_list_ellipsis_opt ')' // empty parameter list OBSOLESCENT (see 3)
+	typedef_name '(' parameter_list_ellipsis_opt ')'	// empty parameter list OBSOLESCENT (see 3)
 		{ $$ = $1->addParamList( $3 ); }
 	| '(' type_parameter_ptr ')' '(' parameter_list_ellipsis_opt ')' // empty parameter list OBSOLESCENT (see 3)
@@ -3876,5 +3909,5 @@
 
 abstract_function:
-	'(' parameter_list_ellipsis_opt ')'			// empty parameter list OBSOLESCENT (see 3)
+	'(' parameter_list_ellipsis_opt ')'					// empty parameter list OBSOLESCENT (see 3)
 		{ $$ = DeclarationNode::newFunction( nullptr, nullptr, $2, nullptr ); }
 	| '(' abstract_ptr ')' '(' parameter_list_ellipsis_opt ')' // empty parameter list OBSOLESCENT (see 3)
@@ -4008,5 +4041,5 @@
 
 abstract_parameter_function:
-	'(' parameter_list_ellipsis_opt ')'			// empty parameter list OBSOLESCENT (see 3)
+	'(' parameter_list_ellipsis_opt ')'					// empty parameter list OBSOLESCENT (see 3)
 		{ $$ = DeclarationNode::newFunction( nullptr, nullptr, $2, nullptr ); }
 	| '(' abstract_parameter_ptr ')' '(' parameter_list_ellipsis_opt ')' // empty parameter list OBSOLESCENT (see 3)
@@ -4280,4 +4313,4 @@
 // mode: c++ //
 // tab-width: 4 //
-// compile-command: "make install" //
+// compile-command: "bison -Wcounterexamples parser.yy" //
 // End: //
