Parsing context-free languages in a stream of tokens
问题
从位置 1 开始匹配:ab
从位置 4 开始匹配:aabb
给定具有任意规则和标记流的上下文无关文法,如何有效识别匹配文法的流片段?
例子:
语法
1 2 3 | S -> ASB | AB A -> a B -> b |
(所以本质上,多个
溪流:
1 | aabaaabbc... |
预期结果:
当然,关键是"有效地"。没有测试太多绝望的候选人太久。我对我的数据唯一了解的是,尽管语法是任意的,但实际上匹配序列会相对较短(<20 个终端),而流本身会很长(>10000 个终端)。
理想情况下,我还想要一个语法树,但这并不是很重要,因为一旦识别出片段,我就可以在它上面运行一个普通的解析器来获取树。
我应该从哪里开始?哪种类型的解析器可以适应这种类型的工作?
"任意语法"让我建议你看看 wberry 的评论。
这些语法有多复杂?是否有人工干预步骤?
我会尝试的。如果我修改了您的示例语法:
1 2 3 | S -> ASB | AB A -> a B -> b |
包括:
1 2 | S' -> S | GS' | S'GS' | S'G G -> sigma* |
所以 G = 垃圾和 S' 是许多 S 片段之间有垃圾(我可能对我的生产规则粗心。你明白了),我认为我们可以解决你的问题。您只需要一个在 G 之前匹配其他规则的解析器。您可能需要根据解析器修改这些生产规则。我几乎保证会根据解析器进行规则排序更改。由于大多数解析器库将词法分析与解析分开,因此您可能需要一个包罗万象的词位,然后修改 G 以包含所有可能的词位。根据您的具体情况,这可能不会比仅在流中的每个位置开始每次尝试更好(效率方面)。
但是...假设我的生产规则是固定的(为了正确性和解析器的特殊风格),这不仅应该匹配流中的片段,而且应该为您提供整个流的解析树。您只对以 S 类型的节点为根的子树感兴趣。