[英]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.