Parsing 减少语法中的冲突
在LR解析器分析期间,该语法中的reduce-reduce和shift-reduce冲突是什么?该摘录中没有reduce-reduce冲突,但肯定到处都有shift-reduce冲突。它们都有相同的原因:语法没有试图定义各种运算符的优先级,结果是任何具有多个运算符的表达式都是不明确的 例如,Parsing 减少语法中的冲突,parsing,lr,shift-reduce-conflict,reduce-reduce-conflict,Parsing,Lr,Shift Reduce Conflict,Reduce Reduce Conflict,在LR解析器分析期间,该语法中的reduce-reduce和shift-reduce冲突是什么?该摘录中没有reduce-reduce冲突,但肯定到处都有shift-reduce冲突。它们都有相同的原因:语法没有试图定义各种运算符的优先级,结果是任何具有多个运算符的表达式都是不明确的 例如,前缀ID后缀可以被解析为写入(前缀ID)后缀或前缀(ID后缀)。这显然会在ID减少为表达式后产生移位-减少冲突: 堆栈:前缀表达式 前瞻:后缀 此时,解析器可以使用expression->PREFIX ex
前缀ID后缀
可以被解析为写入(前缀ID)后缀
或前缀(ID后缀)
。这显然会在ID
减少为表达式后产生移位-减少冲突:
堆栈:前缀表达式
前瞻:后缀
此时,解析器可以使用expression->PREFIX expression
将堆栈缩减为expression
。但是它也可以将POStFIX
从输入转移到堆栈上,为减少expression->expression POStFIX
做准备
每个其他运算符都会发现相同的歧义。Reduce Reduce意味着它已达到一种状态,即在语言符号前面,它可以减少两种不同的规则,导致两种不同的语法树代表您的句子。由于下一个符号在这两种情况下都是有效的,并且是一个提前一个符号的解析器,这意味着您的语法是不明确的,您需要提供更多信息(如优先级规则或类似信息),以便使解析器进行一种或另一种缩减
您可以从yacc
类型语法编译器或shift-reduce收到此错误,这同样意味着语法中存在歧义。虽然除了改变语法的定义方式,或者切换到基于运算符优先级的语法来解决这个问题之外,没有其他解决方案,但在这两种情况下,我们都看到了某种歧义,导致在语言句子中描述两种不同的语法树
在你的情况下,规则
expression -> expression OPER expression
expression -> PREFIX expression
expression -> expression POSTFIX
expression -> expression ‘?’ expression ‘:’ expression
expression -> expression ‘[’ expression ‘]’
expression -> expression ‘(’ expression ‘)’
expression -> ID
expression -> CONSTANT
expression ->‘(’ expression ‘)’
充满了歧义,因为您无法猜测:
expression : expression OPER expression
将生成一个解析树:
3 + 5 + 8
/---表达式:常量
表达式:表达式操作表达式
\/---表达式:常量
\---表达式:表达式运算符
\---表达式:常量
或
/---表达式:常量
/---表达式:表达式操作表达式
/\---表达式:常数
表达式:表达式操作表达式
\---表达式:常量
第一个表示表达式被解析为(用全括号表示)(3+(5+8))
,第二个表示解析器已经解释了((3+5)+8)
/--- <3> expression : CONSTANT
<+> expression : expression OPER expression
\ /--- <5> expression : CONSTANT
\--- <+> expression : expression OPER
\--- <8> expression : CONSTANT
/--- <3> expression : CONSTANT
/--- <+> expression : expression OPER expression
/ \--- <5> expression : CONSTANT
<+> expression : expression OPER expression
\--- <8> expression : CONSTANT