任何工具都可以根据语言语法随机生成源代码?

时间:2010-12-17 05:54:14

标签: random compiler-construction context-free-grammar

C程序源代码可以根据C语法(在CFG中描述)进行解析,最终转化为许多AST。我正在考虑是否存在这样的工具:它可以通过首先随机生成许多AST来做相反的事情,其中​​包括没有具体字符串值的令牌,只有令牌的类型,根据CFG,然后生成混凝土令牌根据令牌在正则表达式中的定义。

我可以想象第一步看起来像是一个迭代的非终端替换,它是随机的,并且可以受到一定数量的迭代次数的限制。第二步是根据正则表达式生成随机字符串。

有没有可以做到这一点的工具?

4 个答案:

答案 0 :(得分:4)

“数据生成语言”DGL执行此操作,增加了对输出语法中的作品概率进行加权的能力。

通常,递归下降解析器可以直接重写为一组递归过程,以生成语言,而不是解析/识别语言。

答案 1 :(得分:1)

鉴于语言的无上下文语法,可以generate a random string that matches the grammar

例如, nearley 解析器生成器包含可以从语法生成字符串的an implementation of an "unparser"

使用Prolog中的明确句子语法可以完成相同的任务。使用明确子句语法的句子生成器的示例是here

答案 2 :(得分:0)

如果你有一个标准化形式的语法模型(所有这样的规则):

 LHS = RHS1 RHS2 ...  RHSn ;

和语言prettyprinter(例如,AST到文本转换工具),你可以很容易地构建其中一个。

只需将目标符号作为单位树开始。

  Repeat until no nonterminals are left:
    Pick a nonterminal N in the tree;
       Expand by adding children for the right hand side of any rule
       whose left-hand side matches the nonterminal N

对于带有值的终端(例如,变量名,数字,字符串......),您必须生成随机内容。

上述算法的一个复杂因素是它没有明确终止。你真正想要做的是选择一些树的大小限制,并运行算法,直到所有非终结符号消失或你超过限制。在后一种情况下,回溯,撤消最后一次替换,并尝试其他方法。这将使您有条不紊地深度搜索您确定大小的AST。

然后将结果打印出来。它是prettyprinter part很难做到的。

[你可以自己构建所有这些东西,包括prettyprinter,但这是相当多的工作。我直接以语言参数化方式构建包含所有这些机器的工具;看我的生物]。

即使是格式良好的AST,一个令人讨厌的问题是它们可能是荒谬的;对于不允许这种情况的语言,您可能会生成一个整数X的声明,并为其指定一个字符串文字值。您可以消除一些简单的问题,但语言语义可能非常复杂,以C ++为例。确保你最终得到一个语义上有意义的程序是非常困难的;本质上,您必须解析生成的文本,并执行名称和类型解析/检查。对于C ++,您需要一个完整的C ++前端。

答案 3 :(得分:0)

随机生成的问题在于,对于许多CFG,输出字符串的预期长度是无限的(使用与非终端符号对应的生成函数和对应于规则的方程,可以容易地计算预期长度。语法);你必须以某种方式控制制作的相对概率,以保证收敛;例如,有时,将非终端符号的每个生产规则加权与其RHS的长度成反比

在这个问题上有很多: Noam Chomsky,Marcel-Paul Sch \“{u} tzenberger,”The Context of Free Context of Context-Free Languages'',pp。\ 118-161 in P. Braffort and D. Hirschberg(eds。),Computer Programming and Formal系统,北荷兰省(1963) (参见关于Chomsky-Schützenberger枚举定理的维基百科条目)