Bison 冲突转移/减少

标签 bison yacc

我是 bison\yacc 的新手,我正在尝试编写一个类似 pascal 的语法分析器,并且我得到了

analizorSintactic.y: conflicts: 1 shift/reduce 
analizorSintactic.y:65.13-23: warning: rule useless in parser due to conflicts: decllist: declaration

我收到有关以下语法规则的警告

program : PROGRAM IDENTIFIER SEMICOLON content; 
content : VAR decllist SEMICOLON cmpdstmt DOT ;

decllist :  declaration | declaration SEMICOLON decllist ;
declaration : IDENTIFIER COLON type 
        | IDENTIFIER COMMA declaration;

如何解决此冲突? 谢谢!

最佳答案

首先,请发布一些内容是自给自足的。这并不难:将语法片段中不需要的非终结符转换为标记。对于您的情况:

%%
program : "PROGRAM" "IDENTIFIER" "SEMICOLON" content; 
content : "VAR" decllist "SEMICOLON" "cmpdstmt" "DOT" ;

decllist :  declaration | declaration "SEMICOLON" decllist ;
declaration : "IDENTIFIER" "COLON" "type" 
        | "IDENTIFIER" "COMMA" declaration;

然后,将其提供给 bison --report=all 并读取生成的 *.output 文件,其中包含:

State 10

    3 decllist: declaration .  ["SEMICOLON"]
    4         | declaration . "SEMICOLON" decllist

    "SEMICOLON"  shift, and go to state 14

    "SEMICOLON"  [reduce using rule 3 (decllist)]

换句话说,Bison 不知道如何读取声明后跟的;。这是因为由于 content< 规则,有一个“单个”声明(规则 3)可以后跟一个 ;/。这种冲突无法通过优先级/关联性来解决,因为在某些情况下,移位是正确的(如果在 ; 之后有一个 decllist),在其他情况下,reduce 是正确的(因为;后面有一个cmpdstmt)。您必须重写语法以帮助解析器生成器“在规则中看得更远”。

例如,您可以将 ;content 规则发送到 decllist 规则:

%%
program : "PROGRAM" "IDENTIFIER" "SEMICOLON" content; 
content : "VAR" decllist "cmpdstmt" "DOT" ;

decllist : declaration "SEMICOLON"
         | declaration "SEMICOLON" decllist ;
declaration : "IDENTIFIER" "COLON" "type" 
        | "IDENTIFIER" "COMMA" declaration;

应该可以了。

关于 Bison 冲突转移/减少,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20305104/

相关文章:

c++ - Bison :存储自定义类

python - PLY Lex 和 Yacc 问题

java - 使用 byaccj 构建 ast 时出错

c++ - 弹性/Bison ,错误 : undeclared

python - 层 lex yacc : Errors handling

c - Flex Bison 计算器不打印结果

parsing - 修复 Bison 语法中的移位/减少冲突

parsing - LR(k) 到 LR(1) 语法转换

c++ - 使用 Bison 解析简单 C 源代码的问题

c - 在 flex 和 bison 中获取超出预期的字符串标记值