C程序源代码可以根据C语法(在CFG中描述)进行解析,最终转化为许多AST。我正在考虑是否存在这样的工具:它可以通过首先随机生成许多AST来做相反的事情,其中包括没有具体字符串值的令牌,只有令牌的类型,根据CFG,然后生成混凝土令牌根据令牌在正则表达式中的定义。
我可以想象第一步看起来像是一个迭代的非终端替换,它是随机的,并且可以受到一定数量的迭代次数的限制。第二步是根据正则表达式生成随机字符串。
有没有可以做到这一点的工具?
答案 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枚举定理的维基百科条目)