]> git.draconx.ca Git - cdecl99.git/blobdiff - src/parse.y
libcdecl: Fix parsing of very long declarator lists.
[cdecl99.git] / src / parse.y
index 3a17b998babf5cabc1bc5cfb6e76278304da74f8..0a12f3f9e7aa6cdeacaba331afd5785bc7d9da35 100644 (file)
@@ -226,11 +226,29 @@ static struct cdecl_declspec *join_specs3(struct cdecl_declspec *a,
        return b;
 }
 
+/*
+ * Reverse the order of a "struct cdecl" list, and return the new first
+ * element of the list (i.e., the last element of the original list).
+ */
+static struct cdecl *reverse_decls(struct cdecl *decl)
+{
+       struct cdecl *prev, *next;
+
+       for (prev = NULL; decl; decl = next) {
+               next = decl->next;
+               decl->next = prev;
+               prev = decl;
+       }
+
+       return prev;
+}
+
 /*
  * Alter an abstract declarator (type name) to declare an identifier instead,
  * used by the English parser rules to reduce "identifier as type" sequences.
  */
-static struct cdecl *insert_identifier(struct cdecl *decl, struct parse_item *ident)
+static struct cdecl *
+insert_identifier(struct cdecl *decl, struct parse_item *ident)
 {
        struct cdecl_declarator *d, **p = &decl->declarators;
 
@@ -343,7 +361,7 @@ cdecl: english | declaration
 
 semi: | T_SEMICOLON
 declaration: declspecs declarators semi {
-       $$ = $2;
+       $$ = reverse_decls($2);
        $$->specifiers = $1;
 };
 
@@ -382,9 +400,9 @@ qualifiers: { $$ = NULL; } | qualifiers qualifier {
        $$->next = $1;
 }
 
-declarators: declarator_wrap | declarator_wrap T_COMMA declarators {
-       $$ = $1;
-       $$->next = $3;
+declarators: declarator_wrap | declarators T_COMMA declarator_wrap {
+       $$ = $3;
+       $$->next = $1;
 }
 
 declarator_wrap: declarator {