开元编译器 UCC 研究 - 符号表

开源编译器 UCC 研究 - 工作流程

皮贝贝 posted @ 2009年9月15日 17:18 in 编译器 with tags ucc 编译器 编译原理 , 6271 阅读

最近看 UCC 的代码,研究下编译器的工作原理。大学时候的编译原理知识也忘得差不多了,本来当初就学的不好。现在拿一个实例来研究下吧。

 

从用户接口来看,一个正常的流程是这个样子的:

 

 

         ucc -o test.exe test.c

 

 

 

从一个 test.c 生成一个 test.exe.中间经历的步骤,从UCC源代码看,主要是这个流程:

 

1. 对 test.c 进行预处理。

这一步是 ucc 调用 vc 的cl进行的,结果生成 test.i 文件:

 

cl -nologo -u -D_WIN32 -D_M_IX86 -D_UCC -P test.c

 

 

 

2. 对test.i 进行编译处理。

这一步是调用自己的编译器 ucl 进行的,结果生成 test.asm 汇编文件:

 

ucl -ignore __declspec(deprecated),__declspec(noreturn),__inline,__fastcall -keyword __int64 -ext:.asm test.i

 

 


3. 对汇编文件 test.asm 进行编译

这一步是调用 vc 的汇编编译器 ml 进行的,结果生成 test.obj 文件:

 

ml -nologo -c -Cp -coff -Fotest.obj test.asm

 

 

 

4. 对 test.obj 和一些需要的lib 进行链接

这一步是调用 vc 的链接器 link 进行的,结果生成 test.exe 可执行文件:

 

link -nologo -subsystem:console -entry:mainCRTStartup -OUT:test.exe test.obj oldnames.lib libcmt.lib kernel32.lib

 

 

 

 

由上面看到,仅仅对 C源程序的纯编译是调用自己的 ucl 进行,其余都是调用VC进行。接下来看看 ucl 的工作流程:

 

1. 读入 test.i, 生成语法树,并进行语法检查

这一步是调用函数 ParseTranslationUnit() 函数进行, 结果生成一个 AstTranslationUnit 类型的语法树( 暂且定名为 transUnit )。

 

        transUnit = ParseTranslationUnit(file);

 

 

 

2. 对 transUnit 进行语义检查

这一步是调用函数 CheckTranslationUnit() 函数进行,

 

        CheckTranslationUnit(transUnit);
 

 

 

 

3. 将transUnit 翻译成 中间代码

这一步是调用函数 Translate() 进行,

 

        Translate(transUnit);

 

 

 

4. 通过 transUnit 生成汇编文件 test.asm

这一步是调用函数 EmitTranslationUnit() 进行,

 

        EmitTranslationUnit(transUnit);

 

 

 

 


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter