]> git.draconx.ca Git - cdecl99.git/commitdiff
libcdecl: Factor out open-coded list concatenation.
authorNick Bowler <nbowler@draconx.ca>
Thu, 20 Jul 2023 00:28:59 +0000 (20:28 -0400)
committerNick Bowler <nbowler@draconx.ca>
Thu, 20 Jul 2023 00:28:59 +0000 (20:28 -0400)
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.

src/parse.y

index abfccd20a5accb80404c9e5d399eb528742552da..cf24b25ae73d1e3377bc8804b492bb10d118f817 100644 (file)
@@ -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($$); }            <strval>
@@ -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: {