基于Clang的Source to Source源代码转换(一)
Clang中包含了非常多的关于抽象语法树(AST)的访问和操作的类和接口。我们程序开发人员可以直接通过继承其中的某些类,重写其中的关键成员方法,从而形成我们自己的对抽象语法树的操作。
那么,首先我们简要介绍几个概念:
抽象语法树(AST):抽象语法树是源代码的抽象语法结构的树状表现形式。树上的每个节点都表示源代码中的一种结构。之所以说语法是“抽象”的,是因为这里的语法并不会表示出真实语法中出现的每个细节。一般的,在源代码的翻译和编译过程中,语法分析之后会创建出抽象语法树。一旦AST被创建出来,在后续的处理过程中,比如语义分析阶段,会添加很多语义信息帮助进行后续的语义翻译工作。AST其实就是一个程序的静态模型,它抽象出了一个程序在静态时结构状态,我们可以通过对AST的分析从而了解一个程序的相关静态信息。
Source to Source转换:我所理解的源到源的转换可以简单的当做是从一种源代码的形式转换到另一种源代码的形式。这其中,形式的定义很宽泛,包括了最简单的源代码风格、变量函数的命名到不同的编程语言。这些的转换都可以成为source to source transformation。
那么,如果要进行源到源的转换,最直接的思路和方式就是通过获得一个程序代码片段的抽象语法树(AST),然后通过修改AST的若干子树或若干结点,然后将AST转换成源代码,从而完成源到源的转换。
既然,我们已经明白了我们的目标和途径,那么接下来就介绍一下Clang中的基于AST的操作以及它们的设计模式。
Clang中的AST部分操作和表示的设计和实现比较类似于设计模式中的访问者模式。
Stmt
Stmt是表示程序语言语法成分的最原始的抽象基类接口,而我们的其他各种语法类型则是继承Stmt,如IfStmt,NullStmt,DeclStmt等等。
它们相当于是访问者模式中的Element和ConcreteElement。元素类和抽象元素类。
RecursiveASTVisitor
RecursiveASTVisitor类似于访问者模式中的访问者。
我们在实现自己的操作AST的方法时需要继承自RecursiveASTVisitor类,并重写其中的多个方法,一般为bool VisitXXX(Stmt* stmt)方法。
每一个VisitXXX方法都是访问某个具体对应类型的Stmt结点并对它进行操作的函数。
所以RecursiveASTVisitor和我们写的Visitor类就相当于抽象访问者类和访问者类。
ASTConsumer
ASTConsumer类的主要功能是提供一种自顶向下的对抽象语法树进行访问的入口。
因为AST中包含了各种各样的Stmt,所以也可以认为ASTConsumer类似于提供了访问这个包含多种类型Stmt的容器的入口。
因此我们可以将它对应到访问者模式中的ObjectStructure和Client。在这其中有多种方法来遍历当前程序生成的抽象语法树AST,从而获得各种各样类型的AST Node。
因此,我们需要自己实现一个继承自ASTConsumer得类,并重写其中的遍历AST的方法,如:HandleTopLevelDecl,HandleTranslationUnit等等。

2、接着,调用对应的VisitXXX()方法,进行具体的操作;
3、最后,在遇到接下来的语句再调用对应的TraverseDecl、TraverseStmt等等,递归执行。
有人说,访问者模式比较适用于对已有功能的重构,或者说对一个项目已经完成,它的元素类型、数据结构已经定的差不多,而对数据的操作还有可能后序会改变。这样,可以使用访问者模式对原有的代码进行重构一遍。
基于Clang的Source to Source源代码转换(一)的更多相关文章
- 打造基于Clang LibTooling的iOS自动打点系统CLAS(二)
1. 配置LLVM和Clang 在这篇文章里,我们会基于上一篇所述的方案进行展开,详细讲解如何从0开始创建一个基于Clang LibTooling的编译器前端工具.在开始之前,我们假设你已经基本了解何 ...
- 数据的异构实战(一) 基于canal进行日志的订阅和转换
什么是数据的异构处理.简单说就是为了满足我们业务的扩展性,将数据从某种特定的格式转换到新的数据格式中来. 为什么会有这种需求出现呢? 传统的企业中,主要都是将数据存储在了关系型数据库中,例如说MySQ ...
- Java To CSharp源代码转换
前言 开发环境 客户端:Unity3D开发(C#) 服务器:Java (基于Java7) 日 期:2016年09月 需求说明 部分服务器的部分逻辑功能在客户端实现一遍,可以简单的理解为服务器的部分 ...
- 打造基于Clang LibTooling的iOS自动打点系统CLAS(一)
1. 手动打点的弊端 在很多ios工程师的日常工作中,不但要对接产品提出的功能性需求,还会收到产品出于数据统计分析需求目的而提出的附带的隐形需求:统计打点.大多数公司的基础框架层都会对统计打点功能做高 ...
- 打造基于Clang LibTooling的iOS自动打点系统CLAS(三)
1. 源码变换 第一章我们提到过,CLAS的本质是对源码做一次非常简单的变换(有些文章里称作变形),即Source-Source-Transformation,将打点代码精确地插入到目标函数的首部,保 ...
- SSIS 使用OLEDB/ADO NET Source 数据流source控件 连接Oracle失败
在做数据提取的时候发现一个非常奇怪的问题. Oracle客户端是安装正确并且Toad可以正常运行的,但是在新建OLEDB/ADO NET Source 数据流source控件连接Oracle的时候一直 ...
- DirectShow中写push模式的source filter流程 + 源代码(内附详细注释)
虽然网上已有很多关于DirectShow写source filter的资料,不过很多刚开始学的朋友总说讲的不是很清楚(可能其中作者省略了许多他认为简 单的过程),读者总希望看到象第一步怎么做,第二步怎 ...
- 在使用Reference Source调试.Net 源代码时如何取消optimizations(代码优化)-翻译
在使用PDB调试XAF时,发现好多变量都看不到.都被优化掉了. 下面的方法可以解决. 当你在使用Reference Source functionality in VS 2008 调试.Net 的源代 ...
- .NET Core使用Source Link提高源代码调试体验和生产效率
前言: 在我们日常开发过程中常常会使用到很多其他封装好的第三方中间件(NuGet依赖项).类库或者是.NET框架中自带的库.但是当你想要对这些类库的方法设置断点调试,然后发现无法F11(逐语句)调试进 ...
随机推荐
- SVN中trunk、branches、tag的使用
我相信初学开发在SVN作为版本管理时,都估计没可能考虑到如何灵活的运用SVN来管理开发代码的版本,下面我就摘录一篇文章来简单说明SVN里的trunk,branched,tags这个三个文件目录的用法 ...
- 3D滚动下拉菜单-简直不要太任性
预览 先看看最终效果 简介 由来 最初看到这个是在14年5月,猛戳这里:妙味官网,觉得非常炫.想要做出来,所以就开始学习web. 那时候是做c/s的,也因为这个走上了b/s之路,(゚Д゚≡゚Д゚) 现 ...
- WinServer2003 文件夹共享 方法设置
文件夹设置: 5.假设我们在E盘有一个wmpub文件夹要设置在网络中共享,让大家都可以看到,首先我们右键点击WMPUB文件夹[共享和安全],弹出对话框,选择[共享此文件夹],点击[权限],弹出的对话框 ...
- php 登录注册api接口代码
/** *一览(www.yl1001.com) * PHP开发API接口 服务端 */ require 'conn.php'; //连接数据库的文件 header('Content-Type:text ...
- 真机远程调试 ( IOS Android 以及微信,weex)
1.以前cordova远程调试,Android的直接连接USB后,用chrome打开chrome://inspect网址 IOS的打开Safari的developer下. 这是因为cordova的we ...
- xargs -I
xargs -i 参数或者-I参数配合{}即可进行文件的操作. -I replace-str Replace occurrences of replace-str ...
- centos6.4 挂载新盘并移动mysql数据目录
1 centos 挂载新盘并格式化 以vmware workstation12 中安装的centos6. 虚拟机为例进行演示 关机,添加硬盘 开机,格式化硬盘,并挂载 通过命令查看硬盘 fdisk – ...
- 无题 MVC
1. MVC 里controller 返回匿名类型, 在View里是访问不了匿名类型的字段,因为它是Internal Private, 必须定义强类型 2. 扩展view的方法 public stat ...
- c 头文件<ctype.h>(二)
测试<ctype.h>函数 #include <stdio.h> #include <ctype.h> int main(){ ; ; i < ; ++i){ ...
- 夺命雷公狗-----React---17--事件常用的属性
我们可以通过打印的方式将他打印出来看看,如下所示: <!DOCTYPE> <html> <head> <meta charset="utf-8&qu ...