diff --git a/b2/lang.y b/b2/lang.y index 91d18d6..b1e87c3 100644 --- a/b2/lang.y +++ b/b2/lang.y @@ -50,14 +50,18 @@ static void push_field(const struct field *field) } -static void pop_field(void) +static void pop_fields(const struct field *last) { struct field_stack *entry; + const struct field *popped; - assert(field_stack); - entry = field_stack; - field_stack = entry->next; - free(entry); + do { + assert(field_stack); + entry = field_stack; + popped = entry->field; + field_stack = entry->next; + free(entry); + } while (popped != last); } @@ -241,7 +245,7 @@ rule: $$->any = $5; $$->next = NULL; field_finalize($$); - pop_field(); + pop_fields($$); } ; @@ -290,13 +294,14 @@ opt_wildcard: action: { + $$ = (struct field *) top_field(); push_field(top_field()); } opt_fields opt_rule ';' { $$.fields = $2; $$.rules = $3; - pop_field(); + pop_fields($1); } ; @@ -349,14 +354,13 @@ fields: } | field { + $1->prev = top_field(); push_field($1); } fields { $$ = $1; $$->next = $3; - pop_field(); - $$->prev = top_field(); if ($3) $3->prev = $1; }