X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/blobdiff_plain/4423b55b49e402ca3ac13a6430c23a6629da9bf4..a118e977106144aa753045c59e9f5278facc48d7:/src/parse.y diff --git a/src/parse.y b/src/parse.y index 6d349f7..3a17b99 100644 --- a/src/parse.y +++ b/src/parse.y @@ -211,6 +211,21 @@ static void join_specs(struct cdecl_declspec *a, struct cdecl_declspec *b) a->next = b; } +/* + * Join three specifier lists into a single list, and returns the head of + * the new list. + * + * The list "b" is assumed to be a singleton list. + */ +static struct cdecl_declspec *join_specs3(struct cdecl_declspec *a, + struct cdecl_declspec *b, + struct cdecl_declspec *c) +{ + b->next = c; + join_specs(b, a); + return b; +} + /* * Alter an abstract declarator (type name) to declare an identifier instead, * used by the English parser rules to reduce "identifier as type" sequences. @@ -305,7 +320,7 @@ static struct cdecl_declarator *nulldecl(void) %type typespec_simple typespec_tagged %type declspec_notype declspec_noid typespec_noid typespec %type qualifier qualifiers -%type declspecs declspecs_noid +%type declspecs declspecs_notype declspecs_noid %type direct_declarator declarator pointer array parens postfix %type direct_declarator_ish declarator_ish parameter_type_list %type cdecl declaration declarators declarator_wrap parameter @@ -348,17 +363,18 @@ declaration: declspecs declarators semi { * unexpected parses; libcdecl applies a simplification step to the resulting * parse tree afterwards. */ -declspecs: declspec_notype declspecs { - $$ = $1; - $$->next = $2; -} | typespec declspecs_noid { - $$ = $1; - $$->next = $2; +declspecs: declspecs_notype typespec declspecs_noid { + $$ = join_specs3($1, $2, $3); } -declspecs_noid: { $$ = NULL; } | declspec_noid declspecs_noid { - $$ = $1; - $$->next = $2; +declspecs_notype: { $$ = NULL; } | declspecs_notype declspec_notype { + $$ = $2; + $$->next = $1; +} + +declspecs_noid: { $$ = NULL; } | declspecs_noid declspec_noid { + $$ = $2; + $$->next = $1; } qualifiers: { $$ = NULL; } | qualifiers qualifier { @@ -490,16 +506,16 @@ english: T_DECLARE T_IDENT T_AS english_declaration { * over reducing this empty rule; see below. */ storage_func_specs: %prec T_TYPE { $$ = NULL; } -storage_func_specs: declspec_simple storage_func_specs { - ALLOC_DECLSPEC($$, $1); - $$->next = $2; +storage_func_specs: storage_func_specs declspec_simple { + ALLOC_DECLSPEC($$, $2); + $$->next = $1; } type_qual_spec: typespec_noid | qualifier -type_qual_specs: { $$ = NULL; } | type_qual_spec type_qual_specs { - $$ = $1; - $$->next = $2; +type_qual_specs: { $$ = NULL; } | type_qual_specs type_qual_spec { + $$ = $2; + $$->next = $1; } /* @@ -508,9 +524,7 @@ type_qual_specs: { $$ = NULL; } | type_qual_spec type_qual_specs { * together three different specifiers lists. */ post_specs: qualifiers typespec type_qual_specs { - $2->next = $3; - join_specs($2, $1); - $$ = $2; + $$ = join_specs3($1, $2, $3); } english_declaration: storage_func_specs english_declarator post_specs {