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

Random 任何工具都可以根据语言语法随机生成源代码?,random,compiler-construction,context-free-grammar,Random,Compiler Construction,Context Free Grammar,C程序源代码可以根据C语法(在CFG中描述)进行解析,并最终转换为许多AST。我正在考虑是否存在这样的工具:它可以做相反的事情,首先随机生成许多AST,根据CFG,其中包括没有具体字符串值的令牌,只是令牌的类型,然后根据正则表达式中令牌的定义生成具体令牌 我可以想象第一步看起来像一个迭代的非终端替换,它是随机的,并且可以受到一定数量的迭代次数的限制。第二步是根据正则表达式随机生成字符串 有什么工具可以做到这一点吗?数据生成语言可以做到这一点,它增加了对输出语法中的生成概率进行加权的能力 通常,递

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

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

有什么工具可以做到这一点吗?

数据生成语言可以做到这一点,它增加了对输出语法中的生成概率进行加权的能力


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

给定一种语言的上下文无关语法,可以

例如,nearley解析器生成器包括可以从语法生成字符串的


同样的任务也可以在Prolog中使用definite子句语法来完成。给出了一个使用定分句语法的句子生成器示例。

如果您有一个规范化形式的语法模型(所有规则如下所示):

和语言预打印器(例如,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提供有界深度优先搜索

然后将结果打印出来。这是一个很难纠正的问题

[您可以自己构建所有这些东西,包括预打印程序,但这是一项相当大的工作。我以语言参数化的方式直接构建包含所有这些机器的工具;请参阅我的简历]


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

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

有关这一主题的更多信息,请参见: Noam Chomsky,Marcel Paul Sch\“{u}tzenberger,`上下文无关语言的代数理论',第118-161页,P.Braffort和D.Hirschberg(编辑),《计算机编程与形式系统》,北荷兰(1963年)
(参见维基百科关于乔姆斯基-舒滕贝格计数定理的条目)

但是……为什么?:p我想你可以——如果你遵循CFG规范,你肯定会得到至少在语法上有效的C代码。但我认为从来没有人尝试过这样的事情——你可能需要编写某种反向解析器……我已经与一些人合作过了……(这是一个笑话;我爱我所有的同事).是否有任何理由希望随机、无意义的源代码(很可能)什么都不做?是的,例如,为编译器/解释器提供随机测试用例生成器,或者只是为了好玩。请注意,除了模糊测试之外,很难维护测试用例的正确性以确保上下文的正确性(例如,同一范围内没有重复的变量声明)或类型正确性
  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