简体   繁体   中英

Bison: rule useless in parser due to conflicts [-Wother]

I have this grammar which is supposed to generate java byte code out of java code. I know this warning has been addressed before in many questions but I couldn't find a problem similar to mine. it displays out this warning for this two rules in particular:

statement_list: 
    {
        $<stmt_type>$.next = $<stmt_type>0.next;
    }
     statement 
    | 
    {
        $<stmt_type>$.next = strdup(genLabel().c_str());    //generate label for statement and assign it to statement list next
    }
    statement_list 
    {
        $<stmt_type>$.next = $<stmt_type>0.next;
        fout<<$<stmt_type>1.next<<":"<<endl;    //mark statement with statement list next label
    }
    statement 
    ;

and this one

b_expression:
expression RELA_OP expression       
    {$$ = $<bexpr_type>0;relaCast(string($2),$$.nTrue,$$.nFalse);}
|{/* addding some strings to this action */ } b_expression BOOL_OP b_expression

I need here to mark every statement with its next before parsing it to use it in code generation. when I remove the semantic actions from statement_list its error goes away, but I didn't try the same for b_expression.

Bison only looks ahead 1 token to decide which production to apply. Your two productions for statement both have code blocks before the parser has read any tokens to know which production is going to apply.

If you're generating assembly-like stack code with labels directly in your yacc rules, you usually use something like:

if_statement: IF condition {
                      $$ = gen_label();
                      gen_code(JUMP_FALSE, $$); }
              THEN block {
                      $$ = gen_label();
                      gen_code(JUMP, $$);
                      gen_code(LABEL, $3); }
              ELSE block {
                      gen_code(LABEL, $6); }

while_statement: WHILE { gen_code(LABEL, $$ = gen_label()); }
                 condition { gen_code(JUMP_FALSE, $$ = gen_label); }
                 block { gen_code(JUMP, $2); gen_code(LABEL, $4); }

If you're generating byte-code directly, you don't have 'labels' as such -- when you generate a forward branch you remember the spot in the bytecode where the target offset should go and when you get to the spot where you would output the label, you backpatch the branch to jump to the current location.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM