词法分析器文档.docx
《词法分析器文档.docx》由会员分享,可在线阅读,更多相关《词法分析器文档.docx(17页珍藏版)》请在冰豆网上搜索。
词法分析器文档
词法分析器说明书
华南理工大学广州汽车学院
2007级计算机1班
邹明汕、严嘉健
词法分析器是通过编写程序,对字符集进行识别。
字符集包括保留字,标识符,整数,字符常数和符号(双界符,单界符)。
每次遇到相应的单词时输出单词的种别码,如果单词不在单词表的范围内则输出报错信息。
另外如果双界符不是成对出现程序也可测出错误并报错。
词法分析器功能:
识别指定路径下的文本文档中的内容,并输出单词的种别码,对超出范围的单词报错,对不成对的双界符{},‘’,【】报错,对错误标识符报错,如:
1a。
关键代码分析:
程序代码主要分为三个模块
1、模块一
主函数模块
功能:
对规定路径下的文本文档中的内容进行断句,然后录入数组操作。
首先用i=f.get()从文件中取出一个字符并赋值给i,i为该字符的ASC值,为整数。
并将i存入一个足够大的数组中a[n]=i;
用while()函数循环此操作,遇到空格或换行或文件结束符或符号时,添加自定义的结束标示符127,然后调用字符集识别函数scan(inta[]),在确定调用scan(inta[])之前还要数组中存放的单词是否是否是符号,如果是符号,需要判别该符号是否是双界符,否则程序会将双界符分开两次传送造成识别错误。
该模块还对双界符{},‘’,【】是否成对出现进行判断,当遇到左符号是计数器t加1,遇到有符号时计数器t减1。
如果最后t不为0时报错。
2、模块二
识别函数模块scan(inta[])
功能:
根据单词编码表判别单词的种别码
该函数模块分为六小部分,分别用标志符flag区分,把单词表中的保留字字符存放在指针数组char*p[35]中,符号存放在指针数组char*q[22]中,作为比较的标准。
flag0为保留字判断,代码会通过for循环对单词的逐个字符和指针数组char*p[35]中的保留字进行比较,判断单词是否为保留字。
如果不是则自动进入flag1中判断单词是否为整数,整数的ASC值范围是48到57。
如果不是则自动进入flag2中判断单词是否为标识符,标识符的ASC值范围是65到90和97到122。
如果不是则进入flag3中判断单词是否为字符常数,字符常数判断的重要标准:
单词前后是否含有单引号。
单引号的ASC值是39,
如果不是进入flag4中判断单词是否为符号,代码会通过for循环对单词的逐个字符和指针数组char*q[22]中的符号进行比较,判断单词是否为符号。
如果不是程序则自动进入flag10,并调用输出函数show()报错。
3、模块三
输出函数show(intk,inta[],intflag)
功能:
按照样板的输出标准,输出单词的种别码,如果有错误则报错。
根据flag标志位进行输出,当flag为0和4时输出标准为<种别码,—>
当flag为1、2、3时输出标准为<种别码,n>,把文件中的标识符,整数,字符常数不重复的放入一个足够大的数组中,每次放入前比较数组中是否含有相同的单词,如果没有则添加进数组,并输出该单词在数组中的位置n,反之,输出数组中和该单词相同单词的位置n,n是单词在数组中的序号,按照比较顺序排放。
当flag为10是输出报错信息
附录:
#include
#include
#include
ints=0;
intq[100];
voidshow(intk,inta[],intflag)
{
s++;
inti,j,f1,f2=0,h,t=1;
if(flag==0||flag==4)
{
cout<<"("<}
if(flag==1||flag==2||flag==3)
{
cout<<"("<for(i=0,h=0;i<100;i++,h++)
{
if(f2==1)
{h=0;f2=0;}
if(q[0]==NULL)
{
for(i=0;i<100;i++)
{
q[i]=a[i];
if(a[i]==127)
{
i=0;
break;
}
}
cout<break;
}
if(a[h]==127)
{
cout<break;
}
if(q[i]!
=a[h])
{
for(j=i;j<100;j++)
{
if(q[j]==127)
{
if(q[j+1]==NULL)
{
for(j=j+1,h=0;j<100;j++,h++)
{
q[j]=a[h];
if(a[h]==127)
{
cout<f1=1;
break;
}
}
}
i=j;
t++;
f2=1;
break;
}
}
if(f1==1)
{f1=0;break;}
}
}
cout<<")"<<"";
}
if(flag==10)
{cout<<"("<<"error"<<")"<<"";}
if(s%5==0)
{cout<}
voidscan(inta[])
{
intn,flag,k,r;
char*q[22]={"(",")","*","*/","+",",","-",".","..","/","/*",
":
",":
=",";","<","<=","<>","=",">",">=","[","]"};
char*p[35]={
"and","array","begin","bool","call","case","char","constant",
"dim","do","else","end","false","for","if","input","integer","not",
"of","or","output","procedure","program","read","real","repeat",
"set","stop","then","to","true","until","var","while","write"
};
if(a[0]>=48&&a[0]<=57)
for(n=1;a[n]!
=127;n++)
{
if(a[n]>=65&&a[n]<=90||a[n]>=97&&a[n]<=122)
{
flag=10;
k=0;
show(k,a,flag);
return;
}
}
flag=0;
if(flag==0)
{
for(k=0;k<35;k++)
{
n=0;
while(*(p[k]+n)!
=NULL)
{
if(a[n]!
=int(*(p[k]+n)))
break;
if(*(p[k]+n+1)==NULL&&a[n+1]==127)
{
show(k+1,a,flag);
return;
}
n++;
}
}
}
flag=1;
if(flag==1)
{
n=0;
while(a[n]!
=127)
{
if(a[n]<48||a[n]>57)
break;
n++;
if(a[n]==127)
{
k=37;
show(k,a,flag);
return;
}
}
}
flag=2;
if(flag==2)
{
n=0;
while(a[n]!
=127)
{
if(a[n]>=65&&a[n]<=90||a[n]>=97&&a[n]<=122||a[n]>=48&&a[n]<=57)
n++;
elsebreak;
if(a[n]==127)
{
k=36;
show(k,a,flag);
return;
}
}
}
r=0;
flag=3;
if(flag==3)
{
n=0;
while(a[n]!
=127)
{
if(a[n]==39)
{
r++;
n++;
}
if(a[n]!
=123&&a[n]!
=125)
n++;
else
{flag=10;show(k,a,flag);}
if(a[n]==39)
{
r--;
k=38;
show(k,a,flag);
return;
}
}
if(r!
=0)
{
flag=10;
show(k,a,flag);
return;
}
}
flag=4;
if(flag==4)
{
for(k=0;k<22;k++)
{
n=0;
while(*(q[k]+n)!
=NULL)
{
if(a[n]!
=int(*(q[k]+n)))
break;
if(*(q[k]+n+1)==NULL&&a[n+1]==127)
{
k=k+39;
show(k,a,flag);
return;
}
n++;
}
}
}
flag=10;
if(flag==10)
{
if(a[0]=!
32&&a[0]!
=10)
{show(k,a,flag);}
}
}
voidmain()
{
inta[15];
inti,n,j,t1,t2,t3,t4;
i=0;
n=0;
t1=0;t2=0;t3=0;t4=0;
fstreamf("c:
\\词法分析器.txt",ios:
:
in);
while
(1)
{
i=f.get();
if(f.eof()==1)
{
if(n!
=0)
{
a[n]=127;
scan(a);
break;
}
break;
}
if(i==10)
{
a[n]=127;
scan(a);
n=0;
}
if(i==32&&n!
=0)
{
a[n]=127;
scan(a);
n=0;
}
if(i>=40&&i<=47||i>=58&&i<=62||i==91||i==93)
{
if(i==40)
{
t1++;
}
if(i==41)
{
t1--;
}
if(i==91)
{
t2++;
}
if(i==93)
{
t2--;
}
if(i==39)
{
t3++;
}
if(n!
=0)
{
a[n]=127;
scan(a);
n=0;
}
a[n]=i;
n++;
i=f.get();
if(i>=40&&i<=47||i>=58&&i<=62||i==91||i==93)
{
if(i==42)
{
t4++;
n=0;
}
elseif(i==47)
{
t4--;
n=0;
i=32;
}
else
{
a[n]=i;
n++;
a[n]=127;
scan(a);
n=0;
i=f.get();
}
}
else
{
a[n]=127;
scan(a);
n=0;
}
}
if(i!
=32&&i!
=10&&t4==0)
{
a[n]=i;
n++;
}
}
if(t1!
=0)
{
cout<<"错误:
缺少(或)"<}
if(t2!
=0)
{
cout<<"错误:
缺少[或]"<}
if(t3%2!
=0)
{
cout<<"错误:
缺少'"<}
if(t4!
=0)
{
cout<<"错误:
缺少/*或*/"<}
f.close();
}
单词表:
单词
种别码
单词
种别码
单词
种别码
and
1
output
21
*
41
array
2
procedure
22
*/
42
begin
3
program
23
+
43
bool
4
read
24
44
call
5
real
25
-
45
case
6
repeat
26
.
46
char
7
set
27
..
47
constant
8
stop
28
/
48
dim
9
then
29
/*
49
do
10
to
30
:
50
else
11
true
31
:
=
51
end
12
until
32
;
52
false
13
var
33
<
53
for
14
whilr
34
<=
54
if
15
write
35
<>
55
input
16
标识符
36
=
56
integer
17
整数
37
>
57
not
18
字符常数
38
>=
58
of
19
(
39
[
59
or
20
)
40
]
60