Bison:由于冲突,规则在解析器中无效[-Wother]

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

本文关键字:无效 -Wother 规则 于冲突 冲突 Bison      更新时间:2023-10-16

我有这个语法,它应该从java代码中生成java字节码。我知道这个警告以前已经在很多问题中得到了解决,但我找不到类似的问题。它显示了这两个规则的警告,特别是:

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 
    ;

还有这个

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

在解析每个语句以在代码生成中使用它之前,我需要在这里用下一个语句标记它。当我从statement_list中删除语义操作时,它的错误就消失了,但我没有对b_expression进行同样的尝试。

Bison只向前看1个令牌来决定应用哪个生产。您的两个production for语句在解析器已经读取了任何令牌,以知道要应用哪个产品。

如果您直接在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); }

如果你直接生成字节码,你就没有"标签"——当你生成正向分支时,你会记住字节码中目标偏移应该去的地方,当你到达要输出标签的地方时,你就会对分支进行回溯,跳到当前位置。