简体   繁体   English

野牛:由于冲突,规则在解析器中无用[-Wother]

[英]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. 我有这个语法,应该从Java代码中生成Java字节代码。 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. 当我从statement_list中删除语义动作时,它的错误消失了,但是我没有对b_expression尝试相同的操作。

Bison only looks ahead 1 token to decide which production to apply. 野牛只预取1个令牌来决定要应用哪个生产。 Your two productions for statement both have code blocks before the parser has read any tokens to know which production is going to apply. 在解析器读取任何令牌以知道将应用哪个生产之前,您的两个for语句生产都具有代码块。

If you're generating assembly-like stack code with labels directly in your yacc rules, you usually use something like: 如果您要直接在yacc规则中生成带有标签的类似于程序集的堆栈代码,则通常使用以下方法:

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. 如果直接生成字节码,则没有这样的“标签”-当生成前向分支时,您会记住字节码中目标偏移量应到达的位置以及到达目标位置的位置会输出标签,然后对分支进行后修补以跳转到当前位置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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