欢迎光临散文网 会员登陆 & 注册

用300多行C++代码写一个超简单的编译器

2021-08-11 12:24 作者:GC_CH  | 我要投稿

目标

    将一个可以支持输入任意多个字符串的语言的源代码编译成exe格式的可执行文件。

    该语言只支持一种语句,格式是【 print(字符串); 】,也就是以【print】开头,后跟【(】, 再跟着一个【字符串】,最后跟着【)】和【;】 ,一条语句只包含5个单词,一个程序支持任意多条该语句。

    麻雀虽小,五脏俱全。

流程

词法分析

    词法分析就是将源代码分割成一个一个的单词,舍弃不需要的字符,比如注释等。

    那么需要先定义单词的结构,先定义单词的类型:

 然后是单词:

    只要知道什么单词以什么开头,后面跟着什么,以什么结尾,词法分析就很简单了:

错误处理

    没有哪个程序员不会写错代码的,因此,错误处理也是必不可少的一部分,这部分的主要目的是识别出语法错误,并告诉程序员在哪里出了什么错误。

    这里当出现错误的时候,就简单地告诉出错信息和位置,然后结束编译。

语法分析

    整个结构和词法分析差不多。

    

    这是识别具体语句的部分:

    其中还嵌入了语义分析的代码和中间代码生成的代码。

语义分析

    语法分析识别出的是源代码的结构,而语义分析要判断这个语句是要做什么,能不能这么做。

    因此,这里只需要判断调用的那个函数是不是“print”函数就行了。

中间代码生成

    此处,我使用的是三地址码表示的中间代码,三地址码只是一个结构,该结构有一个操作码和3个操作数,并没有指定实际的操作码和操作数是什么。这些需要我们自己定义,也就是构造我们自己专属的指令集。而指令集用什么结构表示都可以,比如三地址码,抽象语法树,有向无环图等,这是多对多的关系。

    

汇编生成

    到这一步,就是编译器的后端了,需要选择具体的机器的指令集和汇编器。不同的汇编器的汇编代码的语法可能不同。

    当然也可以不生成汇编代码,直接生成可执行文件。但是这就需要了解可执行文件的结构,以及具体的指令的编码是什么了,比如nop指令的编码是0x90。

    这里,我选择了686指令集已经masm32汇编器。

    至于中间代码怎么转成汇编代码,基本是一条中间代码对应多条汇编代码,怎么对应?加法对加法,入栈对入栈,赋值对赋值,就是这么回事。

    

测试

    

    如果汇编出错,那么很可能是没有安装masm32!!!

用300多行C++代码写一个超简单的编译器的评论 (共 条)

分享到微博请遵守国家法律