一、 实验目的
1. 通过实验对编译系统的基本理论、编译程序的基本结构有更为深入的理解和掌握;
2. 掌握编译程序设计的基本方法和步骤;
3. 能够设计实现编译系统的重要环节词法分析,同时增强编写和调试程序的能力。
二、 实验要求
- 单词的分类
可将所有标识符归为一类;将常数归为另一类;保留字和分隔符则采取一词一类。
- 符号表的建立
可事先建立一保留字表,以备在识别保留字时进行查询。变量名表及常数表则在词法分析过程中建立。
- 单词串的输出形式
所输出的每一单词,均按形如(CLASS,VALUE)的二元式编码。
4.数据获取及存储
本设计中默认./src/output.txt读取源文件,运算结果存储./src/output.txt文件中
三、 单词分类表
注:具体及详细编码以com.nonefly.test.KeyTypes类中定义为准
1. 关键字表
关键字,java中共50个关键字,如下,对其按顺序一字一编码
"abstract", "boolean", "break", "byte","case", "catch", "char", "class", "continue", "default", "do","double", "else", "extends", "final", "finally", "float", "for","if", "implements", "import", "instanceof", "int", "interface", "long", "native", "new", "package", "private", "protected", "public", "return", "short", "static", "super", "switch","synchronized", "this", "throw","throws", "transient", "try","void","volatile","while","strictfp","enum","goto","const","assert"
助记符 | 种别编码 | 关键字 |
ABSTRACT | 1 | abstract |
BOOLEAN | 2 | boolean |
BREAK | 3 | break |
BYTE | 4 | byte |
CASE | 5 | case |
... | ... | ... |
ASSERT | 50 | assert |
2. 运算符表
运算符,设计中涉及到+ - * / > = < & | ~十种,对于组合运算符如++ +=等未定义,将其分开描述。
运算符|助记符|种别编码
-----|------|---
• | PLUS | 51
• | MIN | 52
• | MUL | 53
/ | DIV | 54
& | AND | 55
|| OR | 56
~ | NOT | 57
> | GT | 58
= | EQ | 59
< | LT | 60
3. 分隔符表
界符(分隔符)涉及如下几种
, ; { } ( ) [ ] _ : . " \未一词一符定义,统一归为 SEPARATORS(助记符):61(单词种别)
4. 其他(标识符、常数、非法字符)
类型 | 种别编码 | 助记符 |
标识符 | 71 | ID |
常数 | 0 | DIGIT |
非法字符 | -1 | ERROR |
四、单词状态图
五、 算法描述
程序中用到的函数列表:
函数名或变量 | 解释 |
TestLexer(String fileSrc) | 通过路径构造词法分析器 |
StringBuffer buffer; | 文件读入缓冲区 |
char ch; | 字符变量,存放最新读进的源程序字符 |
String strToken; | 字符数组,存放构成单词符号的字符串 |
boolean isLetter(char ch) | 判断ch是否为字母 |
boolean isDigit(char ch) | 判断是否为数字 |
boolean isKeyWord(String) | 判断是否为关键字 |
boolean isOperator(char) | 判断是否为运算符 |
boolean isSeparators(char) | 判断是否为分隔符 |
void analyse() | 分析程序(关键代码) |
void getChar() | 将下一字符读到ch中,搜索指示器前移一个字符 |
void getBC() | 检查ch空白则调用getChar()至ch中进入非空白字符 |
void concat() | 将ch连接到strToken之后 |
void retract() | 将搜索指示器回调一个字符位置,将ch值为空白字 |
void writeFile(String,String) | 按照二元式规则写入文件 |
int getType(String args) | 利用反射获取种别编码 |
六、 程序结构
1. 整体目录结构如下,其中:
a.FileUtil.java 对文件的读写等操作
b.KeyTypes.java 定义了单词种类对应的种别编码
c.TestLexer.java 是分析器类,继承KeyTypes类,对源程序词法分析
d.TypeUtil.java 是一个简单的判断字符种类的类
e.MainTest.java 是测试主方法类,是程序入口,通过源程序路径创建TestLexer类,调用其中词法分析方法,最后结果保存在文件中
2. 上述类中定义方法如下,方法详细功能见(算法描述)中表格
七、 运行结果
1. 准备
在input.txt中输入源程序(我们以本程序源代码为例,此文件必须有),output.txt中为空,作为结果输出(可以不创建,运行时自动创建)如下图:
2. 运行
在文本中,按照要求,我们以(种类编码,VALUE)格式保存结果,在控制台中,为方便观察,以(助记符,VALUE)格式打印出。(运行结果如下)