Python 解决轮班/减少与PLY的冲突
我的语法如下:Python 解决轮班/减少与PLY的冲突,python,parsing,compiler-construction,grammar,ply,Python,Parsing,Compiler Construction,Grammar,Ply,我的语法如下: 如何在不产生新冲突的情况下解决这些问题?我知道它们是从哪里来的,但我不知道如何修复它。任何帮助或一般建议都是值得的。我会倒着做,因为那样我们会从最容易的到最难的。事实上,对于第一次冲突,我并没有真正的解决方案 第三个冲突是语法中实际歧义的结果。您需要消除歧义: Rule 96 enclosure -> parenth_form Rule 97 enclosure -> set_display Rule 99 parenth_form -> LP
如何在不产生新冲突的情况下解决这些问题?我知道它们是从哪里来的,但我不知道如何修复它。任何帮助或一般建议都是值得的。我会倒着做,因为那样我们会从最容易的到最难的。事实上,对于第一次冲突,我并没有真正的解决方案 第三个冲突是语法中实际歧义的结果。您需要消除歧义:
Rule 96 enclosure -> parenth_form
Rule 97 enclosure -> set_display
Rule 99 parenth_form -> LPAREN expression RPAREN
Rule 102 set_display -> LPAREN argument_list RPAREN
Rule 133 argument_list -> expression
因此,如果我们正在寻找一个附件
,并找到一个简单的括号表达式,它可以是一个父形式
,也可以是一个集合显示
,其中包含一个表达式的参数列表
。我怀疑这里的意图是,一个简单的括号表达式将是一个parenth_形式
,但从语法上无法区分
最简单的解决方案是完全去掉parenth\u表单
,并在为与规则102相对应的set\u显示
构建AST节点时检查单元素参数列表
的情况。另一种可能性是明确地表达出来;更改规则102以要求设置_显示
至少有两个表达式:
set_display -> LPAREN expression COMMA argument_list RPAREN
但是,这仍然需要处理AST,因为在构建set\u display
节点时,必须将表达式
前置到参数列表
第二次S/R冲突实际上非常相似。这是因为:
Rule 104 list_display -> LBRACKET expression COMMA expression RANGE expression RBRACKET
Rule 105 list_display -> LBRACKET argument_list RBRACKET
因此:
如果以下符号为范围
,则需要按照规则104进行缩减;根据第105条,如果以下符号为RBRACKET;根据规则134,如果下列符号为逗号
。(这是一个粗略的近似值,因为它假设我们已经知道第二个表达式的结尾)尽管如此,语法需要在看到第一个逗号时立即提交到其中一个路径,因为它需要在那一刻决定是否创建参数列表
解决方案是延迟解析器的决策,这很容易,但很难看:
list_display -> LBRACKET expression RANGE expression RBRACKET
list_display -> LBRACKET expression COMMA expression RANGE expression RBRACKET
list_display -> LBRACKET expression RBRACKET
list_display -> LBRACKET expression COMMA argument_list RBRACKET
现在,第一个逗号
总是被移位,关于显示什么类型的列表
的决定被延迟到第二个表达式
的末尾(如果有两个表达式
的话),但是有必要对最后两个产品的AST进行调整,以更正参数列表
出现第一个S/R冲突是因为
中的既用作运算符,又用作迭代器的语法部分
:
Rule 44 comparison -> sum IN sum
Rule 137 iterator -> target IN expression
但是,由于目标
只是一个表达式
,并且表达式
可以派生和
,因此(大多数情况下)解析器不可能知道它在
中查看的是哪个
前面的延迟决策技术在这里不起作用,因为您需要知道您正在查看的是
中的哪种类型的,以便正确应用运算符优先级。假设我们在一个上下文中需要一个迭代器,输入是:
atom1 AND atom2 IN atom3
如果这是迭代器(即,下一个符号是逗号
或RPAREN
),则实际上:
( atom1 AND atom2 ) IN atom3
但是,如果这是迭代器的左侧,则需要对其进行完全不同的解析:
( atom1 AND ( atom2 IN atom3 ) ) IN expression
此外,atom3
可能是一个任意表达式,可能是atom3和atom4
,导致两种解析:
( atom1 AND atom2 ) IN ( atom3 AND atom4 )
( atom1 AND ( atom2 IN atom3 ) AND atom4 ) IN expression
这就是双关语在语言设计中不好的原因
我强烈怀疑没有LR(k)
语法能够解析语言的特定角落,尽管这只是基于直觉;我没有证据。然而,GLR解析器不会有任何问题,因为它实际上并不含糊。我不知道Python中是否有GLR解析器生成器;如果您不依赖Python,那么您当然可以使用bison
GLR解析器还可以解决第二个冲突,这也不是歧义的结果。我将反向执行这些操作,因为这样我们可以从最容易的到最难的。事实上,对于第一次冲突,我并没有真正的解决方案
第三个冲突是语法中实际歧义的结果。您需要消除歧义:
Rule 96 enclosure -> parenth_form
Rule 97 enclosure -> set_display
Rule 99 parenth_form -> LPAREN expression RPAREN
Rule 102 set_display -> LPAREN argument_list RPAREN
Rule 133 argument_list -> expression
因此,如果我们正在寻找一个附件
,并找到一个简单的括号表达式,它可以是一个父形式
,也可以是一个集合显示
,其中包含一个表达式的参数列表
。我怀疑这里的意图是,一个简单的括号表达式将是一个parenth_形式
,但从语法上无法区分
最简单的解决方案是完全去掉parenth\u表单
,并在为与规则102相对应的set\u显示
构建AST节点时检查单元素参数列表
的情况。另一种可能性是明确地表达出来;更改规则102以要求设置_显示
至少有两个表达式:
set_display -> LPAREN expression COMMA argument_list RPAREN
但是,这仍然需要处理AST,因为在构建set\u display
节点时,必须将表达式
前置到参数列表
第二次S/R冲突实际上非常相似。这是因为:
Rule 104 list_display -> LBRACKET expression COMMA expression RANGE expression RBRACKET
Rule 105 list_display -> LBRACKET argument_list RBRACKET
因此:
如果以下符号为范围
,则需要按照规则104进行缩减;根据第105条,如果以下符号为
RBRACKET
;根据规则134,如果下列符号为逗号
。(这是一个粗略的近似值,因为它假设我们已经知道第二个表达式的结尾)