词法分析程序.docx
《词法分析程序.docx》由会员分享,可在线阅读,更多相关《词法分析程序.docx(16页珍藏版)》请在冰豆网上搜索。
词法分析程序
词法分析器
1、本程序目的:
针对C语言的词法分析程序。
2、设计思路:
1、将文件input.txt中的数据放入数组program[]中,文件原本位置为d:
\\input.txt;
2、将结果保存在类数组token(type,string)中,属性type存字符串类型,属性string存字符串本身;
3、设全局变量inti记录当前处理字符的位置;
4、从charc=program[0]开始处理,判断当前字符的类型
1)若isChar(c)为真,调用intdealWithChar(charc,intn)处理,其中c为当前处理字符,n为当前字符所在位置。
返回n值,当前处理位置向前推一位,即i=n-1;
2)若isNumber(c)为真,调用intdealWithChar(charc,intn)处理,原理同上;
3)若isOperator(c)为真,调用intdealWithOperator(charc,intn)处理,原理同上;
4)若isSeperator(c)为真,调用intdealWithSeperator(charc,intn)处理,原理同上;
5、上面四种处理方法已分别将相应字符串放入tokens中,依次输出tokens中的值。
2、各类单词
单词符号
种别码
单词符号
种别码
bgin
1
:
17
If
2
:
=
18
then
3
<
20
while
4
<>
21
do
5
<=
22
end
6
>
23
lettet(letter|digit)*
10
>=
24
dightdight*
11
=
25
+
13
;
26
-
14
(
27
*
15
)
28
/
16
#
0
三、程序流程图:
是
否
字母数字
运算符、界符
否
是
图3-2
四、
C词法分析程序的java语言程序源代码:
importjava.io.File;
importjava.io.FileInputStream;
importjava.io.FileNotFoundException;
importjava.io.IOException;
importjava.io.RandomAccessFile;
importjava.util.Vector;
publicclassMyLexicalAnalysis{
publicstaticfinalintEND_OF_FILE=65535;
privateString[]keyword=newString[]{"begin","if","then","while","do","end"};//记录关键字
privateStringoperator[]={"-","+","*","/","<",">","=",":
"};
privateStringseperator[]={"(",")",";"};//不是分隔符和比较运算符,只是组成分隔符和运算符的元素。
classToken{//因为动态数组只能存类,所以构造一个类保存信息。
Token(inttyp,Stringst)//字符串类型和内容。
{
type=typ;
str=st;
}
publicinttype;
publicStringstr;
}
privateVectortokens=newVector();//动态对象数组
//输入流
privateFileInputStreamfis;
charprogram[]=newchar[1000];
MyLexicalAnalysis()throwsIOException
{
intlocation=0;
fis=newFileInputStream(newFile("d:
\\input.txt"));
charc=(char)fis.read();
while((int)c!
=END_OF_FILE)//检查是否到文件末尾
{
program[location]=c;
c=((char)fis.read());
location++;
}
}
//执行方法
publicvoiddoAnalysis()throwsIOException//处理程序内容
{
inti=0;
charc;
intn;
while(i{
c=program[i];
if(c=='#')tokens.add(newToken(0,"#"));
if(isChar(c)){//如果开始字符是字母,转入字母处理函数,可能结果为保留字或标识符
n=dealWithChar(c,i);i=n-1;}
if(isNumber(c)){//如果开始字符是数字,转入数字处理函数,可能结果为整数
n=dealWithNumber(c,i);i=n-1;}
if(isOperator(c)){//开始字符是操作符或比较运算符
n=dealWithOperator(c,i);i=n-1;}
if(isSeperator(c)){//开始是分隔符
n=dealWithSeperator(c,i);i=n-1;}
i++;
}
}
//第一个字符是字母的处理方法
privateintdealWithChar(charc,intn)throwsIOException{
Stringstr=newString();
while(isChar(c))//将连着的字母放入类的属性str中
{
str=str+c;
n++;
c=program[n];
}
intj=0;
for(j=0;j<6;j++){
if(str.equals(keyword[j])){//如果是关键字
tokens.add(newToken(j+1,str));
break;
}
}if(j==6)tokens.add(newToken(10,str));//不是关键字
returnn;
}
//第一个字符是数字的处理方法
privateintdealWithNumber(charc,intn)throwsIOException{
Stringstr=newString();
while(isNumber(c))//是数字,则加到str中;不是数字,则str就是识别出的数,将str加入到tokens中
{
str=str+c;
n++;
c=program[n];
}
Tokentoken=newToken(11,str);
tokens.add(token);
returnn;
}
privateintdealWithSeperator(charc,intn)throwsIOException{
Stringstr=newString();
str=str+c;
if(str.equals(";"))tokens.add(newToken(26,str));
if(str.equals("("))tokens.add(newToken(27,str));
if(str.equals(")"))tokens.add(newToken(28,str));
n++;
returnn;
}
//第一个字符是操作符和运算符
privateintdealWithOperator(charc,intn)throwsIOException{
Stringstr=newString();
str=str+c;
n++;
c=program[n];
if(isOperator(c)){str=str+c;n++;}
if(str.equals("+"))tokens.add(newToken(13,str));
if(str.equals("-"))tokens.add(newToken(14,str));
if(str.equals("*"))tokens.add(newToken(15,str));
if(str.equals("/"))tokens.add(newToken(16,str));
if(str.equals(":
"))tokens.add(newToken(17,str));
if(str.equals(":
="))tokens.add(newToken(18,str));
if(str.equals("<"))tokens.add(newToken(20,str));
if(str.equals("<>"))tokens.add(newToken(21,str));
if(str.equals("<="))tokens.add(newToken(22,str));
if(str.equals(">"))tokens.add(newToken(23,str));
if(str.equals(">="))tokens.add(newToken(24,str));
if(str.equals("="))tokens.add(newToken(25,str));
returnn;
}
//判断是否是字母(包括下划线)
privatebooleanisChar(charc)
{
if((c<='z'&&c>='A')||c=='_')
returntrue;
else
returnfalse;
}
//判断是否是数字
privatebooleanisNumber(charc)
{
if(c>'9'||c<'0')
returnfalse;
else
returntrue;
}
//判断是否是运算符
privatebooleanisOperator(charc){
Stringstr=newString();
str=str+c;
for(intj=0;jif(str.equals(operator[j])){
returntrue;
}
}
returnfalse;
}
//判断是否是分隔符
privatebooleanisSeperator(charc){
if((c!
=';')&&(c!
='(')&&(c!
=')'))returnfalse;
elsereturntrue;
}
//打印tokens内容
publicvoidprintTokens()
{
for(inti=0;i{
inttype=tokens.elementAt(i).type;
Stringstr=tokens.elementAt(i).str;
System.out.println("("+type+","+str+")");
}
}
publicstaticvoidmain(String[]args)throwsIOException{
MyLexicalAnalysislx=newMyLexicalAnalysis();
//处理
lx.doAnalysis();
//输出
lx.printTokens();
}
}
5、程序运行测试
input.txt
#include
intmain(void)
{
inti,m;
printf("Enteranumber:
");
scanf("%d",&m);
for(i=2;i<=m/2;i++)
if(m%i==0)
break;
if(i>m/2)
printf("%disaprimenumber!
\n",m);
else
printf("No!
\n");
return0;
}
Output.txt
(0,#)
(10,include)
(20,<)
(10,studio)
(10,h)
(23,>)
(10,int)
(10,main)
(27,()
(10,void)
(28,))
(10,int)
(10,i)
(10,m)
(26,;)
(10,printf)
(27,()
(10,Enter)
(10,a)
(10,number)
(17,:
)
(28,))
(26,;)
(10,scanf)
(27,()
(10,d)
(10,m)
(28,))
(26,;)
(10,for)
(27,()
(10,i)
(25,=)
(11,2)
(26,;)
(10,i)
(22,<=)
(10,m)
(16,/)
(11,2)
(26,;)
(10,i)
(28,))
(2,if)
(27,()
(10,m)
(10,i)
(11,0)
(28,))
(10,break)
(26,;)
(2,if)
(27,()
(10,i)
(23,>)
(10,m)
(16,/)
(11,2)
(28,))
(10,printf)
(27,()
(10,d)
(10,is)
(10,a)
(10,prime)
(10,number)
(10,\n)
(10,m)
(28,))
(26,;)
(10,else)
(10,printf)
(27,()
(10,No)
(10,\n)
(28,))
(26,;)
(10,return)
(11,0)
(26,;)
六、备注,很多符号都没有给出标识符或者跟你要求的不一样,但只要你读懂代码很容易就能加上或更改。
本程序也不具有过滤注释和确定单词位置的功能,相信你稍加思考就能加上,可能不久本人会有更新。