grammar: preserve token declaration order

In a declaration %token A B, the token A is declared before B, but in %left
A B (or with %precedence or %nonassoc or %right), the token B was declared
before A (tokens were declared in reverse order).

* src/symlist.h, src/symlist.c (symbol_list_append): New.
* src/parse-gram.y: Use it instead of symbol_list_prepend.
* tests/input.at: Adjust expectations.
This commit is contained in:
Valentin Tolmer
2013-01-25 11:12:47 +01:00
committed by Akim Demaille
parent 9b3bb25885
commit 93561c21e8
5 changed files with 33 additions and 7 deletions

6
NEWS
View File

@@ -289,6 +289,12 @@ GNU Bison NEWS
It used to be an error only if used in non GLR mode, _and_ if there are
reduce/reduce conflicts.
** Token numbering has changed to preserve the user-defined order
When declaring %token A B, the numbering for A is inferior to B. Up to now,
when declaring associativity at the same time, with %left (or %right,
%precedence, %nonassoc), B was inferior to A.
* Noteworthy changes in release 2.7 (2012-12-12) [stable]
** Bug fixes

View File

@@ -503,7 +503,7 @@ symbols.prec:
symbol.prec
{ $$ = symbol_list_sym_new ($1, @1); }
| symbols.prec symbol.prec
{ $$ = symbol_list_prepend ($1, symbol_list_sym_new ($2, @2)); }
{ $$ = symbol_list_append ($1, symbol_list_sym_new ($2, @2)); }
;
symbol.prec:
@@ -516,12 +516,12 @@ symbols.1:
symbol
{ $$ = symbol_list_sym_new ($1, @1); }
| symbols.1 symbol
{ $$ = symbol_list_prepend ($1, symbol_list_sym_new ($2, @2)); }
{ $$ = symbol_list_append ($1, symbol_list_sym_new ($2, @2)); }
;
generic_symlist:
generic_symlist_item { $$ = $1; }
| generic_symlist generic_symlist_item { $$ = symbol_list_prepend ($1, $2); }
| generic_symlist generic_symlist_item { $$ = symbol_list_append ($1, $2); }
;
generic_symlist_item:

View File

@@ -107,6 +107,23 @@ symbol_list_prepend (symbol_list *list, symbol_list *node)
}
/*-------------------------.
| Append NODE to the LIST. |
`-------------------------*/
symbol_list *
symbol_list_append (symbol_list *list, symbol_list *node)
{
if (!list)
return node;
symbol_list *next = list;
while (next->next)
next = next->next;
next->next = node;
return list;
}
/*-----------------------------------------------.
| Free the LIST, but not the items it contains. |
`-----------------------------------------------*/

View File

@@ -97,6 +97,9 @@ void symbol_list_syms_print (const symbol_list *l, FILE *f);
/** Prepend \c node to \c list. */
symbol_list *symbol_list_prepend (symbol_list *list, symbol_list *node);
/** Append \c node to \c list. */
symbol_list *symbol_list_append (symbol_list *list, symbol_list *node);
/** Free \c list, but not the items it contains. */
void symbol_list_free (symbol_list *list);

View File

@@ -445,14 +445,14 @@ input.y:5.10-24: error: %printer redeclaration for <field2>
input.y:2.10-24: previous declaration
input.y:5.10-24: error: %printer redeclaration for <field2>
input.y:5.10-24: previous declaration
input.y:11.13-29: error: %destructor redeclaration for <field1>
input.y:4.13-29: previous declaration
input.y:11.13-29: error: %destructor redeclaration for <field2>
input.y:1.13-29: previous declaration
input.y:12.10-24: error: %printer redeclaration for <field1>
input.y:2.10-24: previous declaration
input.y:11.13-29: error: %destructor redeclaration for <field1>
input.y:4.13-29: previous declaration
input.y:12.10-24: error: %printer redeclaration for <field2>
input.y:5.10-24: previous declaration
input.y:12.10-24: error: %printer redeclaration for <field1>
input.y:2.10-24: previous declaration
]])
AT_CLEANUP