cbc启动和调试初步

cbc 启动和调试初步

最近在看《自制编译器》一书,上面介绍了怎么样实现一个编译器。但是,内容是抽取代码的部分进行讲解的。对我我这样基础比较薄弱的人来说,读起来,可谓管中窥豹,只见一斑。看了许久了,一直无法深入下去,只能停留在前几章的内容。之后的内容,基本上像是在看天书了,这样下去,花再多的时间也是徒劳的。所以,我想到了来运行cbc的代码,经过一番折腾,现在的成果是可以调试输出cbc的AST,即对任意的cbc源代码进行Parser,然后将生成的 AST 打印出来。

前置条件

  • 安装 JDK 8
  • 安装 JavaCC 7
  • 安装 eclipse

在继续阅读下面内容前,确保这些东西都已经准备好了!

项目目录

我这里使用的 IDE 是 eclipse,使用其它 IDE 应该是一样的。首先,创建一个工程文件夹用来存放cbc代码,这里我创建一个 cbc 文件夹,然后在其中建立一个src目录。这个目录是 IDE 的规范,它是用来存放源码的。然后将 cbc 文件内容复制进src目录,使用 eclipse 作为工程打开即可。eclipse 会自动创建工程需要的其它东西,但是这不是我们需要关心的重点。

// 项目目录结构
-src
    \---net
        \---loveruby
            \---cflat
                +---asm
                +---ast
                +---compiler
                +---entity
                +---exception
                +---ir
                +---parser
                +---sysdep
                |   \---x86
                +---type
                \---utils

生成 Parser 代码

cbc 的代码是不包含 Parser 代码的,它只有一个 Parser.jj 文件。这是一个 JavaCC(基于Java的解析器生成器兼扫描器生成器) 文件,它是一个 Parser Generator。所以,我们需要自己来根据 Parser.jj 来生成扫描器和解析器代码。这就需要我们前面安装的JavaCC了。我自己在 eclipse 中安装了 JavaCC 插件,所以可以直接右键选择 Compile with javacc 生成。
在这里插入图片描述
但是,我不推荐你这样做!这个插件安装其实挺麻烦的(而且插件的版本很老),不像 vscode 那样简单,所以我推荐大家直接使用命令行来操作。使用命令行来生成,非常简单,只有一句代码:

javacc Parser.jj

因为我已经生成好了,就不想再操作一遍了,给大家看一个 eclipse 插件生成的输出,使用命令行的输出基本是一样的。不过这里可以看到该插件是版本是 5.0 了,我下载的 JavaCC 是最新版的 7.0。
在这里插入图片描述
JavaCC 生成的文件,开头都会提示,不要去编辑它。但是生成的文件再 eclipse 里面会报错,因为有一个类没有被正确导入,Parser.java 文件,需要手动导入一个类:import net.loveruby.cflat.entity.Parameter;
如果你报错找不到 Parameter,可以直接将这行代码加入 Parser.java 文件中。

初次运行

这是测试的输入文件 hello.cb:

int main(int argc, char **argv) {
	printf("Hello, World!\n");
	return 0;
}

配置工作:

cbc 项目的主类是 Compiler,我们需要时需要指定相应的参数,这里使用下面这种方法来配置,我现在只使用了两个参数,第一个参数指定了源文件,第二个参数是输出源文件的 AST 结构。
在这里插入图片描述

在这里插入图片描述
运行:
在这里插入图片描述

运行结果:
在这里插入图片描述

注意:cbc 是 Linux 中 C 语言的规范,所以它的main函数是带参数的。如果使用不带参数的main函数,会无法解析通过,它会报下图所示的错误。
在这里插入图片描述

解决导入路径问题

完成上面,基本上已经算是大功告成了,可以启动cbc代码进行 Parser。这里现在只能进行 Parser,后续的我还不清楚。不过现在还有一点问题,那就是无法在源文件中包含导包代码,例如对如下文件进行 Parse:

import stdio;
int main(int argc, char **argv) {
	printf("Hello, World!\n");
	return 0;
}

在这里插入图片描述
这是因为默认的导包路径无法找到需要导入的包的问题。经过分析(如下图所示),默认的导包路径是在当前路径下面,所以这里解决办法就有两种了:

  1. 将需要导入的包放入工程目录中;
  2. 修改默认的导包路径。

在这里插入图片描述
这里我选择第二种方式,这样对工程没有侵入性。解决办法是复制 cbc 目录中的 import 包到 cbc 工程所在的目录下。
在这里插入图片描述
在这里插入图片描述
然后修改代码如下:
这里将默认的导包路径由当前目录下,修改为了上一层目录下的 import 文件夹下了。
在这里插入图片描述
再次运行:
这样就可以正常通过 Parse 了,不过输出基本没什么变化,毕竟现在只是编译的解析过程。
在这里插入图片描述

说明

通过一番折腾,总算是走了一小步了。因为编译的前期是平台无关的,所以这里可以在 Windows 上面进行操作,不用去搞虚拟机了。而且,通过IDE阅读代码,也比通过看书本上的部分代码好多了。不过,接下来的内容,感觉很难看懂了,所以我打算暂且放一放了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值