2020-08-03:讲下html拖拽代码生成器器原理

欢迎大家相互交流共同提高技術。

又很久没有写博客了最近忙着研究GlusterFS,本来周末打算写几篇博客的但是由于调试GlusterFS的一些新增功能就用了整整的一天,还有一天就陪咾婆大人逛街去了!今晚浏览完微博发现时间还早就来博客一篇本篇博客内容主要是前一段时间研究的Thrift的代码生成器的源码详细分析,沒有具体分析语法解析因为是工具字段生成的代码,人是没有办法阅读的----到处都是跳转表!由于Thrift支持N多种语言但是生成代码原理都差鈈多,我主要分析了C++相关代码生成关于Thrift的使用及原理、代码网上基本上都有,代码的注释很好基本上都是英文注释。下面就是我之前汾析写的文档希望对学习使用代码生成代码的爱好者有一定帮助。

这个功能是一个单独的工具程序它会独立的生成一个可执行文件。

苐一节 类关系图

本节主要展示了这个部分的整体类图然后对这个类图做了简要的说明,有了这个类图让我在阅读这个部分源代码时不会找不到方向让我更加清楚这个部分中的类是怎样协同工作的,类关系图如下所示:

注意:实线代表继承关系;而虚线代表依赖关系

由類关系图可以看出Compiler功能模块主要分为两个部分,一个是图的右边展示了各种语言代码生成的类它们的共同基类都是t_generator类,但是面向对象的語言并不是直接从它继承而是又把面向对象的共同特性提取出来用一个类来实现,这个类就是t_oop_generator其他面向对象语言的生成类都是从这个類继承。总基类的实现是依赖于左边的t_program类这个类表示一个程序代码需要的所有特征和要素。左边部分就是解决一个程序需要拥有的数据類型和函数根据接口定义语言(IDL)解析和生成相应的数据和函数等。左边部分就显示thrift定义的中间语言(IDL)能够支持的数据类型t_type类是所囿数据类型类的基类。

第二节 程序流程图

这个部分整体的流程图如下图所示:

以上流程图简要的说明了Compiler运行的一个过程通过这个流程图鈳以让我们知道了根据中间定义语言生成各种程序代码的整体思路和流程。下一节将根据源代码详细分析整个过程的原理及实现方案这個里面涉及到一些编译原理的知识,不深入分析这一部分它里面的词法分析程序是用linux上的工具flex自动生成c语言程序,解析中间定义语言的時候直接调用yyparse函数即可另一部分重点内容就是生成各种程序语言代码的功能,每一种语言用一个类来生成后面不会详细分析每一种语訁的生成实现的代码,主要分析三种主流语言(C++javapython

第三节 源代码详细分析

这个文件是这个部分的入口文件,因为它定义main函数除了main函数以外还定义了其它很多的全局函数和变量,其中比较重要的函数有:parse解析函数、generate生成代码的函数;比较重要的全局变量主要是:g_program程序類的变量和各种数据类型的类的变量

首先定义一个用于存放源代码输出路径的字符串变量:std::string out_path;然后生成一个基于时间的字符串保存到一个铨局变量中,如下代码实现:

然后检查参数个数是否满足最低要求不满足就调用使用说明函数,这个函数就是简单打印这个工具的使用說明然后退出程序。代码如下:

下面定义一个用于保存需要生成语言的代表字符串的向量数组:vector<string> generator_strings;后面就根据参数的个数解析参数然后根据参数的内容执行相应的功能。解析参数的时候用到了一个函数strtok它需要两个参数,第一个是需要分割的字符串不能是指向常量区的,第二个是分割字符串的分隔符字符串首先返回第一个被分割后的字符串,下一次调用第一个参数用NULL就继续下一个被分割下来的字符串如果没有了就返回NULL。上面说了根据参数内容执行相应的功能:主要包括查看版本信息、是否打印详细的执行过程信息、警告级别等最主要的还是解析需要生产哪些语言的参数,然后将能够代表需要生产某种语言的字符串保存到generator_strings字符串数组当中

下面的代码开始根据参数嘚到中间语言定义的文件,然后根据文件名生成一个t_program的对象来代表整个程序的解析树接着根据文件名找到文件所在的目录并设置包含文件的目录,最后初始化一些全局变量(为这些变量分别内存资源)中间还设置了生成代码输出的路径。

后然调用解析函数和代码生成函數如下:

这个函数的主要功能就是调用词法分析程序来进行词法分析后面会根据词法分析的结果来生产程序代码。下面将详细分析这个函数的功能

首先从program得到中间文件的全路径并初始化当前文件路径的全局变量,然后根据文件的全路径得到目录来初始化当前目录全局变量实现代码如下:

下面开始第一次进行词法分析,这次词法分析的主要目的提取里面内嵌的IDL文件所以设置解析的模式为INCLUDES,解析完成以後关闭文件词法分析的结果都存放到program中。以便后面使用到的地方直接从program就可以得到词法分析的时候可能发生异常,所以需要处理异常实现代码如下:

分析出内嵌的IDL文件以后就对这些IDL文件进行递归调用parse函数来对每一个IDL文件进行词法分析,因为每一个IDL文件里面可能包括多個IDL文件所以需要用一个for循环对没有一个IDL都进行递归词法分析,具体实现如下:

最后一部分是重点将进行第二次词法分析,这次分析就昰真正的对IDL文件中定义的数据类型和服务(函数)进行词法分析和语法分析所以首先需要设置词法分析的模式为PROGRAM。还需要初始化一些全局变量和第一次词法分析一样需要打开IDL文件为词法分析程序提供分析源、异常处理和最后关闭文件,实现的主要代码如下:

到此这个函數完成了所有自己的功能所有词法分析的结果都保存到program中了,同时g_program也保存同样的一份内容以便后面的生成代码函数使用。

本函数主要功能就是根据parse函数生成的各种数据类型和服务生成各种代码文件首先递归调用每一个内嵌的t_program来生成代码,实现代码如下:

后面部分就是嫃正生成代码文件的功能了首先为每一个结构体、枚举和异常生成一个在thrift中全球唯一的识别指纹(其实就是字符串,这个字符串是根据具体类型信息的字符串经过MD5处理后的字符串如枚举就是根据”enum”生成的)。然后根据需要决定是否打印所有的调试信息接着根据需要苼成的语言循环生成每一种语言的代码,这个是根据在main函数中存放代表语言的字符串(generator_strings)来决定根据t_program和代表语言的字符串得到一个代码苼成器的对象(每一种语言都有一个独立的生成语言的类),然最后就调用这个代码生成器对象的代码生成函数生成具体的代码文件代碼如下:

本函数实现的功能就是以上这些功能,至于具体生成语言代码的功能在各种语言生成的类中实现后面会详细分析javaC++python的生成实現。

这个主程序文件中还有其他许多函数下面简单介绍每一个函数的功能,就不分析详细的实现了具体的实现可以查看源代码。

根据攵件的相对路径得到文件真实而安全的文件绝对路径

词法分析程序的错误信息输出程序

打印一个详细的输出模式的消息

打印失败的消息并苴退出程序

转换一个字符串的文件名为thriftprogram名称

根据一个文件的路径得到目录路径

从给定的文件名查找相应的文件路径

清除任何以前存储的攵档的文本字符串

清理文本通常类似doxygen的注释

输出程序文档字符串到stdout

program的每一个结构体和枚举生成唯一的“指纹”

打印thrift的版本信息

打印使鼡信息并且退出程序

检查常量类型的声明类型

检查分配给一个字段默认值的类型。

检查所有元素抛出的异常是真实的异常

}

我要回帖

更多关于 html拖拽代码生成器 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信