【问题标题】:Shift/reduce with equal precedence具有相同优先级的移位/减少
【发布时间】:2014-02-27 22:13:02
【问题描述】:

我必须为 C 的一个子集构建一个编译器。显然,因为这是我第一次做这样的事情,所以进展并不顺利。然而。我目前正在尝试为所述子集构建词法分析器和解析器。

我决定一块一块地构建它,并在错误出现时修复它们。所以我有一个基本的语法,如下所示。这个语法可以正确解析,我可以做简单的数学运算,包括比较运算符。由于 thsi 是 C 的子集,并且它们返回整数值,因此这是可能的。

现在是棘手的部分。我还希望(需要)将 !- 建模为 unary 运算符,这意味着 -5 + 5 应该等于 0。

由于这两个一元运算符绑定最紧密,我想我需要将它们放在我的语法的 term 子句中。所以我将我的条款更改为以下内容:

term        :   NUMBER
            |   NOT term { printf("NOT term\n"); $$ = !$2; }
            |   SUB term { printf("MINUS term\n"); $$ = - ($2);}
            |   LEFTPAR exp RIGHTPAR { printf("expression between parents\n");$$ = $2; }
            |   
            ;

但是,这会让 bison 抱怨 shift/reduce 错误。我知道如何解决这些问题的基础知识,但是,这会在几乎所有可能的状态下产生移位/减少错误,所以我现在有点困惑。

我可以通过选择 - 而不是 ! 在我的语法中添加更多优先级,但这些同样严格。

整个语法

calclist    : /* nothing */
            | COMMENT { printf("Comment\n"); }
            | calclist comp EOL { printf("= %d\n", $2); } 
            ;

comp        :   exp
            |   comp GREATER exp { printf("comp GREATER factor\n");$$ = $1 > $3; }
            |   comp LESS exp { printf("comp LESS factor\n");$$ = $1 < $3; }
            |   comp EQUAL exp { printf("comp EQUAL factor\n");$$ = $1 == $3; }
            |   comp NEQUAL exp { printf("comp NEQUAL factor\n");$$ = $1 != $3; }
            ;

exp         :   factor
            |   exp ADD factor { printf("exp add factor\n");$$ = $1 + $3; }
            |   exp SUB factor { printf("exp sub factor\n");$$ = $1 - $3; }
            ;

factor      :   term       
            |   factor MUL term { printf("factor mul term\n");$$ = $1 * $3; }
            |   factor DIV term { printf("factor div term\n");$$ = $1 / $3; }
            ;           

term        :   NUMBER
            |   NOT term { printf("NOT term\n"); $$ = !$2; }
            |   SUB term { printf("MINUS term\n"); $$ = - ($2);}
            |   LEFTPAR exp RIGHTPAR { printf("expression between parents\n");$$ = $2; }
            |   
            ;

Bison 的输出如下:

bison -dv bison.y
bison.y: conflicts: 12 shift/reduce
flex lex.l
cc -o calc bison.tab.c lex.yy.c -lfl

我不会在这里粘贴整个 bison.output 文件,因为这是一个相当长的文件。

编辑:

下面粘贴的语法不包含SUB 标记。添加它以便可以复制粘贴。

【问题讨论】:

    标签: c parsing bison


    【解决方案1】:
    term        :   NUMBER
                |   NOT term { printf("NOT term\n"); $$ = !$2; }
                |   LEFTPAR exp RIGHTPAR { printf("expression between parents\n");$$ = $2; }
    

    问题就在这里,空的生产。只需将其删除。

                |   
                ;
    

    【讨论】:

    • 天哪.. 非常感谢! :) 你能否向我解释一下(如果你这样做了)你是如何从野牛的输出中得出这个结论的?或者你只是有经验?还是谢谢!
    • 刚刚看了y.output文件中的冲突,在状态2有一个SUB的转变,与规则#19冲突,查看规则#19,哎呀19 | %empty
    猜你喜欢
    • 2014-10-24
    • 2022-11-21
    • 2015-02-27
    • 1970-01-01
    • 2020-08-24
    • 1970-01-01
    • 2012-09-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多