algorithm - 在标记流中解析上下文无关语言

标签 algorithm parsing context-free-grammar

问题

给定一个具有任意规则的上下文无关文法和标记流,如何有效地识别与文法匹配的流片段?

示例:

语法

S -> ASB | AB
A -> a 
B -> b

(本质上,一定数量的 a 后跟相同数量的 b)

流:

aabaaabbc...

预期结果:

  1. 匹配从位置 1 开始:ab
  2. 匹配从位置 4 开始:aabb

当然关键是“有效”。没有测试太多无望的候选人太久。关于我的数据,我唯一知道的是虽然语法是任意的,但实际上匹配序列会相对较短(<20 个终端),而流本身会很长(>10000 个终端)。

理想情况下,我还想要一个语法树,但这不太重要,因为一旦识别出片段,我就可以在其上运行一个普通的解析器来获取树。

我应该从哪里开始?哪种类型的解析器可以适应这种类型的工作?

最佳答案

“任意语法”让我建议你看看 wberry 的评论。

这些语法有多复杂?是否有人工干预步骤?

我会努力的。如果我修改了您的示例语法:

S -> ASB | AB
A -> a 
B -> b

包括:

S' -> S | GS' | S'GS' | S'G
G -> sigma*

所以 G = garbage 和 S' 是许多 S 片段,中间有垃圾(我可能对我的生产规则粗心了。你明白了),我想我们可以解决你的问题。你只需要一个解析器来匹配 G 之前的其他规则。你可能必须根据解析器修改这些生产规则。我几乎可以保证会根据解析器更改规则顺序。由于大多数解析器库将词法分析与解析分开,因此您可能需要一个包罗万象的词素,然后修改 G 以包含所有可能的词素。根据您的具体情况,这可能不会比在流中的每个位置开始每次尝试更好(效率方面)。

但是...假设我的生产规则是固定的(既为了正确性也为了解析器的特殊风格),这应该不仅匹配流中的片段,而且应该为您提供整个流的解析树。您只对以类型 S 的节点为根的子树感兴趣。

关于algorithm - 在标记流中解析上下文无关语言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7772487/

相关文章:

algorithm - 二叉树递归层序遍历的时间复杂度是多少

python - 分而治之 - 最小硬币 - 将硬币作为数组返回

c++ - 二叉树之字形层次顺序遍历算法的紧时间复杂度是多少?

datetime - 在 golang 中解析日期

c++ - 使用 C++11 正则表达式捕获上下文无关语法文件的内容

c++ - 迭代差异

c++ - 快速读取带有 float 的文本文件

php - php 中的前缀到中缀

c - C语言中的非上下文无关语言的例子?

context-free-grammar - 上下文无关语法中的左递归规则