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:
Joel E. Denny
2006-10-21 04:52:43 +00:00
parent 519d000408
commit f91b162944
5 changed files with 165 additions and 34 deletions

View File

@@ -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> 2006-10-20 Joel E. Denny <jdenny@ces.clemson.edu>
Warn about unset midrule $$ if the corresponding $n is used. Warn about unset midrule $$ if the corresponding $n is used.

View File

@@ -459,11 +459,12 @@ packgram (void)
rules = xnmalloc (nrules, sizeof *rules); rules = xnmalloc (nrules, sizeof *rules);
/* Before invoking grammar_rule_check on any rule, make sure /* Before invoking grammar_rule_check on any rule, make sure all actions have
all actions have already been scanned in order to set `used' flags. already been scanned in order to set `used' flags. Otherwise, checking
Otherwise, checking that a midrule's $$ is set will not always work that a midrule's $$ should be set will not always work properly because
properly because the midrule check must forward-reference the midrule's the check must forward-reference the midrule's parent rule. For the same
parent rule. */ reason, all the `used' flags must be set before checking whether to remove
`$' from any midrule symbol name. */
while (p) while (p)
{ {
if (p->action) if (p->action)
@@ -492,6 +493,15 @@ packgram (void)
rules[ruleno].action = p->action; rules[ruleno].action = p->action;
rules[ruleno].action_location = p->action_location; 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 /* Don't check the generated rule 0. It has no action, so some rhs
symbols may appear unused, but the parsing algorithm ensures that symbols may appear unused, but the parsing algorithm ensures that
%destructor's are invoked appropriately. */ %destructor's are invoked appropriately. */

View File

@@ -769,7 +769,7 @@ dummy_symbol_get (location loc)
symbol *sym; symbol *sym;
sprintf (buf, "@%d", ++dummy_count); sprintf (buf, "$@%d", ++dummy_count);
sym = symbol_get (buf, loc); sym = symbol_get (buf, loc);
sym->class = nterm_sym; sym->class = nterm_sym;
sym->number = nvars++; sym->number = nvars++;
@@ -779,7 +779,7 @@ dummy_symbol_get (location loc)
bool bool
symbol_is_dummy (const symbol *sym) symbol_is_dummy (const symbol *sym)
{ {
return sym->tag[0] == '@'; return sym->tag[0] == '@' || (sym->tag[0] == '$' && sym->tag[1] == '@');
} }
/*-------------------. /*-------------------.

View File

@@ -1096,3 +1096,108 @@ AT_CHECK([bison -o input.c input.y])
AT_COMPILE([input]) AT_COMPILE([input])
AT_CLEANUP 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

View File

@@ -252,13 +252,13 @@ AT_CHECK([cat input.output], [],
0 $accept: expr $end 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 Terminals, with rules where they appear
@@ -276,9 +276,9 @@ $accept (6)
on left: 0 on left: 0
expr (7) expr (7)
on left: 2 4, on right: 0 on left: 2 4, on right: 0
@1 (8) $@1 (8)
on left: 1, on right: 2 on left: 1, on right: 2
@2 (9) $@2 (9)
on left: 3, on right: 4 on left: 3, on right: 4
@@ -288,19 +288,19 @@ state 0
'a' shift, and go to state 1 'a' shift, and go to state 1
$default reduce using rule 3 (@2) $default reduce using rule 3 ($@2)
expr go to state 2 expr go to state 2
@2 go to state 3 $@2 go to state 3
state 1 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 state 2
@@ -312,14 +312,14 @@ state 2
state 3 state 3
4 expr: @2 . 'c' 4 expr: $@2 . 'c'
'c' shift, and go to state 6 'c' shift, and go to state 6
state 4 state 4
2 expr: 'a' @1 . 'b' 2 expr: 'a' $@1 . 'b'
'b' shift, and go to state 7 'b' shift, and go to state 7
@@ -333,14 +333,14 @@ state 5
state 6 state 6
4 expr: @2 'c' . 4 expr: $@2 'c' .
$default reduce using rule 4 (expr) $default reduce using rule 4 (expr)
state 7 state 7
2 expr: 'a' @1 'b' . 2 expr: 'a' $@1 'b' .
$default reduce using rule 2 (expr) $default reduce using rule 2 (expr)
]]) ]])
@@ -553,9 +553,9 @@ AT_CHECK([cat input.output], 0,
2 CONST_DEC_LIST: CONST_DEC 2 CONST_DEC_LIST: CONST_DEC
3 | 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 Terminals, with rules where they appear
@@ -578,7 +578,7 @@ CONST_DEC_LIST (9)
on left: 2 3, on right: 1 3 on left: 2 3, on right: 1 3
CONST_DEC (10) CONST_DEC (10)
on left: 5, on right: 2 3 on left: 5, on right: 2 3
@1 (11) $@1 (11)
on left: 4, on right: 5 on left: 4, on right: 5
@@ -586,12 +586,12 @@ state 0
0 $accept: . CONST_DEC_PART $end 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_PART go to state 1
CONST_DEC_LIST go to state 2 CONST_DEC_LIST go to state 2
CONST_DEC go to state 3 CONST_DEC go to state 3
@1 go to state 4 $@1 go to state 4
state 1 state 1
@@ -606,11 +606,11 @@ state 2
1 CONST_DEC_PART: CONST_DEC_LIST . 1 CONST_DEC_PART: CONST_DEC_LIST .
3 CONST_DEC_LIST: CONST_DEC_LIST . CONST_DEC 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) $default reduce using rule 1 (CONST_DEC_PART)
CONST_DEC go to state 6 CONST_DEC go to state 6
@1 go to state 4 $@1 go to state 4
state 3 state 3
@@ -622,7 +622,7 @@ state 3
state 4 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 undef_id_tok shift, and go to state 7
@@ -643,28 +643,28 @@ state 6
state 7 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 '=' shift, and go to state 8
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 const_id_tok shift, and go to state 9
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 ';' shift, and go to state 10
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) $default reduce using rule 5 (CONST_DEC)
]]) ]])