(原创)clang的python接口教程(二)
来源:互联网 发布:美股交易软件 编辑:程序博客网 时间:2024/06/15 11:26
clang的python接口(二)
N久之前的一个坑了,今天来为大家填上。(果然需求是第一生产力)
- clang的python接口二
- 常用类
- AST的构建
- 前序遍历AST
- 语法单元提取
- 分词的提取
- 参考资料
常用类
- Index:
这个类是clang的核心类。具有构建语法树的主类。
常用方法:
create() ''' 初始化Index类。 ''' parse(self, path, args=None, unsaved_files=None, options = 0) ''' 构建语法树,同时返回AST的根节点。前两个参数比较常用, path:要进行构建的源文件的路径 args:编译选项例如-DUSE_LIBPNG1等 '''
- TranslationUnit:
编译单元,一般来说指的是进行编译的文件。 - CursorKind
语法树的的索引结点的类别。
常用方法:
get_children() """ 这个方法用来获取其子节点列表的迭代器。 """ get_tokens() ''' 得到了其每个分词的列表的迭代器。 ''' @property translation_unit() """返回这个节点索引所在的源文件"""
- TypeKind
这个是每个节点的语义类别。(后文会具体区分和TypeKind的区别) - Config
clang的配置类
AST的构建
抽象语法树(abstract syntax tree或者缩写为AST),或者语法树(syntax tree),是源代码的抽象语法结构的树状表现形式,这里特指编程语言的源代码。树上的每个节点都表示源代码中的一种结构。之所以说语法是“抽象”的,是因为这里的语法并不会表示出真实语法中出现的每个细节。比如,嵌套括号被隐含在树的结构中,并没有以节点的形式呈现;而类似于if-condition-then这样的条件跳转语句,可以使用带有两个分支的节点来表示。 —— [ 维基百科 ]
首先说明一下AST的定义,之后通过代码具体讲解一下clang的工作过程。
from clang.cindex import Configfrom clang.cindex import TypeKindfrom clang.cindex import CursorKindfrom clang.cindex import Index#首先需要导入需要的类型包。#clang的python绑定的具体配置方法看博主的另一篇博客clang的python接口(-)libclangPath = '/usr/lib/llvm-4.0/lib/libclang-4.0.so.1'if Config.loaded==True: pass else: Config.set_library_file(libclangPath)#libclangPath是libclang.so的具体位置。 index = Index.create() tu = index.parse(file_path,commands)
构建语法树的过程十分简单,接下来根据需要进行遍历,常用的便利方法一般都是先序遍历或者层次遍历。
(关于树的遍历可以查询《算法导论》之类的有关数据结构的书籍或资料,这里不进行赘述)
前序遍历AST
这里主要讲解通过前序遍历AST来进行提取各个语法单元的过程,
def iterAST(cursor): ''' 前序遍历严格来说是一个二叉树才有的概念。这里指的是对于每个节点,先遍历本节点,再遍历子节点的过程。 ''' for cur in cursor.get_children(): #do something iterAST(cur)
语法单元提取
这里需要通过识别CursorKind以及TypeKind来进行语法单元的识别。
def iterAST(cursor): ''' 在遍历过程中,遇到了一个节点就进行检查。 CursorKind指的是这个节点在AST中的位置例如(函数,类,参数定义等) TypeKind指的是这个节点的语义类别,例如这个参数的类别是const char,int等类别。 ''' for cur in cursor.get_children(): if cur.CursorKind==CursorKind.FUNCTION_DECL: #do something for cur_sub in cur.get_children(): if cur_sub .kind == CursorKind.CALL_EXPR: #do something #这一段代码分析的是函数定义调用的其他函数。 elif cur.kind == CursorKind.FIELD_DECL: #do something elif cur.type.kind == TypeKind.UCHAR: #do something iterAST(cur)
分词的提取
这里讲解一下如何提取分词,也就是Token.
def iter_cursor_content(self,cur): ''' 这里展示的是一个提取每个分词的方法。 ''' cursor_content="" for token in cur.get_tokens(): #针对一个节点,调用get_tokens的方法。 str_token = token.spelling+" " cursor_content = cursor_content+str_token return cursor_content
参考资料
阅读全文
0 0
- (原创)clang的python接口教程(二)
- (原创)clang的python接口(一)
- Clang 宏定义初探(二)
- clang static analyzer源码分析(二)
- 深入研究Clang(四) Clang编译器的简单分析
- 深入研究Clang(四) Clang编译器的简单分析
- Python教程精华版(二)
- caffe python接口:配置文件的生成(二)
- 打造基于Clang LibTooling的iOS自动打点系统CLAS(二)
- [原创]我的Javascript(二)
- Python基础学习教程(二)之序列的宝藏
- python 接口自动化测试(二)
- 深入研究Clang(二)Abstract Syntax Tree
- clang源码——CompilerInstance和Preprocessor(二)
- llvm+clang的安装(使用cmake)
- 简明python教程学习笔记(二)
- Python教程(二)显示行号
- 《简明Python教程》学习(二)
- MySql安装问题This application requires Visual Studio 2013 Redistributable. Please install
- python实现常用排序算法
- CC3220LaunchPad学习(一)
- 第九周 纸上谈兵:“知原理”检验题目
- ssh
- (原创)clang的python接口教程(二)
- SpringBoot非官方教程 | 第七篇:springboot开启声明式事务
- UIViewController的理解
- 在DPDK环境下搭建OpenvSwitch用户态运行环境
- tomcat挂掉自动启动tomcat
- 【Scikit-Learn 中文文档】神经网络模块(监督的)- 监督学习
- 频率域图像增强MATLAB实现
- Zabbix+grafana搭建MySQL监控平台
- java设计模式之工厂方法模式