mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 20:33:03 +00:00
Don't apply the default %destructor/%printer to an unreferenced midrule
value. Mentioned at <http://lists.gnu.org/archive/html/bison-patches/2006-09/msg00104.html>. * src/symtab.c (dummy_symbol_get): Name all dummy symbols initially like $@n instead of just @n so that the default %destructor/%printer logic doesn't see them as user-defined symbols. (symbol_is_dummy): Check for both forms of the name. * src/reader.c (packgram): Remove the `$' from each midrule symbol name for which the midrule value is referenced in any action. * tests/actions.at (Default %printer and %destructor for mid-rule values): New test. * tests/regression.at (Rule Line Numbers, Web2c Report): Update output for change to dummy symbol names.
This commit is contained in:
16
ChangeLog
16
ChangeLog
@@ -1,3 +1,19 @@
|
||||
2006-10-21 Joel E. Denny <jdenny@ces.clemson.edu>
|
||||
|
||||
Don't apply the default %destructor/%printer to an unreferenced midrule
|
||||
value. Mentioned at
|
||||
<http://lists.gnu.org/archive/html/bison-patches/2006-09/msg00104.html>.
|
||||
* src/symtab.c (dummy_symbol_get): Name all dummy symbols initially
|
||||
like $@n instead of just @n so that the default %destructor/%printer
|
||||
logic doesn't see them as user-defined symbols.
|
||||
(symbol_is_dummy): Check for both forms of the name.
|
||||
* src/reader.c (packgram): Remove the `$' from each midrule symbol
|
||||
name for which the midrule value is referenced in any action.
|
||||
* tests/actions.at (Default %printer and %destructor for mid-rule
|
||||
values): New test.
|
||||
* tests/regression.at (Rule Line Numbers, Web2c Report): Update output
|
||||
for change to dummy symbol names.
|
||||
|
||||
2006-10-20 Joel E. Denny <jdenny@ces.clemson.edu>
|
||||
|
||||
Warn about unset midrule $$ if the corresponding $n is used.
|
||||
|
||||
20
src/reader.c
20
src/reader.c
@@ -459,11 +459,12 @@ packgram (void)
|
||||
|
||||
rules = xnmalloc (nrules, sizeof *rules);
|
||||
|
||||
/* Before invoking grammar_rule_check on any rule, make sure
|
||||
all actions have already been scanned in order to set `used' flags.
|
||||
Otherwise, checking that a midrule's $$ is set will not always work
|
||||
properly because the midrule check must forward-reference the midrule's
|
||||
parent rule. */
|
||||
/* Before invoking grammar_rule_check on any rule, make sure all actions have
|
||||
already been scanned in order to set `used' flags. Otherwise, checking
|
||||
that a midrule's $$ should be set will not always work properly because
|
||||
the check must forward-reference the midrule's parent rule. For the same
|
||||
reason, all the `used' flags must be set before checking whether to remove
|
||||
`$' from any midrule symbol name. */
|
||||
while (p)
|
||||
{
|
||||
if (p->action)
|
||||
@@ -492,6 +493,15 @@ packgram (void)
|
||||
rules[ruleno].action = p->action;
|
||||
rules[ruleno].action_location = p->action_location;
|
||||
|
||||
/* If the midrule's $$ is set or its $n is used, remove the `$' from the
|
||||
symbol name so that it's a user-defined symbol so that the default
|
||||
%destructor and %printer apply. */
|
||||
if (p->midrule_parent_rule
|
||||
&& (p->used
|
||||
|| symbol_list_n_get (p->midrule_parent_rule,
|
||||
p->midrule_parent_rhs_index)->used))
|
||||
p->content.sym->tag += 1;
|
||||
|
||||
/* Don't check the generated rule 0. It has no action, so some rhs
|
||||
symbols may appear unused, but the parsing algorithm ensures that
|
||||
%destructor's are invoked appropriately. */
|
||||
|
||||
@@ -769,7 +769,7 @@ dummy_symbol_get (location loc)
|
||||
|
||||
symbol *sym;
|
||||
|
||||
sprintf (buf, "@%d", ++dummy_count);
|
||||
sprintf (buf, "$@%d", ++dummy_count);
|
||||
sym = symbol_get (buf, loc);
|
||||
sym->class = nterm_sym;
|
||||
sym->number = nvars++;
|
||||
@@ -779,7 +779,7 @@ dummy_symbol_get (location loc)
|
||||
bool
|
||||
symbol_is_dummy (const symbol *sym)
|
||||
{
|
||||
return sym->tag[0] == '@';
|
||||
return sym->tag[0] == '@' || (sym->tag[0] == '$' && sym->tag[1] == '@');
|
||||
}
|
||||
|
||||
/*-------------------.
|
||||
|
||||
105
tests/actions.at
105
tests/actions.at
@@ -1096,3 +1096,108 @@ AT_CHECK([bison -o input.c input.y])
|
||||
AT_COMPILE([input])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
|
||||
## ------------------------------------------------------ ##
|
||||
## Default %printer and %destructor for mid-rule values. ##
|
||||
## ------------------------------------------------------ ##
|
||||
|
||||
AT_SETUP([Default %printer and %destructor for mid-rule values])
|
||||
|
||||
AT_DATA_GRAMMAR([[input.y]],
|
||||
[[%debug /* So that %printer is actually compiled. */
|
||||
|
||||
%{
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
static void yyerror (const char *msg);
|
||||
static int yylex (void);
|
||||
# define USE(SYM)
|
||||
# define YYLTYPE int
|
||||
# define YYLLOC_DEFAULT(Current, Rhs, N)
|
||||
# define YY_LOCATION_PRINT(File, Loc)
|
||||
%}
|
||||
|
||||
%printer { fprintf (yyoutput, "%d", @$); } %symbol-default
|
||||
%destructor { fprintf (stderr, "DESTROY %d\n", @$); } %symbol-default
|
||||
|
||||
%%
|
||||
|
||||
start:
|
||||
{ @$ = 1; } // Not set or used.
|
||||
{ USE ($$); @$ = 2; } // Both set and used.
|
||||
{ USE ($$); @$ = 3; } // Only set.
|
||||
{ @$ = 4; } // Only used.
|
||||
'c'
|
||||
{ USE (($$, $2, $4, $5)); @$ = 0; }
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
static int
|
||||
yylex (void)
|
||||
{
|
||||
static int called;
|
||||
if (called++)
|
||||
abort ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
yyerror (const char *msg)
|
||||
{
|
||||
fprintf (stderr, "%s\n", msg);
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
yydebug = 1;
|
||||
return yyparse ();
|
||||
}
|
||||
]])
|
||||
|
||||
AT_CHECK([bison -o input.c input.y], 0,,
|
||||
[[input.y:31.3-23: warning: unset value: $$
|
||||
input.y:28.3-33.37: warning: unused value: $3
|
||||
]])
|
||||
|
||||
AT_COMPILE([input])
|
||||
AT_PARSER_CHECK([./input], 1,,
|
||||
[[Starting parse
|
||||
Entering state 0
|
||||
Reducing stack by rule 1 (line 28):
|
||||
-> $$ = nterm $@1 (: )
|
||||
Stack now 0
|
||||
Entering state 2
|
||||
Reducing stack by rule 2 (line 29):
|
||||
-> $$ = nterm @2 (: 2)
|
||||
Stack now 0 2
|
||||
Entering state 4
|
||||
Reducing stack by rule 3 (line 30):
|
||||
-> $$ = nterm @3 (: 3)
|
||||
Stack now 0 2 4
|
||||
Entering state 5
|
||||
Reducing stack by rule 4 (line 31):
|
||||
-> $$ = nterm @4 (: 4)
|
||||
Stack now 0 2 4 5
|
||||
Entering state 6
|
||||
Reading a token: Now at end of input.
|
||||
syntax error
|
||||
Error: popping nterm @4 (: 4)
|
||||
DESTROY 4
|
||||
Stack now 0 2 4 5
|
||||
Error: popping nterm @3 (: 3)
|
||||
DESTROY 3
|
||||
Stack now 0 2 4
|
||||
Error: popping nterm @2 (: 2)
|
||||
DESTROY 2
|
||||
Stack now 0 2
|
||||
Error: popping nterm $@1 (: )
|
||||
Stack now 0
|
||||
Cleanup: discarding lookahead token $end (: )
|
||||
Stack now 0
|
||||
]])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
@@ -252,13 +252,13 @@ AT_CHECK([cat input.output], [],
|
||||
|
||||
0 $accept: expr $end
|
||||
|
||||
1 @1: /* empty */
|
||||
1 $@1: /* empty */
|
||||
|
||||
2 expr: 'a' @1 'b'
|
||||
2 expr: 'a' $@1 'b'
|
||||
|
||||
3 @2: /* empty */
|
||||
3 $@2: /* empty */
|
||||
|
||||
4 expr: @2 'c'
|
||||
4 expr: $@2 'c'
|
||||
|
||||
|
||||
Terminals, with rules where they appear
|
||||
@@ -276,9 +276,9 @@ $accept (6)
|
||||
on left: 0
|
||||
expr (7)
|
||||
on left: 2 4, on right: 0
|
||||
@1 (8)
|
||||
$@1 (8)
|
||||
on left: 1, on right: 2
|
||||
@2 (9)
|
||||
$@2 (9)
|
||||
on left: 3, on right: 4
|
||||
|
||||
|
||||
@@ -288,19 +288,19 @@ state 0
|
||||
|
||||
'a' shift, and go to state 1
|
||||
|
||||
$default reduce using rule 3 (@2)
|
||||
$default reduce using rule 3 ($@2)
|
||||
|
||||
expr go to state 2
|
||||
@2 go to state 3
|
||||
$@2 go to state 3
|
||||
|
||||
|
||||
state 1
|
||||
|
||||
2 expr: 'a' . @1 'b'
|
||||
2 expr: 'a' . $@1 'b'
|
||||
|
||||
$default reduce using rule 1 (@1)
|
||||
$default reduce using rule 1 ($@1)
|
||||
|
||||
@1 go to state 4
|
||||
$@1 go to state 4
|
||||
|
||||
|
||||
state 2
|
||||
@@ -312,14 +312,14 @@ state 2
|
||||
|
||||
state 3
|
||||
|
||||
4 expr: @2 . 'c'
|
||||
4 expr: $@2 . 'c'
|
||||
|
||||
'c' shift, and go to state 6
|
||||
|
||||
|
||||
state 4
|
||||
|
||||
2 expr: 'a' @1 . 'b'
|
||||
2 expr: 'a' $@1 . 'b'
|
||||
|
||||
'b' shift, and go to state 7
|
||||
|
||||
@@ -333,14 +333,14 @@ state 5
|
||||
|
||||
state 6
|
||||
|
||||
4 expr: @2 'c' .
|
||||
4 expr: $@2 'c' .
|
||||
|
||||
$default reduce using rule 4 (expr)
|
||||
|
||||
|
||||
state 7
|
||||
|
||||
2 expr: 'a' @1 'b' .
|
||||
2 expr: 'a' $@1 'b' .
|
||||
|
||||
$default reduce using rule 2 (expr)
|
||||
]])
|
||||
@@ -553,9 +553,9 @@ AT_CHECK([cat input.output], 0,
|
||||
2 CONST_DEC_LIST: CONST_DEC
|
||||
3 | CONST_DEC_LIST CONST_DEC
|
||||
|
||||
4 @1: /* empty */
|
||||
4 $@1: /* empty */
|
||||
|
||||
5 CONST_DEC: @1 undef_id_tok '=' const_id_tok ';'
|
||||
5 CONST_DEC: $@1 undef_id_tok '=' const_id_tok ';'
|
||||
|
||||
|
||||
Terminals, with rules where they appear
|
||||
@@ -578,7 +578,7 @@ CONST_DEC_LIST (9)
|
||||
on left: 2 3, on right: 1 3
|
||||
CONST_DEC (10)
|
||||
on left: 5, on right: 2 3
|
||||
@1 (11)
|
||||
$@1 (11)
|
||||
on left: 4, on right: 5
|
||||
|
||||
|
||||
@@ -586,12 +586,12 @@ state 0
|
||||
|
||||
0 $accept: . CONST_DEC_PART $end
|
||||
|
||||
$default reduce using rule 4 (@1)
|
||||
$default reduce using rule 4 ($@1)
|
||||
|
||||
CONST_DEC_PART go to state 1
|
||||
CONST_DEC_LIST go to state 2
|
||||
CONST_DEC go to state 3
|
||||
@1 go to state 4
|
||||
$@1 go to state 4
|
||||
|
||||
|
||||
state 1
|
||||
@@ -606,11 +606,11 @@ state 2
|
||||
1 CONST_DEC_PART: CONST_DEC_LIST .
|
||||
3 CONST_DEC_LIST: CONST_DEC_LIST . CONST_DEC
|
||||
|
||||
undef_id_tok reduce using rule 4 (@1)
|
||||
undef_id_tok reduce using rule 4 ($@1)
|
||||
$default reduce using rule 1 (CONST_DEC_PART)
|
||||
|
||||
CONST_DEC go to state 6
|
||||
@1 go to state 4
|
||||
$@1 go to state 4
|
||||
|
||||
|
||||
state 3
|
||||
@@ -622,7 +622,7 @@ state 3
|
||||
|
||||
state 4
|
||||
|
||||
5 CONST_DEC: @1 . undef_id_tok '=' const_id_tok ';'
|
||||
5 CONST_DEC: $@1 . undef_id_tok '=' const_id_tok ';'
|
||||
|
||||
undef_id_tok shift, and go to state 7
|
||||
|
||||
@@ -643,28 +643,28 @@ state 6
|
||||
|
||||
state 7
|
||||
|
||||
5 CONST_DEC: @1 undef_id_tok . '=' const_id_tok ';'
|
||||
5 CONST_DEC: $@1 undef_id_tok . '=' const_id_tok ';'
|
||||
|
||||
'=' shift, and go to state 8
|
||||
|
||||
|
||||
state 8
|
||||
|
||||
5 CONST_DEC: @1 undef_id_tok '=' . const_id_tok ';'
|
||||
5 CONST_DEC: $@1 undef_id_tok '=' . const_id_tok ';'
|
||||
|
||||
const_id_tok shift, and go to state 9
|
||||
|
||||
|
||||
state 9
|
||||
|
||||
5 CONST_DEC: @1 undef_id_tok '=' const_id_tok . ';'
|
||||
5 CONST_DEC: $@1 undef_id_tok '=' const_id_tok . ';'
|
||||
|
||||
';' shift, and go to state 10
|
||||
|
||||
|
||||
state 10
|
||||
|
||||
5 CONST_DEC: @1 undef_id_tok '=' const_id_tok ';' .
|
||||
5 CONST_DEC: $@1 undef_id_tok '=' const_id_tok ';' .
|
||||
|
||||
$default reduce using rule 5 (CONST_DEC)
|
||||
]])
|
||||
|
||||
Reference in New Issue
Block a user