Module Name:    src
Committed By:   rillig
Date:           Thu May  9 20:15:05 UTC 2024

Modified Files:
        src/usr.bin/xlint/lint1: cgram.y

Log Message:
lint: sort grammar rules according to the order they appear in C23


To generate a diff of this commit:
cvs rdiff -u -r1.496 -r1.497 src/usr.bin/xlint/lint1/cgram.y

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/xlint/lint1/cgram.y
diff -u src/usr.bin/xlint/lint1/cgram.y:1.496 src/usr.bin/xlint/lint1/cgram.y:1.497
--- src/usr.bin/xlint/lint1/cgram.y:1.496	Thu May  9 11:08:07 2024
+++ src/usr.bin/xlint/lint1/cgram.y	Thu May  9 20:15:05 2024
@@ -1,5 +1,5 @@
 %{
-/* $NetBSD: cgram.y,v 1.496 2024/05/09 11:08:07 rillig Exp $ */
+/* $NetBSD: cgram.y,v 1.497 2024/05/09 20:15:05 rillig Exp $ */
 
 /*
  * Copyright (c) 1996 Christopher G. Demetriou.  All Rights Reserved.
@@ -35,7 +35,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID)
-__RCSID("$NetBSD: cgram.y,v 1.496 2024/05/09 11:08:07 rillig Exp $");
+__RCSID("$NetBSD: cgram.y,v 1.497 2024/05/09 20:15:05 rillig Exp $");
 #endif
 
 #include <limits.h>
@@ -328,9 +328,12 @@ is_either(const char *s, const char *a, 
 /* No type for type_attribute. */
 /* No type for begin_type. */
 /* No type for end_type. */
+/* No type for notype_init_declarators. */
+/* No type for type_init_declarators. */
+/* No type for notype_init_declarator. */
+/* No type for type_init_declarator. */
 %type	<y_type>	type_specifier
 %type	<y_type>	notype_type_specifier
-%type	<y_type>	atomic_type_specifier
 %type	<y_type>	struct_or_union_specifier
 %type	<y_tspec>	struct_or_union
 %type	<y_sym>		braced_member_declaration_list
@@ -347,19 +350,17 @@ is_either(const char *s, const char *a, 
 %type	<y_sym>		enums_with_opt_comma
 %type	<y_sym>		enumerator_list
 %type	<y_sym>		enumerator
-%type	<y_type_qualifiers>	type_qualifier
+%type	<y_type>	atomic_type_specifier
 /* No type for atomic. */
-%type	<y_qual_ptr>	pointer
-%type	<y_type_qualifiers>	type_qualifier_list_opt
-%type	<y_type_qualifiers>	type_qualifier_list
-/* No type for notype_init_declarators. */
-/* No type for type_init_declarators. */
-/* No type for notype_init_declarator. */
-/* No type for type_init_declarator. */
+%type	<y_type_qualifiers>	type_qualifier
 %type	<y_sym>		notype_declarator
 %type	<y_sym>		type_declarator
 %type	<y_sym>		notype_direct_declarator
 %type	<y_sym>		type_direct_declarator
+%type	<y_qual_ptr>	pointer
+%type	<y_type_qualifiers>	type_qualifier_list_opt
+%type	<y_type_qualifiers>	type_qualifier_list
+%type	<y_sym>		parameter_declaration
 %type	<y_sym>		type_param_declarator
 %type	<y_sym>		notype_param_declarator
 %type	<y_sym>		direct_param_declarator
@@ -369,13 +370,12 @@ is_either(const char *s, const char *a, 
 %type	<y_sym>		identifier_list
 %type	<y_type>	type_name
 %type	<y_sym>		abstract_declaration
-%type	<y_sym>		abstract_declarator
-%type	<y_sym>		direct_abstract_declarator
 %type	<y_parameter_list>	abstract_decl_param_list
 /* No type for abstract_decl_lparen. */
 %type	<y_parameter_list>	vararg_parameter_type_list
 %type	<y_parameter_list>	parameter_type_list
-%type	<y_sym>		parameter_declaration
+%type	<y_sym>		abstract_declarator
+%type	<y_sym>		direct_abstract_declarator
 /* No type for braced_initializer. */
 /* No type for initializer. */
 /* No type for initializer_list. */
@@ -391,8 +391,8 @@ is_either(const char *s, const char *a, 
 /* No type for no_attr_statement. */
 /* No type for non_expr_statement. */
 /* No type for no_attr_non_expr_statement. */
-/* No type for labeled_statement. */
 /* No type for label. */
+/* No type for labeled_statement. */
 /* No type for compound_statement. */
 /* No type for compound_statement_lbrace. */
 /* No type for compound_statement_rbrace. */
@@ -472,7 +472,7 @@ string:
 	}
 ;
 
-/* K&R 7.1, C90 ???, C99 6.5.1, C11 6.5.1 */
+/* K&R 7.1, C90 ???, C99 6.5.1, C11 6.5.1, C23 6.5.2 */
 primary_expression:
 	T_NAME {
 		bool sys_name, sys_next;
@@ -541,7 +541,7 @@ member_designator:
 	}
 ;
 
-/* K&R ---, C90 ---, C99 ---, C11 6.5.1.1 */
+/* K&R ---, C90 ---, C99 ---, C11 6.5.1.1, C23 6.5.2.1 */
 generic_selection:
 	T_GENERIC T_LPAREN assignment_expression T_COMMA
 	    generic_assoc_list T_RPAREN {
@@ -551,7 +551,7 @@ generic_selection:
 	}
 ;
 
-/* K&R ---, C90 ---, C99 ---, C11 6.5.1.1 */
+/* K&R ---, C90 ---, C99 ---, C11 6.5.1.1, C23 6.5.2.1 */
 generic_assoc_list:
 	generic_association
 |	generic_assoc_list T_COMMA generic_association {
@@ -560,7 +560,7 @@ generic_assoc_list:
 	}
 ;
 
-/* K&R ---, C90 ---, C99 ---, C11 6.5.1.1 */
+/* K&R ---, C90 ---, C99 ---, C11 6.5.1.1, C23 6.5.2.1 */
 generic_association:
 	type_name T_COLON assignment_expression {
 		$$ = block_zero_alloc(sizeof(*$$), "generic");
@@ -574,7 +574,7 @@ generic_association:
 	}
 ;
 
-/* K&R 7.1, C90 ???, C99 6.5.2, C11 6.5.2, C23 6.5.2 */
+/* K&R 7.1, C90 ???, C99 6.5.2, C11 6.5.2, C23 6.5.3.1 */
 postfix_expression:
 	primary_expression
 |	postfix_expression T_LBRACK sys expression T_RBRACK {
@@ -594,7 +594,8 @@ postfix_expression:
 |	postfix_expression T_INCDEC sys {
 		$$ = build_unary($2 ? INCAFT : DECAFT, $3, $1);
 	}
-|	T_LPAREN type_name T_RPAREN {	/* C99 6.5.2.5 "Compound literals" */
+	/* Rule 'compound_literal' from C99 6.5.2.5. */
+|	T_LPAREN type_name T_RPAREN {
 		sym_t *tmp = mktempsym($2);
 		begin_initialization(tmp);
 		cgram_declare(tmp, true, NULL);
@@ -665,7 +666,7 @@ point_or_arrow:			/* helper for 'postfix
 	}
 ;
 
-/* K&R 7.1, C90 ???, C99 6.5.2, C11 6.5.2 */
+/* K&R 7.1, C90 ???, C99 6.5.2, C11 6.5.2, C23 6.5.3.1 */
 argument_expression_list:
 	assignment_expression {
 		$$ = expr_zero_alloc(sizeof(*$$), "function_call");
@@ -677,7 +678,13 @@ argument_expression_list:
 	}
 ;
 
-/* K&R 7.2, C90 ???, C99 6.5.3, C11 6.5.3 */
+
+/* C23 6.5.3.6 */
+/* The rule 'compound_literal' is inlined into 'postfix_expression'. */
+
+/* TODO: Implement 'storage_class_specifiers' from C23 6.5.3.6. */
+
+/* K&R 7.2, C90 ???, C99 6.5.3, C11 6.5.3, C23 6.5.4 */
 unary_expression:
 	postfix_expression
 |	T_INCDEC sys unary_expression {
@@ -725,16 +732,17 @@ unary_expression:
 		lint_assert($2 != NULL);
 		$$ = build_alignof($2->tn_type);
 	}
-	/* K&R ---, C90 ---, C99 ---, C11 6.5.3 */
+	/* K&R ---, C90 ---, C99 ---, C11 6.5.3, C23 6.5.4.4 */
 |	T_ALIGNOF T_LPAREN type_name T_RPAREN {
 		/* TODO: c11ism */
 		$$ = build_alignof($3);
 	}
 ;
 
+/* C23 6.5.4 */
 /* The rule 'unary_operator' is inlined into unary_expression. */
 
-/* K&R 7.2, C90 ???, C99 6.5.4, C11 6.5.4 */
+/* K&R 7.2, C90 ???, C99 6.5.4, C11 6.5.4, C23 6.5.5 */
 cast_expression:
 	unary_expression
 |	T_LPAREN type_name T_RPAREN sys cast_expression {
@@ -759,7 +767,7 @@ expression_opt:
 /* 'conditional_expression' also implements 'inclusive_OR_expression'. */
 /* 'conditional_expression' also implements 'logical_AND_expression'. */
 /* 'conditional_expression' also implements 'logical_OR_expression'. */
-/* K&R ???, C90 ???, C99 6.5.5 to 6.5.15, C11 6.5.5 to 6.5.15 */
+/* K&R ???, C90 ???, C99 6.5.5 to 6.5.15, C11 6.5.5 to 6.5.15, C23 6.5.6 to 6.5.16 */
 conditional_expression:
 	cast_expression
 |	conditional_expression T_ASTERISK sys conditional_expression {
@@ -802,7 +810,7 @@ conditional_expression:
 	}
 ;
 
-/* K&R ???, C90 ???, C99 6.5.16, C11 6.5.16 */
+/* K&R ???, C90 ???, C99 6.5.16, C11 6.5.16, C23 6.5.17.1 */
 assignment_expression:
 	conditional_expression
 |	unary_expression T_ASSIGN sys assignment_expression {
@@ -813,7 +821,10 @@ assignment_expression:
 	}
 ;
 
-/* K&R ???, C90 ???, C99 6.5.17, C11 6.5.17 */
+/* C23 6.5.17.1 */
+/* The rule 'assignment_operator' is inlined into 'assignment_expression'. */
+
+/* K&R ???, C90 ???, C99 6.5.17, C11 6.5.17, C23 6.5.18 */
 expression:
 	assignment_expression
 |	expression T_COMMA sys assignment_expression {
@@ -831,7 +842,7 @@ declaration_or_error:
 |	error T_SEMI
 ;
 
-/* K&R ???, C90 ???, C99 6.7, C11 ???, C23 6.7 */
+/* K&R ???, C90 ???, C99 6.7, C11 ???, C23 6.7.1 */
 declaration:
 	begin_type_declmods end_type T_SEMI {
 		if (dcs->d_scl == TYPEDEF)
@@ -862,7 +873,9 @@ declaration:
 |	static_assert_declaration
 ;
 
-begin_type_declaration_specifiers:	/* see C99 6.7 */
+/* TODO: Implement 'declaration_specifiers' from C23 6.7.1. */
+
+begin_type_declaration_specifiers:	/* see C99 6.7, C23 6.7.1 */
 	begin_type_typespec {
 		dcs_add_type($1);
 	}
@@ -981,7 +994,64 @@ end_type:
 	}
 ;
 
-type_specifier:			/* C99 6.7.2 */
+/* TODO: Implement 'declaration_specifier' from C23 6.7.1. */
+
+/*
+ * For an explanation of 'type' and 'notype' prefixes in the following rules,
+ * see https://www.gnu.org/software/bison/manual/bison.html#Semantic-Tokens.
+ */
+
+/* C23 6.7.1 */
+/* The rule 'init_declarator_list' is split into the 'notype' and 'type' variants. */
+
+notype_init_declarators:
+	notype_init_declarator
+|	notype_init_declarators T_COMMA type_init_declarator
+;
+
+type_init_declarators:
+	type_init_declarator
+|	type_init_declarators T_COMMA type_init_declarator
+;
+
+/* C23 6.7.1 */
+/* The rule 'init_declarator' is split into the 'notype' and 'type' variants. */
+
+notype_init_declarator:
+	notype_declarator asm_or_symbolrename_opt {
+		cgram_declare($1, false, $2);
+		check_size($1);
+	}
+|	notype_declarator asm_or_symbolrename_opt {
+		begin_initialization($1);
+		cgram_declare($1, true, $2);
+	} T_ASSIGN initializer {
+		check_size($1);
+		end_initialization();
+	}
+;
+
+type_init_declarator:
+	type_declarator asm_or_symbolrename_opt {
+		cgram_declare($1, false, $2);
+		check_size($1);
+	}
+|	type_declarator asm_or_symbolrename_opt {
+		begin_initialization($1);
+		cgram_declare($1, true, $2);
+	} T_ASSIGN initializer {
+		check_size($1);
+		end_initialization();
+	}
+;
+
+
+/* TODO: Implement 'attribute_declaration' from C23 6.7.1. */
+
+/* TODO: Implement 'storage_class_specifier' from C23 6.7.2. */
+
+/* C99 6.7.2, C23 6.7.3.1 */
+type_specifier:
 	notype_type_specifier
 |	T_TYPENAME {
 		$$ = getsym($1)->s_type;
@@ -1007,14 +1077,7 @@ notype_type_specifier:		/* see C99 6.7.2
 	}
 ;
 
-/* K&R ---, C90 ---, C99 ---, C11 6.7.2.4 */
-atomic_type_specifier:
-	atomic T_LPAREN type_name T_RPAREN {
-		$$ = $3;
-	}
-;
-
-/* K&R ---, C90 ---, C99 6.7.2.1, C11 ???, C23 6.7.2.1 */
+/* K&R ---, C90 ---, C99 6.7.2.1, C11 ???, C23 6.7.3.2 */
 struct_or_union_specifier:
 	struct_or_union identifier_sym {
 		/*
@@ -1042,7 +1105,7 @@ struct_or_union_specifier:
 	}
 ;
 
-/* K&R ---, C90 ---, C99 6.7.2.1, C11 ???, C23 6.7.2.1 */
+/* K&R ---, C90 ---, C99 6.7.2.1, C11 ???, C23 6.7.3.2 */
 struct_or_union:
 	T_STRUCT_OR_UNION {
 		set_sym_kind(SK_TAG);
@@ -1070,7 +1133,7 @@ member_declaration_list_with_rbrace:	/* 
 	}
 ;
 
-/* K&R ???, C90 ???, C99 6.7.2.1, C11 6.7.2.1, C23 6.7.2.1 */
+/* K&R ???, C90 ???, C99 6.7.2.1, C11 6.7.2.1, C23 6.7.3.2 */
 /* Was named struct_declaration_list until C11. */
 member_declaration_list:
 	member_declaration
@@ -1080,7 +1143,7 @@ member_declaration_list:
 ;
 
 /* Was named struct_declaration until C11. */
-/* K&R ???, C90 ???, C99 6.7.2.1, C11 6.7.2.1, C23 6.7.2.1 */
+/* K&R ???, C90 ???, C99 6.7.2.1, C11 6.7.2.1, C23 6.7.3.2 */
 member_declaration:
 	begin_type_qualifier_list end_type {
 		/* ^^ There is no check for the missing type-specifier. */
@@ -1124,6 +1187,13 @@ member_declaration:
 	}
 ;
 
+/* TODO: Implement 'specifier_qualifier_list' from C23 6.7.3.2. */
+
+/* TODO: Implement 'type_specifier_qualifier' from C23 6.7.3.2. */
+
+/* C23 6.7.3.2 */
+/* The rule 'member_declarator_list' is split into the 'type' and 'notype' variants. */
+
 /* Was named struct_declarators until C11. */
 notype_member_declarators:
 	notype_member_declarator {
@@ -1148,6 +1218,9 @@ type_member_declarators:
 	}
 ;
 
+/* C23 6.7.3.2 */
+/* The rule 'member_declarator' is split into the 'type' and 'notype' variants. */
+
 /* Was named struct_declarator until C11. */
 notype_member_declarator:
 	notype_declarator
@@ -1176,7 +1249,7 @@ type_member_declarator:
 	}
 ;
 
-/* K&R ---, C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2 */
+/* K&R ---, C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2, C23 6.7.3.5 */
 enum_specifier:
 	enum gcc_attribute_specifier_list_opt identifier_sym {
 		$$ = make_tag_type($3, ENUM, false, false);
@@ -1226,7 +1299,8 @@ enums_with_opt_comma:		/* helper for C99
 	}
 ;
 
-enumerator_list:		/* C99 6.7.2.2 */
+/* C99 6.7.2.2, C23 6.7.3.3 */
+enumerator_list:
 	enumerator
 |	enumerator_list T_COMMA enumerator {
 		$$ = concat_symbols($1, $3);
@@ -1236,7 +1310,8 @@ enumerator_list:		/* C99 6.7.2.2 */
 	}
 ;
 
-enumerator:			/* C99 6.7.2.2 */
+/* C99 6.7.2.2, C23 6.7.3.3 */
+enumerator:
 	identifier_sym gcc_attribute_specifier_list_opt {
 		$$ = enumeration_constant($1, enumval, true);
 	}
@@ -1247,10 +1322,12 @@ enumerator:			/* C99 6.7.2.2 */
 	}
 ;
 
-type_qualifier:			/* C99 6.7.3 */
-	T_QUAL
-|	atomic {
-		$$ = (type_qualifiers){ .tq_atomic = true };
+/* TODO: Implement 'enum_type_specifier' from C23 6.7.3.3. */
+
+/* K&R ---, C90 ---, C99 ---, C11 6.7.2.4, C23 6.7.3.5 */
+atomic_type_specifier:
+	atomic T_LPAREN type_name T_RPAREN {
+		$$ = $3;
 	}
 ;
 
@@ -1263,75 +1340,24 @@ atomic:				/* helper */
 	}
 ;
 
-pointer:			/* C99 6.7.5 */
-	T_ASTERISK type_qualifier_list_opt {
-		$$ = xcalloc(1, sizeof(*$$));
-		add_type_qualifiers(&$$->qualifiers, $2);
-	}
-|	T_ASTERISK type_qualifier_list_opt pointer {
-		$$ = xcalloc(1, sizeof(*$$));
-		add_type_qualifiers(&$$->qualifiers, $2);
-		$$ = append_qualified_pointer($$, $3);
-	}
-;
+/* TODO: Implement 'typeof_specifier' from C23 6.7.3.6. */
 
-type_qualifier_list_opt:	/* see C99 6.7.5 */
-	/* empty */ {
-		$$ = (type_qualifiers){ .tq_const = false };
-	}
-|	type_qualifier_list
-;
+/* TODO: Implement 'typeof_specifier_argument' from C23 6.7.3.6. */
 
-type_qualifier_list:		/* C99 6.7.5 */
-	type_qualifier
-|	type_qualifier_list type_qualifier {
-		$$ = $1;
-		add_type_qualifiers(&$$, $2);
+/* C99 6.7.3, C23 6.7.4.1 */
+type_qualifier:
+	T_QUAL
+|	atomic {
+		$$ = (type_qualifiers){ .tq_atomic = true };
 	}
 ;
 
-/*
- * For an explanation of 'notype' in the following rules, see
- * https://www.gnu.org/software/bison/manual/bison.html#Semantic-Tokens.
- */
+/* TODO: Implement 'function_specifier' from C23 6.7.5. */
 
-notype_init_declarators:
-	notype_init_declarator
-|	notype_init_declarators T_COMMA type_init_declarator
-;
+/* TODO: Implement 'alignment_specifier' from C23 6.7.6. */
 
-type_init_declarators:
-	type_init_declarator
-|	type_init_declarators T_COMMA type_init_declarator
-;
-
-notype_init_declarator:
-	notype_declarator asm_or_symbolrename_opt {
-		cgram_declare($1, false, $2);
-		check_size($1);
-	}
-|	notype_declarator asm_or_symbolrename_opt {
-		begin_initialization($1);
-		cgram_declare($1, true, $2);
-	} T_ASSIGN initializer {
-		check_size($1);
-		end_initialization();
-	}
-;
-
-type_init_declarator:
-	type_declarator asm_or_symbolrename_opt {
-		cgram_declare($1, false, $2);
-		check_size($1);
-	}
-|	type_declarator asm_or_symbolrename_opt {
-		begin_initialization($1);
-		cgram_declare($1, true, $2);
-	} T_ASSIGN initializer {
-		check_size($1);
-		end_initialization();
-	}
-;
+/* C23 6.7.7.1 */
+/* The rule 'declarator' is split into the 'notype' and 'type' variants. */
 
 notype_declarator:
 	notype_direct_declarator
@@ -1347,6 +1373,9 @@ type_declarator:
 	}
 ;
 
+/* C23 6.7.7.1 */
+/* The rule 'direct_declarator' is split into the 'notype' and 'type' variants. */
+
 notype_direct_declarator:
 	type_attribute_list_opt T_NAME {
 		$$ = declarator_name(getsym($2));
@@ -1383,6 +1412,78 @@ type_direct_declarator:
 |	type_direct_declarator type_attribute
 ;
 
+
+/* TODO: Implement 'array_declarator' from C23 6.7.7.1. */
+
+/* TODO: Implement 'function_declarator' from C23 6.7.7.1. */
+
+/* C99 6.7.5, C23 6.7.7.1 */
+pointer:
+	T_ASTERISK type_qualifier_list_opt {
+		$$ = xcalloc(1, sizeof(*$$));
+		add_type_qualifiers(&$$->qualifiers, $2);
+	}
+|	T_ASTERISK type_qualifier_list_opt pointer {
+		$$ = xcalloc(1, sizeof(*$$));
+		add_type_qualifiers(&$$->qualifiers, $2);
+		$$ = append_qualified_pointer($$, $3);
+	}
+;
+
+/* see C99 6.7.5, C23 6.7.7.1 */
+type_qualifier_list_opt:
+	/* empty */ {
+		$$ = (type_qualifiers){ .tq_const = false };
+	}
+|	type_qualifier_list
+;
+
+/* C99 6.7.5 */
+type_qualifier_list:
+	type_qualifier
+|	type_qualifier_list type_qualifier {
+		$$ = $1;
+		add_type_qualifiers(&$$, $2);
+	}
+;
+
+/* TODO: Implement 'parameter_type_list' from C23 6.7.7.1. */
+
+/* TODO: Implement 'parameter_list' from C23 6.7.7.1. */
+
+/* C23 6.7.7.1 */
+/* XXX: C99 6.7.5 defines the same name, but it looks completely different. */
+parameter_declaration:
+	begin_type_declmods end_type {
+		/* ^^ There is no check for the missing type-specifier. */
+		$$ = declare_parameter(abstract_name(), false);
+	}
+|	begin_type_declaration_specifiers end_type {
+		$$ = declare_parameter(abstract_name(), false);
+	}
+|	begin_type_declmods end_type notype_param_declarator {
+		/* ^^ There is no check for the missing type-specifier. */
+		$$ = declare_parameter($3, false);
+	}
+	/*
+	 * type_param_declarator is needed because of following conflict:
+	 * "typedef int a; f(int (a));" could be parsed as
+	 * "function with argument a of type int", or
+	 * "function with an unnamed (abstract) argument of type function".
+	 * This grammar realizes the second case.
+	 */
+|	begin_type_declaration_specifiers end_type type_param_declarator {
+		$$ = declare_parameter($3, false);
+	}
+|	begin_type_declmods end_type abstract_declarator {
+		/* ^^ There is no check for the missing type-specifier. */
+		$$ = declare_parameter($3, false);
+	}
+|	begin_type_declaration_specifiers end_type abstract_declarator {
+		$$ = declare_parameter($3, false);
+	}
+;
+
 /*
  * The two distinct rules type_param_declarator and notype_param_declarator
  * avoid a conflict in parameter lists. A typename enclosed in parentheses is
@@ -1495,8 +1596,9 @@ identifier_list:		/* C99 6.7.5 */
 |	identifier_list error
 ;
 
+/* C99 6.7.6, C23 6.7.8 */
 /* XXX: C99 requires an additional specifier-qualifier-list. */
-type_name:			/* C99 6.7.6 */
+type_name:
 	{
 		begin_declaration_level(DLK_ABSTRACT);
 	} abstract_declaration {
@@ -1520,51 +1622,6 @@ abstract_declaration:		/* specific to li
 	}
 ;
 
-/* K&R 8.7, C90 ???, C99 6.7.6, C11 6.7.7 */
-/* In K&R, abstract-declarator could be empty and was still simpler. */
-abstract_declarator:
-	pointer {
-		$$ = add_pointer(abstract_name(), $1);
-	}
-|	direct_abstract_declarator
-|	pointer direct_abstract_declarator {
-		$$ = add_pointer($2, $1);
-	}
-|	type_attribute_list direct_abstract_declarator {
-		$$ = $2;
-	}
-|	pointer type_attribute_list direct_abstract_declarator {
-		$$ = add_pointer($3, $1);
-	}
-;
-
-/* K&R ---, C90 ???, C99 6.7.6, C11 6.7.7 */
-direct_abstract_declarator:
-	/* TODO: sort rules according to C99 */
-	T_LPAREN abstract_declarator T_RPAREN {
-		$$ = $2;
-	}
-|	T_LBRACK array_size_opt T_RBRACK {
-		$$ = add_array(abstract_name(), $2.has_dim, $2.dim);
-	}
-|	direct_abstract_declarator T_LBRACK array_size_opt T_RBRACK {
-		$$ = add_array($1, $3.has_dim, $3.dim);
-	}
-|	abstract_decl_param_list asm_or_symbolrename_opt {
-		sym_t *name = abstract_enclosing_name();
-		$$ = add_function(symbolrename(name, $2), $1);
-		end_declaration_level();
-		block_level--;
-	}
-|	direct_abstract_declarator abstract_decl_param_list
-	    asm_or_symbolrename_opt {
-		$$ = add_function(symbolrename($1, $3), $2);
-		end_declaration_level();
-		block_level--;
-	}
-|	direct_abstract_declarator type_attribute_list
-;
-
 abstract_decl_param_list:	/* specific to lint */
 	abstract_decl_lparen T_RPAREN type_attribute_opt {
 		$$ = (parameter_list){ .first = NULL };
@@ -1615,50 +1672,70 @@ parameter_type_list:
 	}
 ;
 
-/* XXX: C99 6.7.5 defines the same name, but it looks completely different. */
-parameter_declaration:
-	begin_type_declmods end_type {
-		/* ^^ There is no check for the missing type-specifier. */
-		$$ = declare_parameter(abstract_name(), false);
+/* K&R 8.7, C90 ???, C99 6.7.6, C11 6.7.7, C23 6.7.8 */
+/* In K&R, abstract-declarator could be empty and was still simpler. */
+abstract_declarator:
+	pointer {
+		$$ = add_pointer(abstract_name(), $1);
 	}
-|	begin_type_declaration_specifiers end_type {
-		$$ = declare_parameter(abstract_name(), false);
+|	direct_abstract_declarator
+|	pointer direct_abstract_declarator {
+		$$ = add_pointer($2, $1);
 	}
-|	begin_type_declmods end_type notype_param_declarator {
-		/* ^^ There is no check for the missing type-specifier. */
-		$$ = declare_parameter($3, false);
+|	type_attribute_list direct_abstract_declarator {
+		$$ = $2;
 	}
-	/*
-	 * type_param_declarator is needed because of following conflict:
-	 * "typedef int a; f(int (a));" could be parsed as
-	 * "function with argument a of type int", or
-	 * "function with an unnamed (abstract) argument of type function".
-	 * This grammar realizes the second case.
-	 */
-|	begin_type_declaration_specifiers end_type type_param_declarator {
-		$$ = declare_parameter($3, false);
+|	pointer type_attribute_list direct_abstract_declarator {
+		$$ = add_pointer($3, $1);
 	}
-|	begin_type_declmods end_type abstract_declarator {
-		/* ^^ There is no check for the missing type-specifier. */
-		$$ = declare_parameter($3, false);
+;
+
+/* K&R ---, C90 ???, C99 6.7.6, C11 6.7.7, C23 6.7.8 */
+direct_abstract_declarator:
+	/* TODO: sort rules according to C99 */
+	T_LPAREN abstract_declarator T_RPAREN {
+		$$ = $2;
 	}
-|	begin_type_declaration_specifiers end_type abstract_declarator {
-		$$ = declare_parameter($3, false);
+|	T_LBRACK array_size_opt T_RBRACK {
+		$$ = add_array(abstract_name(), $2.has_dim, $2.dim);
 	}
+|	direct_abstract_declarator T_LBRACK array_size_opt T_RBRACK {
+		$$ = add_array($1, $3.has_dim, $3.dim);
+	}
+|	abstract_decl_param_list asm_or_symbolrename_opt {
+		sym_t *name = abstract_enclosing_name();
+		$$ = add_function(symbolrename(name, $2), $1);
+		end_declaration_level();
+		block_level--;
+	}
+|	direct_abstract_declarator abstract_decl_param_list
+	    asm_or_symbolrename_opt {
+		$$ = add_function(symbolrename($1, $3), $2);
+		end_declaration_level();
+		block_level--;
+	}
+|	direct_abstract_declarator type_attribute_list
 ;
 
+/* TODO: Implement 'array_abstract_declarator' from C23 6.7.8. */
+
+/* TODO: Implement 'function_abstract_declarator' from C23 6.7.8. */
+
+/* TODO: Implement 'typedef_name' from C23 6.7.9. */
+
+/* C23 6.7.11 */
+/* K&R ---, C90 ---, C99 6.7.8, C11 6.7.9, C23 6.7.10 */
 braced_initializer:
-	/* K&R ---, C90 ---, C99 ---, C11 ---, C23 6.7.10 */
 	init_lbrace init_rbrace {
 		/* empty initializer braces require C23 or later */
 		c23ism(353);
 	}
-	/* K&R ---, C90 ---, C99 6.7.8, C11 6.7.9, C23 6.7.10 */
 |	init_lbrace initializer_list init_rbrace
 |	init_lbrace initializer_list T_COMMA init_rbrace
 ;
 
-initializer:			/* C99 6.7.8 "Initialization" */
+/* C99 6.7.8, C23 6.7.11 */
+initializer:
 	assignment_expression {
 		init_expr($1);
 	}
@@ -1671,14 +1748,16 @@ initializer:			/* C99 6.7.8 "Initializat
 |	error
 ;
 
-initializer_list:		/* C99 6.7.8 "Initialization" */
+/* C99 6.7.8, C23 6.7.11 */
+initializer_list:
 	initializer
 |	designation initializer
 |	initializer_list T_COMMA initializer
 |	initializer_list T_COMMA designation initializer
 ;
 
-designation:			/* C99 6.7.8 "Initialization" */
+/* C99 6.7.8, C23 6.7.11 */
+designation:
 	{
 		begin_designation();
 	} designator_list T_ASSIGN
@@ -1690,12 +1769,14 @@ designation:			/* C99 6.7.8 "Initializat
 	}
 ;
 
-designator_list:		/* C99 6.7.8 "Initialization" */
+/* C99 6.7.8, C23 6.7.11 */
+designator_list:
 	designator
 |	designator_list designator
 ;
 
-designator:			/* C99 6.7.8 "Initialization" */
+/* C99 6.7.8, C23 6.7.11 */
+designator:
 	T_LBRACK range T_RBRACK {
 		if (!allow_c99)
 			/* array initializer with designators is a C99 ... */
@@ -1710,6 +1791,7 @@ designator:			/* C99 6.7.8 "Initializati
 	}
 ;
 
+/* C23 6.7.12 */
 static_assert_declaration:
 	T_STATIC_ASSERT T_LPAREN constant_expression T_COMMA T_STRING
 	    T_RPAREN T_SEMI {
@@ -1747,6 +1829,28 @@ init_rbrace:			/* helper */
 	}
 ;
 
+/* TODO: Implement 'attribute_specifier_sequence' from C23 6.7.13.2. */
+
+/* TODO: Implement 'attribute_specifier' from C23 6.7.13.2. */
+
+/* TODO: Implement 'attribute_list' from C23 6.7.13.2. */
+
+/* TODO: Implement 'attribute' from C23 6.7.13.2. */
+
+/* TODO: Implement 'attribute_token' from C23 6.7.13.2. */
+
+/* TODO: Implement 'standard_attribute' from C23 6.7.13.2. */
+
+/* TODO: Implement 'attribute_prefixed_token' from C23 6.7.13.2. */
+
+/* TODO: Implement 'attribute_prefix' from C23 6.7.13.2. */
+
+/* TODO: Implement 'attribute_argument_clause' from C23 6.7.13.2. */
+
+/* TODO: Implement 'balanced_token_sequence' from C23 6.7.13.2. */
+
+/* TODO: Implement 'balanced_token' from C23 6.7.13.2. */
+
 asm_or_symbolrename_opt:	/* GCC extensions */
 	/* empty */ {
 		$$ = NULL;
@@ -1761,7 +1865,7 @@ asm_or_symbolrename_opt:	/* GCC extensio
 	}
 ;
 
-/* K&R ???, C90 ???, C99 6.8, C11 ???, C23 6.8 */
+/* K&R ???, C90 ???, C99 6.8, C11 ???, C23 6.8.1 */
 statement:
 	expression_statement
 |	non_expr_statement
@@ -1790,10 +1894,13 @@ no_attr_non_expr_statement:
 |	asm_statement
 ;
 
-labeled_statement:		/* C99 6.8.1 */
-	label gcc_attribute_specifier_list_opt no_attr_statement
-;
+/* TODO: Implement 'unlabeled_statement' from C23 6.8.1. */
+
+/* TODO: Implement 'primary_block' from C23 6.8.1. */
 
+/* TODO: Implement 'secondary_block' from C23 6.8.1. */
+
+/* C23 6.8.2 */
 label:
 	T_NAME T_COLON {
 		set_sym_kind(SK_LABEL);
@@ -1814,7 +1921,13 @@ label:
 	}
 ;
 
-compound_statement:		/* C99 6.8.2 */
+/* C99 6.8.1, C23 6.8.2 */
+labeled_statement:
+	label gcc_attribute_specifier_list_opt no_attr_statement
+;
+
+/* C99 6.8.2, C23 6.8.3 */
+compound_statement:
 	compound_statement_lbrace compound_statement_rbrace
 |	compound_statement_lbrace block_item_list compound_statement_rbrace
 ;
@@ -1842,7 +1955,8 @@ compound_statement_rbrace:
 	}
 ;
 
-block_item_list:		/* C99 6.8.2 */
+/* C99 6.8.2, C23 6.8.3 */
+block_item_list:
 	block_item
 |	block_item_list block_item {
 		if ($1 && !$2)
@@ -1852,7 +1966,8 @@ block_item_list:		/* C99 6.8.2 */
 	}
 ;
 
-block_item:			/* C99 6.8.2 */
+/* C99 6.8.2, C23 6.8.3 */
+block_item:
 	declaration_or_error {
 		$$ = false;
 		restore_warning_flags();
@@ -1863,7 +1978,8 @@ block_item:			/* C99 6.8.2 */
 	}
 ;
 
-expression_statement:		/* C99 6.8.3 */
+/* C99 6.8.3, C23 6.8.4 */
+expression_statement:
 	expression T_SEMI {
 		expr($1, false, false, false, false);
 		suppress_fallthrough = false;
@@ -1874,7 +1990,8 @@ expression_statement:		/* C99 6.8.3 */
 	}
 ;
 
-selection_statement:		/* C99 6.8.4 */
+/* C99 6.8.4, C23 6.8.5.1 */
+selection_statement:
 	if_without_else %prec T_THEN {
 		save_warning_flags();
 		stmt_if_then_stmt();
@@ -1920,7 +2037,8 @@ switch_expr:			/* see C99 6.8.4 */
 	}
 ;
 
-iteration_statement:		/* C99 6.8.5 */
+/* C99 6.8.5, C23 6.8.6.1 */
+iteration_statement:
 	while_expr statement {
 		clear_warning_flags();
 		stmt_while_expr_stmt();
@@ -1997,7 +2115,8 @@ for_exprs:			/* see C99 6.8.5 */
 	}
 ;
 
-jump_statement:			/* C99 6.8.6 */
+/* C99 6.8.6, C23 6.8.7.1 */
+jump_statement:
 	goto identifier T_SEMI {
 		stmt_goto(getsym($2));
 	}
@@ -2040,12 +2159,14 @@ read_until_rparen:		/* helper for 'asm_s
 	}
 ;
 
-translation_unit:		/* C99 6.9 */
+/* C99 6.9, C23 6.9.1 */
+translation_unit:
 	external_declaration
 |	translation_unit external_declaration
 ;
 
-external_declaration:		/* C99 6.9 */
+/* C99 6.9, C23 6.9.1 */
+external_declaration:
 	function_definition {
 		global_clean_up_decl(false);
 		clear_warning_flags();
@@ -2097,7 +2218,8 @@ top_level_declaration:		/* C99 6.9 calls
 	}
 ;
 
-function_definition:		/* C99 6.9.1 */
+/* C99 6.9.1, C23 6.9.2 */
+function_definition:
 	func_declarator {
 		if ($1->s_type->t_tspec != FUNC) {
 			/* syntax error '%s' */
@@ -2234,6 +2356,8 @@ gcc_attribute:
 	}
 ;
 
+/* The rule 'function_body' from C23 6.9.2 is inlined into 'function_definition'. */
+
 sys:
 	/* empty */ {
 		$$ = in_system_header;

Reply via email to