2012-12-28 30 views
0

我正在开发一个类似于C的编译器,我想知道编译器如何与系统包含在一起。设计一个编译器像C

编译器读取完整的代码,并存储所有包含在一个列表和解析器中包含的包含,读完当前代码后?

// file main.c 
#include <stdio.h> // store in one list 

// continue the parse ... 
int main() 
{ 
    return 0; 
} 
// now, read the includes 
// after finish the includes parse, gen code of sources 

// just a sample 
// file stdio.h 
#include <types.h> // store in list 
#include <bios.h> // store in list 

void printf(...) 
{ 
} 

void scanf(...) 
{ 
} 

顺便说一句,我developd的系统(仅测试)来读取包括和,停止解析,阅读包括...(这是一个令人厌恶的代码,但是,工作...) (链接样本) - >https://gist.github.com/4399601

btw,什么是最好的方式来阅读包括...和包括文件的工作?

+0

我只是跳你没有尝试在C语言中实现解析器...有更好的语言,例如Bison – benjarobin

+2

你需要小心的术语。 C不是编译器,它是一种语言。你想编写一个C编译器,或者一个C语言的编译器吗? – Mat

+0

或者你想让一个完整的语言说“Alexa”?如果是这样,那么你可以用C或C++或Java创建完整的应用程序,一旦完成,然后用你的语言重构你的代码。 –

回答

1

C中以#开头的任何行都由预处理器处理,而不是编译器处理。预处理器生成编译器随后编译的文件。该文件的内容取决于开发人员和SDK定义的任何内容。

+0

我不觉得这个区别有用,在这里。例如,一个C编译器包含一个预处理器,“编译器”和连接器,但整个事情仍然是一个C编译器。这个词被超载。 – GManNickG

+0

@GManNickG预处理既可以是单个编译器exe中的一个阶段,也可以是单独的程序。重要的是,它发生在别的之前。 – James

5

#include,#define,#ifdef等被称为preprocessor的单独通道处理。它用#include替换包含文件的行。然后将生成的临时源文本输入到后续传递,如tokenizerparser

+0

而包含预处理输出*的概念文件可以是一个实际的临时文件,但一个管道(进程之间)或流(进程内部)也是可行的选项。 –

+0

@BenVoigt谢谢,修正。 –

0

任何与开始是一个预处理器指令..相应代码获取在编译时被取代..汇编的第一阶段是这样的预处理器编译..

再后来预处理器的输出(.i文件)是给编辑的后期阶段..

编制的后期阶段包括词法分析器,解析器优化器和代码生成器..

0

如果我从头开始编写一个编译器,我会首先考虑是否哈包括是语言的必要组成部分 - 如果是,您是否必须编写它,或者您可以使用已有的语言(例如gcc的cpp部分)。毕竟,编译器的“有趣”部分是编译代码的真正目的,而不是通过宏扩展来读取文件和用其他字符串替换字符串[虽然这当然也很有趣 - 但是你可以写一次你有一个可以工作的编译器!]。包含文件的棘手部分不是包含它本身(相当平凡,递归,函数),而是#define /#ifdef /#if /#undef的解析,更重要的是, 。

玩得开心!