help-bison
[Top][All Lists]
Advanced

[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]




reply via email to

[Prev in Thread] Current Thread [Next in Thread]