[英]Algorithm to generate finite language from non-recursive context-free grammar
我正在搜索一种算法,从非递归的无上下文语法生成完整的有限语言。 该应用程序是为测试自动化生成一组可能的方案。
EBNF中的语法示例(S是起始规则):
S = Sender, Receiver;
Sender = Human | Machine;
Human = "user-type-1" | "user-type-2"
Machine = Access, Protocol;
Access = "internal" | "external";
Protocol = "soap" | "smtp";
Receiver = "local" | "remote";
应该产生一组句子,如:
user-type-1 local
internal soap local
external smtp remote
到目前为止我发现的例子和文献都提到了基于递归语法的随机生成的例子。 但我的问题更简单。 欢迎提供出版物的所有提示,名称或链接。
谢谢,
S.
一种方法是在编程语言中定义语法,然后编写代码以迭代所有可能性。 你的语法是用变量和三个结构来指定的: lit(x)
表示像"local"
这样的文字, alt(a, b, c, ...)
表示选择a
, b
, c
, ...和seq(a, b, ..., z)
表示的一两件事从序列a
,从一件事级联b
等。
这是你那种形式的语法。
Protocol = alt(lit("soap"), lit("smtp"))
Receiver = alt(lit("local"), lit("remote"))
Access = alt(lit("internal"), lit("external"))
Human = alt(lit("user-type-1"), lit("user-type-2"))
Machine = seq(Access, Protocol)
Sender = alt(Human, Machine)
S = seq(Sender, Receiver)
这里有一些完整的(Python)代码,它使用精心选择的alt
, seq
和lit
定义来使每个生产规则成为生成其所有可能性的函数:
import itertools
def seq(*xs):
def r():
for f in itertools.product(*[x() for x in xs]):
yield ' '.join(f)
return r
def alt(*xs):
def r():
for x in xs:
for f in x():
yield f
return r
def lit(x):
def r():
yield x
return r
Protocol = alt(lit("soap"), lit("smtp"))
Receiver = alt(lit("local"), lit("remote"))
Access = alt(lit("internal"), lit("external"))
Human = alt(lit("user-type-1"), lit("user-type-2"))
Machine = seq(Access, Protocol)
Sender = alt(Human, Machine)
S = seq(Sender, Receiver)
for s in S():
print s
您可以递归地生成一个树,其分支将根据语法规则表示派生,其叶子将表示语法语言中的单词。 恢复整个有限语言就像在生成叶子时保存叶子一样简单。
将每个节点表示为符号的有序集合(终端或非终端)。 对于每个非终结符,递归地下降到一组新的节点,其中每个可能的替换都进行。 继续,直到列表中只包含终端符号,然后输出与节点对应的符号的有序串联。 您的初始节点将始终为[S]
。 例:
S = Sender, Receiver;
Sender = Human | Machine;
Human = "user-type-1" | "user-type-2"
Machine = Access, Protocol;
Access = "internal" | "external";
Protocol = "soap" | "smtp";
Receiver = "local" | "remote";
[S]
[Sender, ",", Receiver]
[Human, ",", Receiver]
["user-type-1", ",", Receiver]
["user-type-1", ",", "local"] ***
["user-type-1", ",", "remote"] ***
["user-type-2", ",", Receiver]
["user-type-2", ",", "local"] ***
["user-type-2", ",", "remote"] ***
[Machine, ",", Receiver]
[Access, ",", Protocol, ",", Receiver]
["internal", ",", Protocol, ",", Receiver]
["internal", ",", "soap", ",", Receiver]
["internal", ",", "soap", ",", "local"] ***
["internal", ",", "soap", ",", "remote"] ***
["internal", ",", "smtp", ",", Receiver]
["internal", ",", "smtp", ",", "local"] ***
["internal", ",", "smtp", ",", "remote"] ***
["external", ",", Protocol, ",", Receiver]
["external", ",", "soap", ",", Receiver]
["external", ",", "soap", ",", "local"] ***
["external", ",", "soap", ",", "remote"] ***
["external", ",", "smtp", ",", Receiver]
["external", ",", "smtp", ",", "local"] ***
["external", ",", "smtp", ",", "remote"] ***
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.