我正在尝试设计一种算法,该算法将CFG G和终端符号a作为输入,如果S(G的起始规则)可以生成以a开头的句子形式,则输出yes。即,如果在(T U N)*中存在串α,使得S => *aα,否则它输出no。例如,如果语法是S - > [S] | SS | ε,如果a =],答案是否定的。我不是在寻找代码,我只是想了解如何在伪代码中处理这个主题。
答案 0 :(得分:2)
您可以只运行Earley parser的预测变量,直到它停止预测,并查看它是否生成以相关终端开头的任何规则。
或者从下往上开始,将接受相关终端的所有非终端标记为第一个输入,然后将接受已标记的非终结符号的所有非终结符号标记为第一个输入,并重复直到完成,并查看S是否为在标记的非终结者集合中。
答案 1 :(得分:2)
X
有三种方式可以派生以a
开头的字符串。
X -> a...
X -> A...
形式的规则和A
派生以a
开头的字符串。X -> B A...
和B
派生ε
,A...
派生以a
开头的字符串。您可以使用这些来构建一个算法,该算法查看语法的所有规则,从S -> ...
形式的规则开始,如果rhs以终端开头,则应用check 1;如果是,则应用check 2和3它从一个非终端开始。每个检查对应一个返回布尔值的(可能是递归的)函数。
一个有趣的细节是需要处理语法中的循环,例如单一规则,如A -> A a
,还有A -> B...
,B -> C...
,C -> A...
。如果你不小心,相互递归检查将无限重复。我会告诉你的。想想深度优先搜索如何永远避免图中的循环。
另一个细节是如何确定给定的非终端B是否派生ε
。你应该能够自己解决这个问题,但是如果一切都失败了,那么请查看“可以为空的非终端”。你会发现一个众所周知的小算法。
如果任何检查结果为肯定,则返回yes。其他详尽无遗的规则已经找不到办法。退货号码