【问题标题】:Given a grammar, how to find a valid AST for an incomplete string?给定一个语法,如何为不完整的字符串找到有效的 AST?
【发布时间】:2021-04-11 18:11:53
【问题描述】:

是否有一种已知算法可以返回给定语法和修剪输入的可能语法树?

例如,当给定 JSON 语法和输入 ",1 时,有效输出将是 ["", 1] 的语法树,因为这是一个有效的 JSON 语法树,而 ",1["",1] 的子字符串。 ",1" 也是一个有效的输出。

给定一个简单的数学表达式语法和字符串1)-,它可以输出(1)-0,因为它是一个包含子字符串1)-的有效表达式。

【问题讨论】:

  • 您或许可以修改 CYK 解析算法以找到与给定片段一致的解析。
  • 如果子字符串拆分了复杂的文字值(例如带引号的字符串或嵌套注释),尝试解析实用语言的子字符串可能会非常麻烦,因为您不确定要解析的子字符串是否以文字片段。 OP 的 ",1" 示例是一个有趣的案例;您可以为 ["",1] 争论,但您也可以为 [",1"] 争论。为了避免这种困难,您可能应该考虑根据以下方式定义语言语法单个字符。

标签: algorithm parsing grammar tokenize


【解决方案1】:

这更像是一种启发式而不是算法,因为我手边没有正确性证明。它还假设您有一个实际的 LR 语法分析器。 (显然,这对语法施加了某些限制。但这似乎是一个合理的假设,因为问题陈述或多或少暗示您有一些机制来解析完整的句子。)

然后您可以在输入上运行解析器,直到到达最后一个输入标记。如果解析器在使用最后一个输入符号之前到达错误操作,则输入不是任何有效句子的前缀,因此您可以报告失败。 (您可以尝试找到一个类似的字符串,它是有效句子的前缀,但这远远超出了本问题的范围。)如果您最终处于输入结束标记上接受操作的状态,那么你已经有了一个有效的解析,所以没有必要继续。否则,请执行以下操作,直到您在输入结束标记上达到接受操作的状态:

  • 如果状态有一项或多项减少操作,请采取其中一项。
  • 否则,选择状态中可用的一些移位动作,并将移位后的令牌作为完成令牌输出。然后进行换档动作中指示的转换。

以上内容并未说明如何在可用的 reduce 或 shift 操作之间进行选择。减少您选择的动作不应该有太大的区别,但是如果您一直选择错误的换档动作,您可能会陷入无限循环。随机选择可能是最简单且安全的策略。

【讨论】:

  • 如果它是有效表达式的子字符串但不是前缀,则缺少该做什么。我要补充一点,在这种情况下,您将不得不稍微研究一下语言。如果我们只处理数字、括号和二元运算符,则可能只是在不完整的前导二元运算符前面滑一个零,并匹配所有括号。当然不是证明。
  • @JerryHalisberry:是的,好点。我应该更仔细地查看这些示例。对于 Dyck 语言(或功能等价物),这很容易,并且两个示例都符合该模式。但在一般情况下,它更难。虽然我认为这是可能的,因为 CFG 的子字符串集是 CFG。
猜你喜欢
  • 2015-07-21
  • 2012-04-02
  • 2018-01-05
  • 1970-01-01
  • 2014-01-14
  • 1970-01-01
  • 2014-05-24
  • 2022-12-04
  • 1970-01-01
相关资源
最近更新 更多