C0Compiler
作者:积极向上小木木 联系方式:PositiveMumu@126.com
2018年编译原理大作业,基于java语言和JavaCC工具的C0语言编译器
1.C0语言介绍
C0语言的语法结构定义如下:
->[] {}
-> int id {, id};
-> ( int id | void id) '(' ')'
->void main'(' ')'
->'{' [] '}'
-> {}
-> | | '{''}' | | | | | | ;
->if '('')' [else ]
->while '(' ')'
->;
->id = ;
->return ['(' ')'] ;
->scanf '(' id ')';
->printf '(' [ ] ')';
-> [+|-] { (+|-) }
-> {(*|/) }
-> id|'(' ')' | num |
->id '(' ')'
其中,id代表标识符,num代表整数,其含义及构成方式与C语言相一致;
C0源程序中的变量需先定义后使用,其作用域与生存期与C语言相一致;
自定义函数可超前使用(调用在前,定义在后);
其它方面的语义与C语言相一致。
假想的栈式指令系统表:
指令
含义
LIT 0 a
将常数值取到栈顶,a为常数值
LOD t a
将变量值取到栈顶,a为相对地址,t为层差
STO t a
将栈顶内容送入某变量单元中,a为相对地址,t为层差
CAL 0 a
调用函数,a为函数地址
INT 0 a
在运行栈中为被调用的过程开辟a个单元的数据区
JMP 0 a
无条件跳转至a地址
JPC 0 a
条件跳转,当栈顶值为0,则跳转至a地址,否则顺序执行
ADD 0 0
次栈顶与栈顶相加,退两个栈元素,结果值进栈
SUB 0 0
次栈顶减去栈顶,退两个栈元素,结果值进栈
MUL 0 0
次栈顶乘以栈顶,退两个栈元素,结果值进栈
DIV 0 0
次栈顶除以栈顶,退两个栈元素,结果值进栈
RED 0 0
从命令行读入一个输入置于栈顶
WRT 0 0
栈顶值输出至屏幕并换行
RET 0 0
函数调用结束后,返回调用点并退栈
2.项目功能
该编译器可以实现对C0程序的编译(由源代码编译成指令序列的过程)及解释执行(执行指令序列,输出结果)。
编译器功能:
输入:
源代码地址。在工程中位于testFile目录下的Sources目录中,若使用提供的测试文件,可输入testFile/Sources/xxx.txt。
是否输出中间代码(Y/N)。中间代码即为指令序列,输入Y的话会将指令序列输出在控制台(没啥用)。
是否输出分程序列表(Y/N)。即在控制台输出函数调用关系。
是否解释执行(Y/N)。即是否直接解释执行,选择否的话需要单独调用解释执行模块来执行程序。
请输入目标文件输出路径。指令序列文件将要存储的路径,想存储在默认路径填写testFile/ExecutedLists/xxx.txt即可。
输出:
如果未选择解释执行,程序运行结束后将在目标文件输出路径生成一个txt文件,供给解释执行程序使用。
如果选择解释执行,则将进入解释执行程序的输入部分。
解释执行器功能:
输入:
解释执行文件地址。即指令序列文件地址,在工程中位于testFile目录下的ExecutedLists目录中,若使用提供的测试文件,可输入testFile/ExecutedLists/xxx.txt。
程序参数参数。即源程序执行需要的参数,如果源程序不需要参数则不用输入。
输出:执行结果。
3.项目介绍
本项目由解释执行程序(Eexcute)和编译程序(Compiler)两个主要模块构成。编译程序负责将C0源代码编译并生成中间指令序列,解释执行程序负责将指令序列解释执行并生成结果。编译程序由JavaCC工具编译生成。
在Compiler包下的文件Compiler.jj、ErrorCode.java、MyError.java、SymbolItem.java是手动添加的,其他的.java文件均由JavaCC工具Compiler.jj编译得到,具体方法详见JavaCC官网(https://javacc.org/)。
测试文件存放在testFile文件夹下。
Sources目录下为源程序,主要包括:
A+AA+AAASource.txt : 输入A,N计算A+AA+....知道N个A的值。
AddMoreSource.txt : 输入N,计算从1加到N的值。
factorialSource.txt : 输入N,计算N的阶乘。
GCD&LCMSource.txt : 输入M,N计算M与N的最大公约数,最小公倍数。
ExecutedLists目录下为编译后的指令序列文件,与上述一一对应。
注意:若你的源程序为放置在指定目录中,请输入你源程序的绝对路径。生成的指令序列文件也请输入绝对路径,在运行解释执行器的时候也要输入绝对路径。