java实现的词法分析.docx
- 文档编号:5074868
- 上传时间:2022-12-13
- 格式:DOCX
- 页数:29
- 大小:189.83KB
java实现的词法分析.docx
《java实现的词法分析.docx》由会员分享,可在线阅读,更多相关《java实现的词法分析.docx(29页珍藏版)》请在冰豆网上搜索。
java实现的词法分析
实验一:
词法分析器
一、词法分析器程序的实验综述
1.1开发背景
1.2问题介绍
1.3词汇表
二、词法分析器程序的系统分析
2.1词法形式化描述
2.2单词种别定义
2.3状态转换图
三、词法分析器程序的系统设计
3.1运行环境介绍
3.2关键算法流程图及文字解释
3.3用于处理注释的skip函数
3.4基于trie树的保留字搜索函数
3.5系统运行与调试
四、系统测评
图0系统开发流程图
词法分析器程序
一词法分析器程序的实验综述
1.1开发背景
编译原理涉及词法分析,语法分析,语义分析及优化设计等各方面。
词法分析阶段是编译过程的第一个阶段,是编译的基础。
这个阶段的任务是从左到右一个字符一个字符地读入源程序,即对构成源程序的字符流进行扫描然后根据构词规则识别单词(也称单词符号或符号)。
词法分析程序实现这个任务。
词法分析程序可以使用Lex等工具自动生成。
从左到右逐个字符对构成源程序的字符串进行扫描,依据词法规则,识别出一个一个的标记(token),把源程序变为等价的标记串序列。
执行词法分析的程序称为词法分析器,也称为扫描器。
词法分析是所有分析优化的基础,涉及的知识较少,如状态转换图等,易于实现。
本次实验使用java代码实现。
1.2问题介绍
对某特定语言A,构造其词法规则。
A的内容如下:
该语言的单词符号包括
1.保留字
2.运算符及界符
3.标识符(字母大小写不敏感),整型常数
1.3词汇表
对于后文正则式中可能出现的符号定义如下,以便清晰地描述A语言的正则式
符号
说明
a
字母
b
数字
c
符号(不包括字母和数字)
*
闭包运算符
|
或运算符
.
连接运算符(可省略)
空
#
结束符
二词法分析器程序的系统分析
2.1词法形式化描述
正则式
意义
举例
a(a|b)*
标识符或保留字
Lex1,program
b*
常数
12345
c
运算符或界符或非法字符
+,*,(,)等
2.2单词种别定义
program
1
not
8
常数
15
.
22
begin
2
if
9
+
16
;
23
end
3
then
10
*
17
//
24
var
4
else
11
:
=
18
/*
25
int
5
while
12
(
19
*/
26
and
6
do
13
)
20
or
7
标识符
14
21
对于标识符或保留字的推导
对于常数的推导
对于符号的推导
2.3状态转换图
其中:
识别标识符或保留字
识别常数
识别加运算符
识别乘运算符
识别赋值运算符
识别大于等于运算符,大于运算符并加以区分
识别小于等于运算符,不等于运算符,小于运算符并加以区分
识别括号,逗号,点号,分号,等于号
其余所有无法被此状态转换图识别的符号视为非法符号。
三词法分析器程序系统设计
3.1运行环境介绍
词法分析器程序由一个java控制台程序实现,通过读入一个名为A.txt的文本文件中的测试代码来对其进行词法分析。
开发环境:
MyEclipse8.5,jdk1.6
系统流程图:
3.2关键算法流程图及文字解释
词法分析程序(Analysis函数)详细流程图如下:
voidanalysis()throwsException
{
StringBufferlexSegment=newStringBuffer();
StringBufferdigitSegment=newStringBuffer();
//charnext;
try
{
while(true)
{
program=in.readLine();
if(program==null)
{
if(line==0)
{
System.out.println("文件为空,");
break;
}
else
{
System.out.println("文件已编译完成");
break;
}
}
else
{
line++;
column=-1;
lineLength=program.length()-1;
while(column++<=lineLength-1)
{
now=program.charAt(column);
if(now=='')
continue;
//System.out.println(now);
//isFinished=false;
elseif(Character.isDigit(now))
{
next=now;
//column++;
while(Character.isDigit(next))
{
digitSegment.append(next);
column++;
if(column>lineLength)
break;
next=program.charAt(column);
}
column--;
constant.append("数字",digitSegment.toString(),4,constant.binaryTeamLengthUsed);
digitSegment.delete(0,digitSegment.length());
continue;
}
elseif(now>='A'&&now<='z')
{
now=Character.toLowerCase(now);
lexSegment.append(now);
if(column next=program.charAt(column+1); else next=''; if(reservedWordTrie.SearchWord(lexSegment.toString())==true) { signal.append("保留字",lexSegment.toString(),2,signal.binaryTeamLengthUsed); if((lexSegment.toString().equalsIgnoreCase("var")==true)||(lexSegment.toString().equalsIgnoreCase("int")==true)) isAnnotation=false; else isAnnotation=true; lexSegment.delete(0,lexSegment.length()); continue; } /*elseif(lexSegment.length()>reservedWordMaxLength) { lex.append("标志符",lexSegment.toString(),3,lex.binaryTeamLengthUsed); lexSegment.delete(0,lexSegment.length()); continue; }*/ elseif(Character.isDigit(next)) { column++; while(Character.isDigit(next)) { lexSegment.append(next); column++; if(column>lineLength) break; next=program.charAt(column); } column--; lex.append("标志符",lexSegment.toString(),4,lex.binaryTeamLengthUsed); lexSegment.delete(0,lexSegment.length()); continue; } elseif(next<'A'||next>'z') { lex.append("标志符",lexSegment.toString(),5,lex.binaryTeamLengthUsed); lexSegment.delete(0,lexSegment.length()); continue; } } elseif(now.equals('+')) { signal.append("运算符",symbol[0],1,signal.binaryTeamLengthUsed); isFinished=true; continue; } elseif(now.equals('*')) { signal.append("运算符",symbol[1],1,signal.binaryTeamLengthUsed); isFinished=true; continue; } elseif(now.equals('(')) { signal.append("运算符",symbol[2],1,signal.binaryTeamLengthUsed); isFinished=true; continue; } elseif(now.equals(')')) { signal.append("运算符",symbol[3],1,signal.binaryTeamLengthUsed); isFinished=true; continue; } elseif(now.equals(',')) { signal.append("运算符",symbol[4],1,signal.binaryTeamLengthUsed); isFinished=true; continue; } elseif(now.equals('.')) { signal.append("运算符",symbol[5],1,signal.binaryTeamLengthUsed); isFinished=true; continue; } elseif(now.equals(': ')) { column++; if(program.charAt(column)=='=') { signal.append("运算符",symbol[6],1,signal.binaryTeamLengthUsed); isFinished=true; continue; } else { System.out.println("第"+line+"行出现非法字符': '"); column--; continue; } } elseif(now.equals(';')) { signal.append("运算符",symbol[7],1,signal.binaryTeamLengthUsed); isFinished=true; if(column==lineLength) { isAnnotation=true; continue; } elseif(column+1<=lineLength&&program.charAt(column+1)=='/') { isAnnotation=true; continue; } elseif(column+1<=lineLength&&program.charAt(column+1)=='') { isAnnotation=true; continue; } else { System.out.println("第"+line+"行出现非法字符';'"); continue; } } elseif(now.equals('>')) { column++; if(program.charAt(column)=='=') { signal.append("运算符",symbol[11],1,signal.binaryTeamLengthUsed); isFinished=true; continue; } else { signal.append("运算符",symbol[8],1,signal.binaryTeamLengthUsed); column--; continue; } } elseif(now.equals('<')) { column++; if(program.charAt(column)=='=') { signal.append("运算符",symbol[12],1,signal.binaryTeamLengthUsed); isFinished=true; continue; } elseif(program.charAt(column)=='>') { signal.append("运算符",symbol[13],1,signal.binaryTeamLengthUsed); isFinished=true; continue; } else { signal.append("运算符",symbol[9],1,signal.binaryTeamLengthUsed); column--; continue; } } elseif(now.equals('=')) { signal.append("运算符",symbol[10],1,signal.binaryTeamLengthUsed); isFinished=true; continue; } elseif(now.equals('/')) { if(column+1<=lineLength) next=program.charAt(column+1); else { System.out.println("第"+line+"行"+"第"+column+"列"+"出现非法字符'"+now+"'"); continue; } if(next.equals('/')) { column=lineLength; //isAnnotation=true; //System.out.println("注释"); } elseif(next.equals('*')) { skip(this.in,this.line,this.column,this.lineLength,this.program); //isAnnotation=true; //System.out.println("/*注释"); } } else { System.out.println("第"+line+"行"+"第"+column+"列"+"出现非法字符'"+now+"'"); } } } if(isAnnotation==true) { isAnnotation=false; } else { System.out.println("第"+line+"行缺少';'"); } } } catch(IOExceptione) { System.out.println("FileReadingError"); } } 函数分析: 此函数用于进行词法分析,其中有多处对分号的检查,所以比较复杂,但是报错精确,处理速度也有一定的优化。 其中在判定是否是保留字时使用了trie树这种数据结构,大大加快了搜索速度,将原来每次O(n*n)的时间复杂度提升为O(n*log(n)),极大地加快了搜索,当保留字数目较多时更能显示这种数据结构的优势,具体的trie树搜索算法将在后文中描述。 3.3用于处理注释的skip函数 voidskip(BufferedReaderin,intline,intcolumn,intlineLength,Stringprogram)throwsException { Characternow; //program=in.readLine(); while(true) { //System.out.println("skip: "+program); while(column++<=lineLength-2) { now=program.charAt(column); next=program.charAt(column+1); //System.out.print("line="+line); if(now.equals('*')&&next.equals('/')) { //System.out.println("return2"); this.program=program; this.column=column+2; this.line=line; this.lineLength=lineLength; this.in=in; return; } } program=in.readLine(); //System.out.print("skip: "+program); line++; column=-1; lineLength=program.length()-1; } } 函数分析: 此函数用于处理/*注释。 当Analysis函数判定程序中出现了/*时,调用此函数,skip函数会从此行开始持续往后读入字符,直到出现结束标志*/。 之后返回注释的结束行数及列数,继续词法分析。 3.4基于trie树的保留字搜索函数 publicbooleanSearchWord(Stringword) { returnSearchWords(word+"#",root,0); } privatebooleanSearchWords(Stringword,Vertexvertex,inthierarchy){ //System.out.println(word); Vertex[]edges=vertex.edges; intindex=0; if(hierarchy>word.le
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- java 实现 词法 分析