lvxuzhou


私信TA

用户名:lvxuzhou

访问量:45081

签 名:

lvxuzhou

等  级
排  名 186
经  验 5091
参赛次数 0
文章发表 35
年  龄 0
在职情况 学生
学  校 西安
专  业

  自我简介:

编译原理初探一

环境:win7 64位+llvm11+mingw+python3.7+libclang11

LLVM编译一个源文件的过程:预处理 -> 词法分析 -> Token -> 语法分析 -> AST -> 代码生成 -> LLVM IR -> 优化 -> 生成汇编代码 -> Link -> 目标文件

main.c 源码:

//#include<stdio.h> //可以注释,不影响分析
int main(int argc,char*argv[])
{
   puts("hello world");
   return 0;
}

使用LLVM的对一门语言编译的简图如下所示:


Clang和LLVM关系:

    Clang是一个C++编写、基于LLVM、发布于LLVM BSD许可证下的C/C++/Objective-C/Objective-C++编译器。那么为什么已经有了GCC还要开发Clang呢?Clang相比于GCC有什么优势呢?   其实,这也是Clang当初在设计开发的时候所主要考虑的原因。Clang是一个高度模块化开发的轻量级编译器,它的编译速度快、占用内存小、非常方便进行二次开发。


 LVM和Clang的关系是怎样的呢。我们将它们对应于传统的编译器当中的几个独立的部分,这样能够更加方便明确生动的表述。

微信图片_20211004230020.png



1、查看程序编译过程:
clang -ccc-print-phases main.c

微信图片_20211004224244.png

2、查看preprocessor(预处理)的结果

clang -E main.c

微信图片_20211004224601.png

3、词法分析,生成token

clang  -Xclang -dump-tokens main.c

微信图片_20211004224900.png

4、语法分析,生成语法树

clang  -fsyntax-only -Xclang -ast-dump main.c

微信图片_20211004225433.png

Clang AST介绍可以参考

https://www.cnblogs.com/jourluohua/p/14524955.html

配置python clang 

    现在的Clang,不仅仅是一个编译器前端,同时也可以作为一个库使用。作为一个库使用的时候,可以用它去分析C/C++/ObjectC语言代码,可以分析源码得到AST,也可以获取已经分析好的AST,也可以遍历AST,还可以获取AST中基本元素的物理源码位置。这就是libclang。libclang提供了一系列的C语言的接口,但是这些接口并不能完全提供存储在Clang C++ AST中的所有信息,只能提供部分基本信息,但是这些基本信息已经可以满足一般情况下的使用。主要目的是为了稳定,并且可以支持开发工具的基本功能。

    libclang很方便就打印了词法分析结果和AST语法树

C语言测试代码

typedef unsigned int VOS_UINT32;
VOS_UINT32 add(VOS_UINT32 num1,VOS_UINT32 num2)
{
    VOS_UINT32 result=num1+num2;
    return result;
}

生成的AST语法树:

微信图片_20211004234320.png

python解析代码

功能:遍历tokens流和AST抽象语法树

from clang.cindex import Config #配置
from clang.cindex import TypeKind
from clang.cindex import CursorKind
from clang.cindex import Index #主要API

def GetTranslationUnit(filename):
    index = Index.create()
    tu = index.parse(filename)
    print("tTranslation Unit=%s"%(tu.spelling))
    return tu
def LoadLibClang(libclangPath):
    if Config.loaded == True:
        pass
    else:
        Config.set_library_file(libclangPath)
#主函数
if __name__ == '__main__':
    filename='test.c' # C语言文件
    libclangPath = r'C:\Program Files\LLVM\bin\libclang.dll' #libclang库路径
    LoadLibClang(libclangPath) #加载libclang库
    tu=GetTranslationUnit(filename)#解析main.c
    ast_root_node=tu.cursor #获取cursor根节点
    # 获取词法分析结果
    print("Print all tokens:")
    for token in ast_root_node.get_tokens():#遍历词法分析结果
        print('%10s %s'%(token.spelling,token.kind))
    print("Print all nodes in ast tree:")
    for node in ast_root_node.walk_preorder():  # 遍历词法分析结果
        print('%10s %s %s '%(node.spelling,node.location.line,node.kind))
    #help(Token)
        #help(Index)

运行结果

微信图片_20211004234519.png

 

0.0分

0 人评分

  评论区