解决yacc冲突-由于冲突,解析器中的规则无效 我正在研究一个YACC文件,解析给定文件并将其转换成等效的C++文件。我根据提供的语法图创建了以下语法: program: PROGRAMnumber id 'is' comp_stmt ; comp_stmt: BEGINnumber statement symbol ENDnumber ; statement: statement SEMInumber statement | id EQnumber expression | PRINTnumber expression | declaration ; declaration: VARnumber id ; expression: term ; term: term as_op term | MINUSnumber term | factor ; factor: factor md_op factor | ICONSTnumber | id | RPARENnumber expression LPARENnumber ; as_op: PLUSnumber | MINUSnumber ; md_op: TIMESnumber | DIVnumber ; symbol: SEMInumber | COMMAnumber ; id: IDnumber | id symbol id ;
我剩下的唯一问题是,我在尝试使用yacc编译时收到了这个错误解决yacc冲突-由于冲突,解析器中的规则无效 我正在研究一个YACC文件,解析给定文件并将其转换成等效的C++文件。我根据提供的语法图创建了以下语法: program: PROGRAMnumber id 'is' comp_stmt ; comp_stmt: BEGINnumber statement symbol ENDnumber ; statement: statement SEMInumber statement | id EQnumber expression | PRINTnumber expression | declaration ; declaration: VARnumber id ; expression: term ; term: term as_op term | MINUSnumber term | factor ; factor: factor md_op factor | ICONSTnumber | id | RPARENnumber expression LPARENnumber ; as_op: PLUSnumber | MINUSnumber ; md_op: TIMESnumber | DIVnumber ; symbol: SEMInumber | COMMAnumber ; id: IDnumber | id symbol id ;,c,yacc,C,Yacc,我剩下的唯一问题是,我在尝试使用yacc编译时收到了这个错误 conflicts: 14 shift/reduce calc.y:103.17-111.41: warning: rule useless in parser due to conflicts: declaration: VARnumber id 我已经解决了我遇到的唯一其他冲突,但我不确定这场冲突的解决方案是什么。它应该匹配的行的格式为 var a, b, c, d; 或 所有用于派生列表的产品都是不明确的,因此会产生redu
conflicts: 14 shift/reduce
calc.y:103.17-111.41: warning: rule useless in parser due to conflicts: declaration: VARnumber id
我已经解决了我遇到的唯一其他冲突,但我不确定这场冲突的解决方案是什么。它应该匹配的行的格式为
var a, b, c, d;
或
所有用于派生列表的产品都是不明确的,因此会产生reduce/reduce冲突。例如:
id: id symbol id
当有三个标识符时,将明显不明确:是先减少前两个,还是后两个?通常的列表习惯用法是左递归:
id_list: id | id_list `,` id
对于大多数语言来说,这对于以分号结尾的语句是不正确的,而不是由分号分隔的,但该模型适用于以逗号分隔的标识符列表,或者适用于加法运算符的左关联序列
对于语句,您可能需要以下内容:
statement_list: | statement_list statement ';'
说到符号
,你真的相信、
和代码>是否具有相同的语法功能?这似乎不太可能,因为您编写了var a、b、c、d代码>而不是,例如,var a;b、 c;d、
bison产生的“无用规则”警告正是因为您的语法允许用分号分隔id
s。当解析器看到带有的“var”ID
时
作为前瞻,它首先将ID
减少到ID
,然后需要决定是将var ID
减少到声明
还是移动
以便稍后将其缩减为symbol
,然后继续缩减id symbol id
。在没有优先规则的情况下,bison总是解决有利于转移的转移/减少冲突,因此在这种情况下它就是这样做的。但其结果是,永远不可能将“var”id
减少为声明
,从而使生产作为移位减少冲突解决的结果变得无用,这或多或少就是警告所说的。所有用于派生列表的产品都不明确,因此会产生reduce/reduce冲突。例如:
id: id symbol id
当有三个标识符时,将明显不明确:是先减少前两个,还是后两个?通常的列表习惯用法是左递归:
id_list: id | id_list `,` id
对于大多数语言来说,这对于以分号结尾的语句是不正确的,而不是由分号分隔的,但该模型适用于以逗号分隔的标识符列表,或者适用于加法运算符的左关联序列
对于语句,您可能需要以下内容:
statement_list: | statement_list statement ';'
说到符号
,你真的相信、
和代码>是否具有相同的语法功能?这似乎不太可能,因为您编写了var a、b、c、d代码>而不是,例如,var a;b、 c;d、
bison产生的“无用规则”警告正是因为您的语法允许用分号分隔id
s。当解析器看到带有的“var”ID
时
作为前瞻,它首先将ID
减少到ID
,然后需要决定是将var ID
减少到声明
还是移动
以便稍后将其缩减为symbol
,然后继续缩减id symbol id
。在没有优先规则的情况下,bison总是解决有利于转移的转移/减少冲突,因此在这种情况下它就是这样做的。但其结果是,永远不可能将“var”id
减少为声明
,从而使生产作为shift-reduce冲突解决方案的结果变得无用,这或多或少是警告所说的。请修复格式设置。此外,单引号用于单字符标记;对于bison,您可以使用“var”
,但仍然需要%token
声明才能从扫描仪返回符号值。我在上次编辑中修复了该问题。有一个为var设置的令牌,最初我没有找到它,但即使在替换它之后,错误仍然存在。您在我的格式设置中看到了哪些其他问题,以便我可以解决它们?您真的使用了像COMMAnumber
这样的令牌名称吗?那几乎是不可读的。。。我以为他们漏掉了空格。还有%的声明吗?我正在使用为项目提供的lex文件。这正是我要处理的。请修改你的格式。此外,单引号用于单字符标记;对于bison,您可以使用“var”
,但仍然需要%token
声明才能从扫描仪返回符号值。我在上次编辑中修复了该问题。有一个为var设置的令牌,最初我没有找到它,但即使在替换它之后,错误仍然存在。您在我的格式设置中看到了哪些其他问题,以便我可以解决它们?您真的使用了像COMMAnumber
这样的令牌名称吗?那几乎是不可读的。。。我以为他们漏掉了空格。还有%的声明吗?我正在使用为项目提供的lex文件。这正是我被赋予的工作。我道歉。实际上,我在发布这篇文章之前解决了语句冲突的问题,但是忘记了在代码块中更新它。我已经解决了这个问题,但您的解决方案似乎更加优雅,因此我可以集成该方法。然而,这并不能解决我所遇到的剩余冲突。我现在更关心原始问题中列出的冲突。@neomang:我很确定这是id
歧义的结果。不要假设冲突是规则中的局部冲突,因为