yacc 编译 linux,如何编写真正的编译器和使用Yacc、lex构建编译器简介

编译器后端一是要考虑目标机器的代码形式,二是要考虑目标操作系统的ABI(应用程序二进制接口),比如WINDOW下的目标文件是COFF结构,LINUX下是ELF结构,还有OUT结构等等,写操作系统要做成BIN结构。 GCC生成ELF文件格式的目标代码,它的连接器只能读取ELF格式,并生成LINUX下的可执行文件,WINDOWS下使用的是COFF,生成的是PE结构的EXE文件。

编译器要考虑两种形式的目标,一是目标机器,即生成不同机器型号的指令(可以是汇编,可以是机器码);另一种是目标文件的格式,即使得编译结果文件在不同的操作系统上运行。基于以上的认识,对于不同的机器提供不同的汇编器,它们生成同一种(中间的)目标文件格式;对于不同的操作系统(当然包括自己写的操作系统,或者操作系统本身),提供不同的连接器,它们都读取该(中间的)目标文件,然后生成各自需要的可执行文件。因此,汇编器存在是必要的,“不能编写操作系统的语言不是好语言”,如果要编写操作系统,那么汇编器也是不可少的,至少启动代码必须使用汇编程序。所以编译器套件需要汇编器。

进程(线程)调度器,每隔一个时间片进行进程的调度,十分繁忙,需要高效实现,如果使用解释器解释执行,低效,目前基本上是不可取的。而且内核中硬件抽象层与硬件打交道,基本上需要很多硬件特性上的细节,解释器也难以执行。但是,如果将操作系统看作一个纯粹的虚拟机也未尝不可,但这种想法仅仅停留在实验室阶段,如果你想在概念上对操作系统进行彻底的革新,可以这样做,实验一下它的性能和可行性。也就是把生成二进制格式的任务留给了汇编器,由汇编器读取汇编成学然后生成目标文件(.obj),然后利用连接器连接成可执行文件(.exe),问题是为了有效的对调试器的支持,目标文件里面需要许多符号信息,它们遵循一定的格式,对于最新的目标文件格式,微软的汇编器MASM不能支持,只能生成较老的格式文件。它编译内核是因为作为编译器代码生成的后端,可以生成若干种目标文件,其中一种就是BIN文件,这是一种没有文件头(格式)的裸文件,直接以可执行代码开始,生成何种格式由在编译时设置不同的选项选择。有一种思路就是自己设计一种目标文件格式(类似于.OBJ文件),不管对任何系统都统一生成该种文件,然后,对不同目标操作系统,提供不同的连接器,生成适应该操作系统的可执行文件。

一个编译器使用lex和yacc(GNU的工具是Flex和Bison)来做只能完成30%的工作,首先使用lex定义关键字、数据类型,lex分析源码生成符号表(主要为标示符、数据、关键字三种),yacc接受lex的符号表作为输入,yacc有很多内置C函数和全局变量用来保存分析结果,yacc中定义了语言的BNF规则后,使用LALR(1)分析法得出一个分析结果保存在yacc的全局变量中,在定义BNF的时候,需要指出每条规则后面的操作,这个时候需要手工编写函数处理,可以把yacc的变量保存为树,也可以以参数的形式直接传递给处理函数由函数计算结果,也可以生成中间代码(为优化做准备)三元式、四元式,也可以直接归约计算出结果,也可以生成虚拟机指令(将来交给虚拟机执行,这种方法你还需要编写一个执行指令的虚拟机),还可以生成汇编指令,或者直接生成二进制代码,以上这些方法你可以使用一种或者几种在不同的归约阶段。最后生成可执行代码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值