Algorithm 给定语法,如何为不完整的字符串找到有效的AST?

Algorithm 给定语法,如何为不完整的字符串找到有效的AST?,algorithm,parsing,grammar,tokenize,Algorithm,Parsing,Grammar,Tokenize,是否有一种已知的算法可以为给定的语法和经过修剪的输入返回可能的语法树 例如,如果给定JSON语法和输入”,1,则有效的输出将是 [“”,1]的语法树,因为这是一个有效的JSON语法树,,1是[“”,1]的子字符串”,1“也将是有效的输出 给定一个简单的数学表达式语法和字符串1),它可以输出(1)-0,因为它是一个包含子字符串1)的有效表达式。这与其说是一个算法,不如说是一个启发式算法,因为我手头没有正确性的证明。它还假设您有一个用于语法的实际LR解析器。(这显然对语法有一定的限制。但这似乎是一个

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

例如,如果给定JSON语法和输入
”,1
,则有效的输出将是
[“”,1]
的语法树,因为这是一个有效的JSON语法树,
,1
[“”,1]
的子字符串<代码>”,1“也将是有效的输出


给定一个简单的数学表达式语法和字符串
1)
,它可以输出
(1)-0
,因为它是一个包含子字符串
1)
的有效表达式。这与其说是一个算法,不如说是一个启发式算法,因为我手头没有正确性的证明。它还假设您有一个用于语法的实际LR解析器。(这显然对语法有一定的限制。但这似乎是一个合理的假设,因为问题陈述或多或少意味着你有某种机制来解析完整的句子。)

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

  • 如果该州有一个或多个reduce操作,请执行其中一个
  • 否则,选择状态中可用的某些移位操作,并将移位的标记作为完成标记输出。然后进行换档操作中指示的转换

上面没有说明如何在可用的减少或转移操作之间进行选择。减少你选择的行动不会有太大的区别,但是如果你一直选择错误的轮班行动,你可能会陷入无休止的循环。随机选择可能是最简单的合理安全的策略。

如果它是有效表达式的子字符串而不是前缀,则缺少该做什么。我想补充一点,在这种情况下,你必须稍微研究一下语言。如果我们只处理数字、圆括号和二元运算符,可能只需在不完整的前导二元运算符前面滑动一个零,然后匹配所有圆括号。当然不是证据。@JerryHalisberry:是的,说得好。我应该更仔细地看一下这些例子。对于Dyck语言(或等效函数),这很容易,而且两个示例都适合这种模式。但在一般情况下,这更难。虽然我认为这是可能的,因为CFG的子字符串集是一个CFG。您可以修改CYK解析算法,以找到与给定片段一致的解析。如果子字符串拆分了复杂的文字值(如引号字符串或嵌套注释),尝试解析实用语言的子字符串可能会遇到真正的麻烦,因为您不确定要分析的子字符串是否以文本片段开头。OP的例子,“1是一个有趣的例子,你可以为[”,1 ]争辩,但你也可以为[,1 ]争论。为了避免这个困难,你应该考虑考虑个体字符来定义语法。