我有一个相当简单的语言,表示为CFG。
S → A z
A → A y A
| A x A
| A w
| v
由于左递归,递归下降解析器不会削减它。但是,我还需要找到所有可能的解释:给定v x v y v z
,我需要我的解析器来查找(v x (v y v)) z
和((v x v) y v) z
。
我有哪些选择?通过添加回溯来进行Shift-reduce以找到所有可能性似乎很好,但我听说向移位减少解析器添加回溯可以使其具有指数时间复杂度。这个CFG足够小,不值得,但我需要将其扩展到更大的语法(有数千个终端)。
答案 0 :(得分:1)
有几类无上下文语法。有确定性语法,可以使用shift-reduce解析器进行解析。存在非确定性语法,解决方案通常是动态前瞻或回溯。并且有一些含糊不清的语法,就像你描述的语法一样,最好用特别设计的算法来解决。
两个这样的算法,是Earley(正如@rici所指出的)和CYK。它们旨在根据您的需要返回所有可能的派生,并可用于创建SPPF(共享打包解析林),这是一个非常有效的结构,适用于高度模糊的语法(无论您是否适合此描述,我当然不能说。)
如果你想试验它,你可以尝试我的解析库python Lark,它实现了Earley和CYK,并且可以列出你输入的所有可能的派生(但是,SPPF支持仍在进行中。)