我正在生成C ++代码,看起来它会变得非常混乱,即使我的简单生成类已经有很多特殊情况。以下是现在的代码:http://github.com/alex/alex-s-language/tree/local%2Fcpp-generation/alexs_lang/cpp。
答案 0 :(得分:9)
我写了Cog部分是为了从XML数据模式生成C ++代码。它允许您使用嵌入在C ++源文件中的Python代码来生成C ++源代码。
答案 1 :(得分:7)
我用于代码生成的一种技术是完全不用担心代码生成器中的格式化问题。然后,作为生成代码后的下一步,通过indent
运行它以合理地格式化它,以便您可以读取(更重要的是,调试)它。
答案 2 :(得分:4)
请参阅Tooling to Build Test Cases。
目前尚不清楚你的问题是什么。
如果您质疑“我如何处理生成类中的所有特殊情况?”那么这里有一些建议。如果您的问题不是其他问题,请更新您的问题。
使用模板生成器。例如,Mako会让您的生活变得更简单。
写下结果的示例。用${thing}
占位符替换部件。由于您从一些有用的东西开始,将其转换为模板很容易。
在使用其他语言生成代码时,您需要将其他所有类定义用于灵活组装。您希望生成尽可能少的新代码。你想调整和定制一点,但你不想从头开始生成很多东西。
特殊情况最好用普通多态进行处理。公共超类的单独子类可以实现各种异常和特殊情况。 策略设计模式可以很好地处理非常复杂的情况。
本质上,您有Python类来表示真实世界的对象。这些类具有适合C ++模板的属性,以生成这些对象的C ++版本。
答案 3 :(得分:1)
我同意S.Lott的意见,你应该写出你想要生成的例子。
解决代码生成问题应该比不使用代码更复杂。
这是因为您的整个程序必须处理大量输入信息,并且如果该信息的子集很少变化,例如每周一次,则代码生成器只需要对该子集进行条件化。生成的代码条件对剩余输入的更改频率更高。 这是一种分而治之的策略。另一个名称是“部分评估”。
生成的代码也应该运行得更快,因为它不那么通用。
在您的特定情况下,在2次(或更多次)传递中进行代码生成没有任何害处。与传递1一样,您生成声明。在第2阶段,您将生成流程代码。或者,您可以生成两个输出流,并在最后连接它们。
希望有所帮助。对不起,如果我只是说明显的话。
答案 4 :(得分:1)
正如Ned建议的那样,Cog是编写样板代码的绝佳工具。例如,我必须为某些类编写一个AOP风格的事件系统支持,它可以像这样工作:
所以我做了一个特殊的python声明函数,我将在一个cog区域上调用它,它将为每个方法和事件生成样板声明和定义。在cog区域的末尾,用户为隐藏实现的函数放置一个代码块,并由AOP包装器调用,大致如下:
class MyFoo
{
public:
/*[[[cog
import myAOPDeclarators
AOP = myAOPDeclarators.AOP
AOP.declareAOPInterceptorMethod( 'invokeSomeStuff' , '(int param1, std::string param2)' )
]]]*/
//AOP wrapper
void invokeSomeStuff_ImplementationAOP(int param1, std::string param2);
void invokeSomeStuff(int param1, std::string param2) {
sendAOPPreEvent( param1 , param2 , "invokeSomeStuff" );
invokeSomeStuff_ImplementationAOP( param1 , param2);
}
void invokeSomeStuff_ImplementationAOP(int param1, std::string param2)
//[[[end]]]
{
// ...invokeSomeStuff implementation, not automatically generated
}
我可以为您提供代码生成的最佳指南; 使您生成的代码与您手写的代码一样可读。它使代码生成的使用变得透明(甚至比模板代码更透明,购买YMMV),当然,正如Greg建议的那样,缩进可以在之后应用,因此浪费时间混合缩进修改代码生成真的没有意义如果工具可以反过来处理源文件
答案 5 :(得分:0)
我有一个代码生成系统,我采用的最佳选择之一就是将大部分结果程序放在非生成代码中,例如:库/运行时。使用模板也很有效。复杂的模板系统可能难以手工操作,但是您不能手动使用它们,因此可以利用它。
答案 6 :(得分:0)
它实际上只是直接向下递归,除了我需要将所有函数声明拉出来并将它们放在其他地方,并且事实上对于所有函数调用我需要构建所有参数的向量,然后传递因为C ++没有vector的语法。
答案 7 :(得分:0)
我也在寻找这样的东西并找到了这个问题。我对cog并不是很满意,所以我最后编写了自己的内容,这类似但增加了一些(imo)非常需要的功能。