【问题标题】:Searching/predicting next terminal/non-terminal by CFG/Tree?通过 CFG/Tree 搜索/预测下一个终端/非终端?
【发布时间】:2021-03-16 18:54:00
【问题描述】:

我正在寻找算法来帮助我预测给定字符串/前缀和上下文无关语法的下一个标记。

第一个问题是代表 CFG 的确切结构是什么。看起来它是一棵树,但是什么类型的树呢?我问是因为叶子总是有序的,是否有有序树? 可能如果我知道正确的结构,我可以找到自下而上 search 的算法!

如果它不完全是 搜索 问题,那么下一个最接近的事情就是 Parsing 前缀字符串,然后 Generating下一个令牌?我该怎么做?

任何想法


我当前生成的语法很简单,它没有 OR 规则(除非我决定将语法重用于新序列,否则我会这样做)。它由 Sequitur 算法生成,被称为 SLG(单行语法).. 但如果我使用许多 seq 生成它,则 TOP 规则将是 Ex:>

S : S1 z S3 | u S2 .. S5 S1 | S4 S2 .. |... | Sn 
S1 : a b
S2 : h u y
...

..即头重脚轻的 SLG,除了 top 规则,其他所有规则都没有 OR |


作为旁注,我正在考虑将其转换为 Prolog 和/或 DCG 程序的方法,哪里可能有更简单的方法来轻松地做我想做的事?!你觉得呢?

【问题讨论】:

  • 您需要多准确的预测?您只是想要一个可能的下一个令牌还是想要完整的集合?
  • 我也不确定“代表 CFG 的确切结构是什么”是什么意思。 CFG 是一组无序的产生式,每个产生式都将一个非终结符映射到一个有序的可能为空的语法符号序列上。那不是很像树。例如,具有有序子级的树状结构显示为解析的表示。
  • 我想要的可能是几个结果... 2-3
  • 是的.. 作品是无序的,但每个作品的主体(如果不是 | )都是有序的.. 我忽略了 OR 案例 ..... 因为到目前为止,它们总是只有并且,除了 TOP 制作 ..sorry

标签: parsing search code-generation prediction context-free-grammar


【解决方案1】:

TL;DR:抽象地说,这是一个难题。但对于给定的语法,它可能非常简单。一切都取决于语法的性质。


基本算法确实是从对前缀使用一些解析算法开始的。然后可以通过尝试使用每个可能的标记继续解析来做出粗略的预测,只保留那些不会立即产生错误的标记。

这肯定会给你一个列表,其中包括所有可能的延续。但该列表也可能包括不能出现在正确输入中的标记。实际上,正确的列表可能是空的(因为给定的前缀不是任何正确输入的前缀);如果解析算法无法正确验证令牌序列是否是可能的前缀,则会发生这种情况。

在某种程度上,这将取决于语法本身。例如,如果语法是 LR(1),则 LR(1) 解析算法可以精确识别延续集。如果对于某些 k>1 的文法是 LR(k),那么理论上可以为相同的语言生成 LR(1) 文法,但生成的文法可能大得不切实际。否则,您可能不得不接受“误报”。如果您的目标是提供制表符补全,这可能是可以接受的,但在其他情况下它可能不是那么有用。

用于执行内部解析和替代探索的精确数据结构将取决于所使用的解析算法。许多解析算法,包括内部数据结构为简单堆栈的标准 LR 解析算法,具有可变的内部状态,并不真正适合探索步骤;您可以通过在处理每个试验令牌之前复制整个内部数据结构(即堆栈)来调整这种算法。或者,您可以实现一个写时复制堆栈。但是解析器堆栈通常不是很大,因此每次复制它通常是可行的。 (这就是 Bison 使用“预期令牌”列表生成扩展错误消息的方法,实际上它似乎不会触发不可接受的运行时开销。)

或者,您可以使用 CYK 图表解析的某些变体(或 Earley 算法等 GLR 算法),其内部数据结构可以以不涉及破坏性修改的方式实现。这种算法通常用于不是 LR(1) 的文法,因为它们可以处理任何 CFG,尽管高度模糊的文法可能需要很长时间来解析(与输入长度的立方成正比)。但是,如上所述,您会从此类算法中得到误报。

如果误报是不可接受的,那么您可以使用某种启发式搜索来尝试找到完成试验前缀的输入序列。这在理论上可能需要相当长的时间,但对于许多语法而言,广度优先搜索可以在合理的时间内找到完成,因此您可以在给定的最长时间后终止搜索。这不会产生误报,但时间限制可能会阻止它找到完整的可能延续集。

【讨论】:

  • 到目前为止,我当前生成的语法很简单,它没有 OR 规则(除非我决定将语法重用于新序列)。它由 Sequitur 算法生成,被称为 SLG(单行语法).. 但如果我使用许多 seq 生成它,则 TOP 规则将是 > S : S1 | S2 | S3 |... |锡..即头重脚轻的SLG
  • @sten:如果您的语言是有限的,那么解决方案会简单得多。但这已在我的总结陈述中涵盖:一切都取决于语法的特定性质。如果您可以写一个更具体的问题,您可以获得更具体的答案。 (但请提出一个新问题,而不是编辑这个问题。)
  • 刚刚测试过 ;) 将 CFG 转换为 DCG,然后 Prolog 会休息,即解析和预测......现在只需要弄清楚如何使用差异列表而不是 DCG 将 CFG 实现/转换为纯 Prolog,因为基于 python 的 Prolog 不支持 DCG ! :) 谢谢..
猜你喜欢
  • 2015-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-18
  • 2014-10-24
  • 1970-01-01
  • 2014-09-04
  • 2018-10-04
相关资源
最近更新 更多