基于XML的代码自动生成工具
2015-12-20张琼,黄翩
张 琼,黄 翩
(西安电子科技大学电子信息攻防对抗与仿真重点实验室,陕西西安 710071)
1 技术背景和优势
1.1 代码生成器的技术发展
自动代码生成技术[1]作为一种出现在上世纪的软件开发技术,首先出现在编译器的开发和设计之中,并在此领域获得了广泛应用。在编译器模型中,编译器前段将输入的源程序翻译成一种中间表示,后端以源程序的中间表示为输入,并产生等价的目标程序作为输出。在此编译器的后端就是编译器的代码生成部分。
在这里,自动代码生成并不是指作为编译器后端的代码生成,而是指通过生成器,读取相关的代码或文档中的定义,生成如 C、C++ 、Java、Perl、Ruby、Python及HTML等高级语言代码。
自动代码生成技术从上世纪起步发展以来,取得了长足进步。但随着计算机科学与技术的不断发展,自动代码生成技术也越来越成熟并被广泛应用[2]。
1.2 采用代码生成器的好处
对于软件工程师而言,代码生成技术有如下优点[3]:
(1)保证代码的质量。一个项目周期中大量的手写代码通常会由于软件工程师在编码时不断采用新的或更好的方法而良莠不齐。代码生成技术从编码的初始阶段创建通用模板,而通过修改模板和再次运行代码生成器来对所有已生成的基本代码修正缺陷或优化。
(2)保证代码的一致性。由代码生成器生成的代码在API和变量名上的写法完全一致,这就为使用者提供了易懂易用的接口,更利于分层思想的实现。
(3)产生代码的高效性。一旦模板等设计好后,只需简单的运行代码生成器便可高效地生成用户需求的代码。
(4)利于维护。接口和变量的一致性有利于后续的维护工作。
2 代码生成工具的框架
一般而言代码生成器有着必不可少的3要素:(1)模板。即生成代码的格式和结构模板。(2)元数据。即在代码中需建模的结构相关资源。(3)业务规则。用于指定元数据和行为的规则,这一部分通常封装在代码生成器中[4]。
常见的典型代码生成方式有3种:(1)CORBA中间件所采用的IDL(接口定义语言)的代码生成方式。(2).NET提供的CodeDOM机制。(3)基于XML的生成方式。表1列出了3种方式采用的模板、元数据、业务规则[5]。
表1 3种典型的代码生成方式
由表1可看出,这3种代码生成方式各有不同,但就实现的简易程度而言,基于XML的代码生成技术明显更具优势。其以XML技术和XLST文档转换技术作为支持,而XSLT语言则直接定义文档转换规则,与生成代码采用的语言无关,故可更方便快捷地实现代码的自动生成;而其他两种代码生成方式由于其业务规则与要生成的代码语言相关,而生成某种特定语言,其映射关系的建立一般不由程序员确立[6]。
另外,从发展前景来看,XML具有良好的可读性,方便的可扩展性,数据内容与其形式的分离,可轻松地跨平台应用,适合面向对象的程序开发等多方面优势。人们可通过DOM或SAX等技术对XML数据进行访问;更可通过XPath和XSLT对其进行文档转换,将其转换为其他格式的文档。
基于以上的自动代码生成方式的对比及XML的应用优势,文中选择基于XML的代码生成方式来实现代码生成。
基于XML的代码生成方式是一种常见的典型代码生成方式。其模板语言一般为XSLT;其元数据一般用XML文件记录;其业务规则一般通过XSLT转换语言定义,通过XSLT引擎自动产生代码[7]。基于XML的代码生成工具的整体框架,如图1所示。
图1是具体的代码生成工具的框架。其中,数据文件即三要素中的元数据;模板文件即模板;而业务规则被封装在代码生成工具中。基于XMl的代码生成工具中的数据文件和模板文件均为XML表,代码生成工具则依赖于XML解析器的实现[8]。
3 代码生成工具的实现
图1 代码自动生成工具框架图
由于在雷达系统建模与仿真中存在众多的代码重复编写的问题,为避免人为编写带来不必要的麻烦和错误,文中使用基于XML的代码生成工具来自动帮助生成底层仿真模型代码。为对XML数据进行访问,设计了一个适合于C/C++的基于DOM解析规则的XML解析器。在现有开源软件CMarkUp的基础上,为适应遍历普通树的各个节点的需求,文中对CMarkUp进行了二次封装,重新设计了数据结构,其结构如下:
Typedef struct xmlElem_tag
{
//节点操作
struct xmlElem_tag*parent;//父节点
struct xmlElem_tag*current;//当前节点
struct xmlElem_tag*childHead;//子节点的头结点
struct xmlElem_tag*forward;//前向指针
struct xmlElem_tag*next;//后向指针数组
//数据操作
char* attribHead;//属性指针头结点
int nAttrib;//属性数目
//节点内容
char elemName[MAXLENGTH+1];//节点名称,MAXLENGTH为一个宏
int nDepthElem;//当前节点的在树形结构中的深度
}xmlElem,*pxmlElem;
重新设计后的XML解析器可更容易的进行递归遍历,方便解析XML数据。
对于代码自动生成工具中重要的模板设计,为适应雷达系统建模与仿真的需求,将模板信息分为5大类:(1)系统信息。代码生成后的存放路径、代码生成后的文件名、生成C++代码的类名、成员函数名等。(2)参数信息。时宽、采样频率、发射功率、带宽、脉冲重复周期等。(3)模型的输入信息。发射信号脉冲重复周期类型、发射信号载频类型、发射信号调制类型、发射信号中心载频等。(4)模型的输出信息。输出数据结构体、输出信号类型。(5)模型之间的连接信息。两个模型之间的连接关系,两个模型之间的数据传输。
同时为生成C++代码,必须为头文件(.h)和源文件(.cpp),分别设置模板。为方便管理,将其放在同一XML表中以”template_h”和”template_cpp”节点区别,如图2所示。
图2 XML模板的设计与实现
图3 数据文件交互式界面
为更人性化、交互性更好,给该数据文件配备了可视化的界面,如图3所示。在用户填入需要一些数据后就可点击“选项”页面的“生成C++代码”按钮即可生成所需要代码。假设文件名填入“subTransmitter”其他为默认值,生成代码:
//参数定义模块,主要完成对参数的定义
typedef struct para_subTransmitter_tag
{
double tau;//脉冲宽度
double fs;//采样频率
double band;//带宽
double pt;//发射机瞬时功率
}para_subTransmitter;//参数定义部分
//接口定义模块,主要完成对接口的定义
typedef struct io_subTransmitter_tag
{
//输入接口定义
int in_prtType;//发射信号脉冲重复周期类型
int in_fcType;//发射信号载频类型
int in_modType;//发射信号调制类型
int in_modPhaseType;//发射相位信号调制类型
//输出接口定义
struct signal out_struct;//发射信号结构体
struct pmatMatrix pout_msignal;//发射信号
}io_subTransmitter;//接口定义部分
typedef struct subTransmitter_tag
{
para_subTransmitter paraData;//参数结构体
io_subTransmitter ioData;//输入输出结构体
struct subTransmitter_tag*pm_data;//指向自己的指针
}subTransmitter,*psubTransmitter;//用 户 模 型定义
4 结束语
基于XML的代码生成工具可减少重复代码的编写,降低因手工编写所带来的编码错误,提高代码的质量和编写效率,从而使大规模软件开发和维护更便捷。
[1]管太阳.基于模板的自动代码生成技术研究[D].成都:电子科技大学,2007.
[2]田宇.基于XML的构件组装描述及其代码生成技术研究[D].长沙:中南大学,2006.
[3]范小刚.代码生成技术的探讨与实现[D].广州:中山大学,2004.
[4]苗维杰,李天辉.基于 XML代码生成技术的应用研究[J].电子元器件应用,2009(10):75 -78.
[5]徐爱春,章坚民.基于XML/XSLT代码自动生成技术研究[J].杭州电子工业学院学报,2004,24(4):64 -68.
[6]范秋生.XML的代码生成器的设计与实现[J].长江大学学报:自然科学版,2008,5(1):211 -212.
[7]赵军.基于模板的代码生成器的研究与实现[J].长春师范学院学报:自然科学版,2011,30(6):28 -34.
[8]杨皓,杨忠,吴愚.基于XML脚本的代码生成技术及其应用[J].多媒体技术与应用,2009(3):1712-1713.