GNU第1.4.2代

基于模板的参数化文本生成器

通过洛伦佐贝蒂尼


目录



Gengen公司(发电机发电机)是一种工具,从开始参数化文本(称为模板)生成一个文本生成器可以用值替换参数。

目前Gengen可以生成C++或C代码;然而其他目标语言正在开发中(例如Java)。

Gengen是自由软件;您可以自由使用、共享和修改在下面GNU通用公共许可证的条款(请参阅复制).

根根的主页是http://www.gnu.org/software/gengen

请参见新闻文件用于中的新功能摘要release和ChangeLog的完整列表更改源

您还可以在我的博客上找到有关新功能的详细信息,请访问以下区域:http://tronprog.blogspot.com/search/label/gengen.

下载

您可以从GNU的ftp站点下载:
ftp://ftp.gnu.org/gnu/gengen/或从其中一个后视镜(请参见http://www.gnu.org/prep/ftp.html).

我不再分发Windows二进制文件;因为,他们可以通过使用轻松构建Cygwin公司++编译器,可在获取网址:http://www.cygwin.com/.然而,如果你不想下载这样的编译器,你可以请求二进制文件直接发送给我,通过电子邮件发送(请在我的主页),我可以发送给你。

执行安装的步骤是标准的包装以源代码形式:一旦您将源代码解压缩到一个目录中,“cd”到包含包源代码的目录,并执行下列的步骤:

./配置
制作
进行安装
注意:除非您通过指定不同的安装目录--前缀配置选项(例如。./configure--prefix=<您的主页>),您必须是root用户才能进行“make install”。

匿名Git访问

可以通过以下方式签出此项目的git存储库克隆指令:

git克隆git://git.savannah.gnu.org/gengen.git

有关更多说明,请访问以下地址:

http://savannah.gnu.org/projects/gengen.

git存储库也可以在线浏览

http://git.savannah.gnu.org/cgit/gengen.git.

自版本1.4.2的GengenCVS存储库被驳回,转而支持Git(网址:http://git-scm.com/).

请注意,这样您将获得最新的开发源也可能是不稳定的。此解决方案是如果你想修改/扩展这个程序,最好是:你应该给我发邮件针对最新git存储库源的补丁。

相反,如果您想获得给定版本的源代码,通过git,例如,版本X.Y.Z,必须指定标记相关X_Y_Z.

当您编译从git存储库获得的源代码时,在运行之前配置制作命令,用于第一次,必须运行以下命令:

自动识别-i

这将以正确的顺序运行autotools命令,并复制可能缺少文件。您应该已经安装了最新版本的汽车制造自动配置文件为了这个成功。

简单示例

假设您正在编写C/C++程序,并且在某个时候您的程序必须生成以下代码:
如果(i<10)
printf(“i的值是%d”,i);

编写这段C++代码并不难:

cout<<“if(i<10)”<<endl;
cout<<“printf(“i的值是%d”,i);”<<endl;

或C代码:

printf(“如果(i<10)\n”);
printf(“printf”(“i的值是%%d”,i);\n“);

只要你记得逃离"(和在C代码,以及%).

假设现在必须生成前一段代码时间取决于您的程序,而不是每次另一个必须生成符号(在运行时决定)。在这种情况下,假设这个值包含在一个变量中符号生成此代码的代码会多一点复杂:

cout<<“if(”<<symb<<“<10)”<<endl;
cout<<“printf(“<<symb<<”的值为%d\”,“
<<symb<<“);”<<endl;

而C版本则更加模糊。

也许你甚至没有意识到你忘了离开前面的空格< 10; 基本上这是由于事实这段代码混合了必须生成的代码使用生成它的代码,这往往会使这一部分程序不太容易维护。特别是如果有一天你必须更改必须生成的代码要执行程序的这一部分,您可能必须执行一些测试以确保您做得正确。

如果您必须生成的代码稍微复杂一些,这项任务很容易让人头疼!

如果你能在一个单独的文件,我们称之为模板,说吧测试1.cc_skel这种方式

如果(@i@<10)
printf(“@i@的值是%d”,@i@);

并有一个生成生成器的工具可以使用必须替换为的值在运行时实例化这个参数 ? 如果存在这样的工具,并且它生成了文件测试1_c.h使用C结构测试1生成结构,然后您可以简单地在另一个文件中编写此代码,比如测试1_gen_c.c:

     #包括 <标准o.h>
     
     #包括 “测试1_c.h”
     
     整数main(){结构测试1生成结构生成结构;
发电机结构=“foo”;
生成测试1(标准输出,&gen_struct,0);
打印("\n个");
生成结构.i=“酒吧”;
generate_test1(标准输出,&gen_struct,0);
打印("\n个");

返回0;
}

或者,如果它生成了一个文件测试1.h使用C++类测试1生成类,然后您可以在比如说,另一个文件测试1_gen.cc:

     #包括 <iostream>
     
     使用标准::cout;
使用标准::endl;

#包括 “测试1.h” 整数main(){测试1生成类生成类;发电机类别集i(“foo”);
gen_class.generate_test1(cout);
cout<<endl;
发电机类别集i(“酒吧”);
gen_class.generate_test1(cout);
cout<<endl;

返回0;
}

当您运行它时,您将获得预期的输出:

如果(foo<10)
printf(“foo的值是%d”,foo);
如果(bar<10)
printf(“条的值为%d”,条);

好吧,Gengen做得对!现在,代码必须并且生成它的代码是分开的,它们可以更容易维护:如果您想更改必须生成您对文件的操作测试1.cc_skel; 或者说您需要更改将被替换的值,你只需更改文件测试1_gen.cc测试1_gen_c.c.

请注意,该方法生成_测试1接受输出流(实际上,在本例中是标准输出流高级定制使用),因此可以利用流抽象设施。类似地C函数生成_测试1接受文件*,因此您可以使用C文件抽象。

实际上,为了生成C++文件测试1.h和全班一起测试1生成类,我只需运行以下命令:

gengen-i test1.cc_skel--文件名test1.h--gen-name test1

为了生成C文件测试1_c.h用结构测试1生成结构,我只需运行以下命令:

gengen-i test1.cc_skel--文件名test1_c.h--gen-name test1\
--输出格式=c

如果我引起你的注意,你想知道关于这些选项和Gengen更高级功能的更多信息,我希望您继续阅读:-)

Gengen手册

用于安装Gengen及其所有高级功能卷入的示例,请阅读info版本和html格式版本.