From: Nick Bowler Date: Thu, 20 Jul 2023 00:28:59 +0000 (-0400) Subject: libcdecl: Factor out open-coded list concatenation. X-Git-Tag: v1.3~111 X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/commitdiff_plain/032fe50c0297846a8d03eda505c9726f60a46501 libcdecl: Factor out open-coded list concatenation. The parser has two rules which join two lists. Let's add a helper to do that instead of duplicating the code for list concatenation. Furthermore, in both cases one of the lists is known to be nonempty; the implementation can be slightly simplified with that assumption. --- diff --git a/src/parse.y b/src/parse.y index abfccd2..cf24b25 100644 --- a/src/parse.y +++ b/src/parse.y @@ -142,6 +142,19 @@ void cdecl__free(struct cdecl *decl) { free_decl(decl); } + +/* + * Join two declaration specifier lists into a single list, with "a" being the + * head of the new list. + * + * The list "a" is assumed to be nonempty. + */ +static void join_specs(struct cdecl_declspec *a, struct cdecl_declspec *b) +{ + while (a->next) + a = a->next; + a->next = b; +} %} %destructor { free($$); } @@ -467,27 +480,16 @@ 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; - $$->next = $1; - for (struct cdecl_declspec *s = $$; s; s = s->next) { - if (!s->next) { - s->next = $3; - break; - } - } } english_declaration: storage_func_specs english_declarator post_specs { + join_specs($3, $1); ALLOC_STRUCT($$, struct cdecl, .specifiers = $3, .declarators = $2); - - for (struct cdecl_declspec *s = $$->specifiers; s; s = s->next) { - if (!s->next) { - s->next = $1; - break; - } - } } english_declarator: {