确定是否可以在 CFG 中模糊地派生字符串
Determine if a string can be derived ambiguously in a CFG
我知道给定一个特定的上下文无关语法,要检查它是否有歧义需要检查是否存在任何可以以不止一种方式派生的字符串。这是不可判定的。
但是,我有一个更简单的问题。给定一个特定的上下文无关文法和一个特定的字符串,是否可以确定字符串是否可以从文法中模糊地导出?是否有通用算法来执行此检查?
是的,您可以使用任何通用的解析算法,例如GLR (Tomita) parser, an Earley parser, or even a CYK parser;所有这些都可以在 O(N3) 时间和 space 内生成一个解析 "forest"(即所有可能的解析器的有向图)。创建解析森林比 "parsing"(即识别)要复杂一些,但是维基百科文章中引用了一些已知的算法。
由于广义解析算法会找到所有可能的解析,您可以放心,如果恰好为字符串找到一个解析,则该字符串没有歧义。
我会远离此算法的 CYK 解析,因为它需要将语法转换为 Chomsky 范式,这使得恢复原始解析树更加复杂。
Bison 将对所有可能不明确的产品生成 GLR parser, if requested, so you could just use that tool. However, be aware that it does not optimize storage of the parse forest, since it is expecting to produce only a single parse, and therefore you can end up with exponentially-sized datastructures (which then take exponential time to construct). That's usually only a problem with pathological grammars, though. Also, you will have to declare a custom %merge
function;否则,如果可以进行不止一次解析,Bison 生成的解析器将失败并出现 "ambiguous parse" 错误。
我知道给定一个特定的上下文无关语法,要检查它是否有歧义需要检查是否存在任何可以以不止一种方式派生的字符串。这是不可判定的。
但是,我有一个更简单的问题。给定一个特定的上下文无关文法和一个特定的字符串,是否可以确定字符串是否可以从文法中模糊地导出?是否有通用算法来执行此检查?
是的,您可以使用任何通用的解析算法,例如GLR (Tomita) parser, an Earley parser, or even a CYK parser;所有这些都可以在 O(N3) 时间和 space 内生成一个解析 "forest"(即所有可能的解析器的有向图)。创建解析森林比 "parsing"(即识别)要复杂一些,但是维基百科文章中引用了一些已知的算法。
由于广义解析算法会找到所有可能的解析,您可以放心,如果恰好为字符串找到一个解析,则该字符串没有歧义。
我会远离此算法的 CYK 解析,因为它需要将语法转换为 Chomsky 范式,这使得恢复原始解析树更加复杂。
Bison 将对所有可能不明确的产品生成 GLR parser, if requested, so you could just use that tool. However, be aware that it does not optimize storage of the parse forest, since it is expecting to produce only a single parse, and therefore you can end up with exponentially-sized datastructures (which then take exponential time to construct). That's usually only a problem with pathological grammars, though. Also, you will have to declare a custom %merge
function;否则,如果可以进行不止一次解析,Bison 生成的解析器将失败并出现 "ambiguous parse" 错误。