java实现的词法分析文档格式.docx
《java实现的词法分析文档格式.docx》由会员分享,可在线阅读,更多相关《java实现的词法分析文档格式.docx(29页珍藏版)》请在冰豆网上搜索。
1.保留字
2.运算符及界符
3.标识符(字母大小写不敏感),整型常数
1.3词汇表
对于后文正则式中可能出现的符号定义如下,以便清晰地描述A语言的正则式
符号
说明
a
字母
b
数字
c
符号(不包括字母和数字)
*
闭包运算符
|
或运算符
.
连接运算符(可省略)
空
#
结束符
二词法分析器程序的系统分析
2.1词法形式化描述
正则式
意义
举例
a(a|b)*
标识符或保留字
Lex1,program
b*
常数
12345
运算符或界符或非法字符
+,*,(,)等
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状态转换图
其中:
识别标识符或保留字
识别常数
识别加运算符
识别乘运算符
识别赋值运算符
识别大于等于运算符,大于运算符并加以区分
识别小于等于运算符,不等于运算符,小于运算符并加以区分
识别括号,逗号,点号,分号,等于号
其余所有无法被此状态转换图识别的符号视为非法符号。
三词法分析器程序系统设计
词法分析器程序由一个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
文件已编译完成"
}
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());
}
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);
}*/
elseif(Character.isDigit(next))
while(Character.isDigit(next))
{
lexSegment.append(next);
column++;
if(column>
break;
next=program.charAt(column);
}
column--;
lexSegment.toString(),4,lex.binaryTeamLengthUsed);
elseif(next<
'
||next>
lexSegment.toString(),5,lex.binaryTeamLengthUsed);
elseif(now.equals('
+'
))
signal.append("
运算符"
symbol[0],1,signal.binaryTeamLengthUsed);
isFinished=true;
*'
symbol[1],1,signal.binaryTeamLengthUsed);
('
symbol[2],1,signal.binaryTeamLengthUsed);
)'
symbol[3],1,signal.binaryTeamLengthUsed);
'
symbol[4],1,signal.binaryTeamLengthUsed);
.'
symbol[5],1,signal.binaryTeamLengthUsed);
column++;
if(program.charAt(column)=='
symbol[6],1,signal.binaryTeamLengthUsed);
isFinished=true;
System.out.println("
第"
+line+"
行出现非法字符'
"
symbol[7],1,signal.binaryTeamLengthUsed);
if(column==lineLength)
isAnnotation=true;
elseif(column+1<
=lineLength&
program.charAt(column+1)=='
/'
>
symbol[11],1,signal.binaryTeamLengthUsed);
symbol[8],1,signal.binaryTeamLengthUsed);
<
symbol[12],1,signal.binaryTeamLengthUsed);
elseif(program.charAt(column)=='
symbol[13],1,signal.binaryTeamLengthUsed);
symbol[9],1,signal.binaryTeamLengthUsed);
symbol[10],1,signal.binaryTeamLengthUsed);
if(column+1<
=lineLength)
行"
+"
+column+"
列"
出现非法字符'
+now+"
if(next.equals('
column=lineLength;
//isAnnotation=true;
//System.out.println("
注释"
elseif(next.equals('
skip(this.in,this.line,this.column,this.lineLength,this.program);
/*注释"
else
System.out.println("
if(isAnnotation==true)
isAnnotation=false;
System.out.println("
行缺少'
}
}
catch(IOExceptione)
System.out.println("
FileReadingError"
}
函数分析:
此函数用于进行词法分析,其中有多处对分号的检查,所以比较复杂,但是报错精确,处理速度也有一定的优化。
其中在判定是否是保留字时使用了trie树这种数据结构,大大加快了搜索速度,将原来每次O(n*n)的时间复杂度提升为O(n*log(n)),极大地加快了搜索,当保留字数目较多时更能显示这种数据结构的优势,具体的trie树搜索算法将在后文中描述。
voidskip(BufferedReaderin,intline,intcolumn,intlineLength,Stringprogram)throwsException
Characternow;
//program=in.readLine();
//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;
//System.out.print("
line++;
column=-1;
lineLength=program.length()-1;
此函数用于处理/*注释。
当Analysis函数判定程序中出现了/*时,调用此函数,skip函数会从此行开始持续往后读入字符,直到出现结束标志*/。
之后返回注释的结束行数及列数,继续词法分析。
publicbooleanSearchWord(Stringword)
returnSearchWords(word+"
#"
root,0);
privatebooleanSearchWords(Stringword,Vertexvertex,inthierarchy){
//System.out.println(word);
Vertex[]edges=vertex.edges;
intindex=0;
if(hierarchy>
word.le