]> git.draconx.ca Git - cdecl99.git/blobdiff - src/parse.y
libcdecl: Factor out toplevel parser actions.
[cdecl99.git] / src / parse.y
index 8631f3b4613fd028b720865f4b85ed03237c3384..f8c960817a31a671ba3e5bd34b462ed452ed4234 100644 (file)
@@ -105,6 +105,7 @@ static void free_declarator(struct cdecl_declarator *x)
 
                switch (x->type) {
                case CDECL_DECL_NULL:
+                       x = NULL;
                case CDECL_DECL_IDENT:
                case CDECL_DECL_ARRAY:
                        break;
@@ -168,11 +169,18 @@ static struct cdecl *insert_identifier(struct cdecl *decl, struct parse_item *id
 
        while ((d = *p)->child)
                p = &d->child;
-       free(d);
 
-       *p = d = &ident->u.declarator;
+       *p = &ident->u.declarator;
        return decl;
 }
+
+static struct cdecl_declarator *nulldecl(void)
+{
+       static const struct cdecl_declarator nulldecl = {0};
+       return (void *)&nulldecl;
+}
+#define NULLDECL (nulldecl())
+
 %}
 
 %destructor { free($$); }            <item>
@@ -248,16 +256,14 @@ static struct cdecl *insert_identifier(struct cdecl *decl, struct parse_item *id
 %type <declspec>   declspecs declspecs_noid
 %type <declarator> direct_declarator declarator pointer array parens postfix
 %type <declarator> direct_declarator_ish declarator_ish parameter_type_list
-%type <decl>       declaration declarators declarator_wrap
-%type <decl>       parameter
+%type <decl>       cdecl declaration declarators declarator_wrap parameter
 
 %type <item>       english_vla
 %type <declspec>   storage_func_specs post_specs
 %type <declspec>   type_qual_spec type_qual_specs typedef_name_qual
 %type <declarator> english_declarator english_array english_function
 %type <declarator> english_parameter_list null_decl
-%type <decl>       english english_declaration
-%type <decl>       english_parameter
+%type <decl>       english english_declaration english_parameter
 
 /* Precedence declaration to avoid conflict in english_parameter; see below. */
 %right T_TYPE
@@ -265,14 +271,10 @@ static struct cdecl *insert_identifier(struct cdecl *decl, struct parse_item *id
 
 %%
 
-input: english {
-       *out = $1;
-} | declaration {
-       *out = $1;
-};
+input: cdecl { *out = $1; }
+cdecl: english | declaration
 
 semi: | T_SEMICOLON
-
 declaration: declspecs declarators semi {
        $$ = $2;
        $$->specifiers = $1;
@@ -431,16 +433,14 @@ declarator_ish: direct_declarator_ish | pointer
 postfix: array | parens
 
 direct_declarator_ish: {
-       ALLOC_STRUCT($$, struct cdecl_declarator,
-               .type = CDECL_DECL_NULL);
+       $$ = NULLDECL;
 } | direct_declarator_ish postfix {
        $$ = $2;
        $$->child = $1;
 }
 
 direct_declarator: {
-       ALLOC_STRUCT($$, struct cdecl_declarator,
-               .type = CDECL_DECL_NULL);
+       $$ = NULLDECL;
 } | T_IDENT {
        $$ = &$1->u.declarator;
 } | direct_declarator postfix {
@@ -491,8 +491,7 @@ english_declaration: storage_func_specs english_declarator post_specs {
 }
 
 english_declarator: {
-       ALLOC_STRUCT($$, struct cdecl_declarator,
-               .type = CDECL_DECL_NULL);
+       $$ = NULLDECL;
 } | english_declarator qualifiers T_POINTER T_TO {
        ALLOC_STRUCT($$, struct cdecl_declarator,
                .type = CDECL_DECL_POINTER,
@@ -535,8 +534,7 @@ typedef_name_qual: T_IDENT qualifiers {
 }
 
 null_decl: {
-       ALLOC_STRUCT($$, struct cdecl_declarator,
-               .type = CDECL_DECL_NULL);
+       $$ = NULLDECL;
 }
 
 /*