前言
学完编译原理后几次都有想做编译器的冲动,但都由于各种原因半途而废(主要原因是菜),这次工程实践中恰好有个在线编译的模块,所以准备认真试一试,恰逢找实习的时候,所以进展十分缓慢,无法忍受决定从头梳理一遍
需求
前几次的工作基本上没太深入这部分,其实从上次构建博客开始我就意识到,无论是从一个项目的整体,还是各个部分,需求在刚开始的时候越明确越好,就拿这个编译器来说,你是想做一个具体的语言编译还是想做一个自定义语言编译,分为哪些模块,每个模块实现哪些功能,还可以具体到输入是怎么获取,支持哪些语法,输出是什么。鉴于工程实践的需求以及个人目前能力精力综合考虑,该在线编译系统功能暂定如下:
- 语言:v1:Main函数
- 模块:
- 前端页面获取输入
- 读取输入(文件或String)
- 词法分析
- 语法分析
- 输出三地址或字节码(未完成)
- 在词法和语法分析的时候都会做相应的简化,是语法分析我希望从简单的一个Main函数做起,而且对支持的语法会做一定的限制,输入的时候可能考虑写入一个解析文件
Example
public class Example {
public static void main(String[] args) {
int a = 1;
int b = 2;
int c = a+b*a;
while (c>=0){
a = a + getSum(b);
c = c -1 ;
}
System.out.println(a);
}
}
结构图
输入字节流会被转换成为Token流,例如 int 会被识别为 [keyword,int]的一个Token。符号表在这里是记录一些id的类型,如int a,则一个id的Token值为a在符号表中的类型为int,后续如果对a与字符串的操作则会报出静态类型检查不匹配
的结果。语法解析部分是自动生成器构建而成,这个自动生成器的输入是一个上下文无关的LL1文法Grammar,输出是一个语法解析器。这个解析器是这个小型编译器的核心,基于这个解析器对Token流进行解析且根据变量出现的顺序对符号表进行更新检查,例如重复定义这种静态错误。而且在解析的过程中可以生产抽象语法树,并进一步进行语义分析和中间代码生成