C代码生成的优雅方式
作者:互联网
我目前正在开发一个与数据库相关的项目,我在其中生成了大量的C代码.然后编译此代码并将其作为动态库加载.我使用这种技术为数据库模式和查询构建有效的代码.
目前,我使用简单的文件写入来生成代码(对于概念验证实现来说还可以).现在,我正在寻找一种更优雅但可比较的灵活解决方案来生成C代码.
我搜索了很多,但到目前为止我发现的所有解决方案都相当复杂/广泛,效率不够,或者不够灵活.
您在C项目中使用哪些库来生成代码?
最好,
莫里茨
解决方法:
您可以使用program transformation system (PTS)以可靠的方式定义和组合代码模板.
大多数PTS允许一个人定义语法,然后使用该语法将源代码解析为AST.更重要的是,它们接受模式:源代码片段(通常是非终结符或非终结符列表),其占位符对应于格式良好的子片段(非终结符表示子树).这些模式通常坚持命名占位符匹配相同(参见下面的示例).这些模式可用于匹配解析的AST,作为使用表面语法查找代码片段的方法.
所以,有人可能会使用一种模式:
pattern x_squared(t: term): product
= " \t * \t ";
寻找由相同子树的产品组成的子表达式.
这将匹配
(p + q[17])*(p+q[17)
但不是
2 * (x-3)
但同样有趣的是,通过使用绑定值(树)为变量实例化模式,可以将这些模式用作代码生成器.所以,
“实例化x_squared(2 ^ x)”产生
(2^x)*(2^x)
就其本身而言,这只是一种奇特的宏观方案.它要好得多,因为它可以告诉你“在编译时”(对于模式)你的作曲是否有意义.因此,您可以对代码片段的组成进行类型检查.例如,您可能会意外编写“实例化x_squared(int q)”,但是好的PTS会反对“int q”不是“term”;你在构建代码生成器时发现了这个bug.
这真的很有趣的地方是可以从许多不同的模式构建许多不同的代码片段,并用更多的模式组合这些片段.这允许人们构建非常复杂的代码.所有这些都是(语法类型)安全的方式;结果树是有效的语法. (你仍然可以使用bollix语义;没有什么是完美的).由于您可以生成的代码的复杂性增加,因此最好进行额外的检查以帮助您避免生成错误的代码.
PTS还有一个额外的优势:在编写代码片段之后,它可以应用源到源的转换来优化生成的代码.因此,您可以根据编写匹配转换的能力以及利用代码生成期间的知识生成优化代码.
想象一下,您为矩阵乘法生成代码:
... P * Q ...
并且您的代码生成器以某种方式或其他方式知道Q是一个单位矩阵.
然后,以下优化可以删除昂贵的矩阵乘法:
rule optimize_matrix_times_unit(m: term, n: term): product -> product
" \m * \q "
-> " \m "
if is_identity_matrix(q)
此转换利用生成的代码中的模式匹配(以查找矩阵产品),模式实例化(以生成匹配产品的替换)以及代码生成可以执行的附加知识或分析(is_identity_matrix).
您需要一个能够处理C解析的PTS;那些有点难找.我设计的那个(DMS Software Reengineering Toolkit)就是这么做的.这个答案中的例子是DMS风格.
这是a technical paper,描述了DMS在C代码上完成的大规模再造任务.本文中的一些例子实际上是用于实例化代码的非常复杂的模式;重新设计任务必须为现有的代码块生成一组新的API.
标签:c,code-generation 来源: https://codeday.me/bug/20191005/1856570.html