逆向分析作为假设策略:从EBNF语法生成示例
hypothesis-grammar的Python项目详细描述
假设语法
(阿尔法之前。。。我试过的东西都很管用,不过还没有经过很好的测试)
这是什么?在
假设语法是一个“反向解析器”——给定一个语法,它将生成该语法的示例。在
它被实现为Hypothesis策略。在
(如果您希望从语法生成文本,而不是使用假设进行测试,那么这个库仍然有用,但我强烈建议您改为使用tools provided with NLTK。)
使用
那么,这个看起来怎么样?在
首先你需要一个语法。我们的语法格式基于Lark parser库使用的语法格式。您可以看到我们的语法解析语法here。语法格式的更多细节below。在
下面是一个使用假设语法的例子:
fromhypothesis_grammarimportstrategy_from_grammarst=strategy_from_grammar(grammar=""" DET: "the" | "a" N: "man" | "park" | "dog" P: "in" | "with" s: np vp np: DET N pp: P np vp: "slept" | "saw" np | "walked" pp """,start="s",)st.example()# ['a', 'dog', 'saw', 'the', 'man']st.example()# ['a', 'park', 'saw', 'a', 'man']st.example()# ['the', 'man', 'slept']
或者作为测试。。。在
^{pr2}$语法取自NLTK文档中的一个示例,并转换为我们的“简化Lark”格式。在
start="s"
告诉解析器开始规则是s
。在
如你所见,我们已经提出了一种假设策略,它能够生成与语法相匹配的例子(在这种情况下,短句有时是有意义的)。在
输出将始终是令牌字符串的平面列表。如果你想要一个句子,你可以" ".join(example)
。在
但是语法并不一定要描述文本,它可能代表一系列动作。在这种情况下,您可能需要将结果标记转换为对象实例,这可以通过查找表完成。在
(但是,如果您要为测试生成操作序列,那么您可能应该首先检查假设stateful testing特性)
语法细节
- 忽略空白
- “Terminals”必须命名为all caps(Terminals only reference literals,not other rules),例如
DET
- “Rules”必须命名为全小写,例如
np
- LHS(名称)和RHS用
:
隔开 - 字符串文字必须用双引号引起来,例如
"man"
- 也可以使用regex文本,它们用正斜杠分隔,例如
/the[a-z]{0,2}/
。regex令牌的内容是使用假设'^{} 策略生成的,其中fullmatch=True
。在 - 相邻的标记连接在一起,即
DET N
表示DET
,后跟N
。在 |
是交替的,所以"in" | "with"
表示"in"
或{}之一 ?
表示可选,即"in"?
表示{}为零次或一次。在 *
即"in"*
意味着{}应为零或多次。在 +
即"in"+
意味着{}被期望一次或多次。在 ~ <num>
的确切意思是-<;num>;次。在~ <min>..<max>
是一个范围,应介于-<;min>;-到-<;max>;次之间。在(
和{}是分组的,可以使用上面的任何一个修饰语来量化这个组。在
- 项目
标签: