[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
recursive rule not used
From: |
James K. Lowden |
Subject: |
recursive rule not used |
Date: |
Tue, 18 Oct 2022 13:02:21 -0400 |
Either I have tickled a bug, or there's a simple explanation.
Below is a fragment of the current GCC Cobol grammar. (The compiler is
based on gcc; it's not yet officially part of the project.)
search_1_cases is a recursive rule. It takes 1 or more occurences of
search_1_case. Each search_1_case starts with the keyword WHEN.
The grammar is meant to handle a series of phrases
WHEN conditional search_stmts
WHEN conditional search_stmts
...
Parsing a sequence of those phrases, Bison reduces the first
one according to the first (non-recursive) rule for search_1_cases. It
reports the lookahead as WHEN. Instead of parsing the remaining WHEN
phrases, it concludes the whole statement, and then complains the 2nd
WHEN is invalid syntax.
I don't understand how that's possible. Because WHEN heads every
search_1_case rule, I think an LALR(1) parser would obviously choose
the recursive path when WHEN is the lookahead token.
FTR, WHEN has %right recursion, and lower precedence than search_stmts
(which have dynamic %prec ADD precedence).
In the interest of full disclosure, I am ignoring a shift/reduce
warning regarding WHEN, but in a different part of the grammar,
related to a different verb:
> State 1008
>
> 530 eval_switch: eval_whens ?
> 532 eval_whens: eval_whens ? eval_when
>
> WHEN shift, and go to state 1005
>
> WHEN [reduce using rule 530 (eval_switch)]
> $default reduce using rule 530 (eval_switch)
>
> eval_when go to state 1312
> when go to state 1010
Testing shows Bison's preference for shift in that case results in
correct behavior.
Why might Bison behave the way it does for search_1_cases?
Grammar fragment follows.
--jkl
[snip]
search_1_cases: search_1_case
{
if( yydebug ) {
const char *lookahead = "?";
switch( yychar ) {
case 0: lookahead = "YYEOF"; break;
case -2: lookahead = "YYEMPTY"; break;
default:
if( yychar > 0 ) {
lookahead = keyword_str(yychar);
}
}
warnx("lookahead is '%s'",lookahead); }
}
| search_1_cases search_1_case
;
search_1_case: WHEN {
parser_lsearch_conditional();
} conditional {
parser_lsearch_when( $conditional.cond );
} search_stmts
;
[pins]
- recursive rule not used,
James K. Lowden <=