无符号数的识别.docx
《无符号数的识别.docx》由会员分享,可在线阅读,更多相关《无符号数的识别.docx(15页珍藏版)》请在冰豆网上搜索。
无符号数的识别
无符号数的词法分析程序
一、实验目的和要求
(1)初步掌握编译原理的实验的技能;
(2)验证所学理论、巩固所学知识并加深理解。
二、实验内容和原理
内容:
掌握词法分析的基本思想,并用高级语言编写无符号数(包括整数和实数)的词法分析程序。
要求:
从键盘中输入一字符串(包括字母、数字等),编写程序识别出其中的无符号数。
无符号数的文法规则课定义如下:
<无符号数><无符号实数>|<无符号整数>
<无符号实数><无符号整数>.<数字串>[E<比例因子>]
<比例因子><有符号整数>
<有符号整数>[+|-]<无符号整数>
<无符号整数><数字串>
<数字串><数字>{<数字>}
<数字>0123456789
本实验中我利用了状态转化图的思想,下面是试验中用到构造的状态转化图:
描述状态机的代码格式如下:
intstate=S0;
while
(1)
{
Switch(state)
{
caseS0:
if(T0转移条件满足){状态转移到满足T0的次态;操作;}
if(T1转移条件满足){状态转移到满足T1的次态;操作;}
if(T2转移条件满足){状态转移到满足T2的次态;操作;}
…
Break;
caseS1:
//插入S1状态下的操作;
break;
…
}
}
实验代码:
//本程序主要实现实数的识别
importjava.io.BufferedReader;
importjava.io.IOException;
importjava.io.InputStreamReader;
publicclassRealNumberIdentified{
/*---------------------------------成员变量的定义---------------------------------------*/
privatefinalintS_0=0;
privatefinalintS_1=1;
privatefinalintS_2=2;
privatefinalintS_3=3;
privatefinalintS_4=4;
privatefinalintS_5=5;
privatefinalintS_6=6;
privatefinalintS_7=7;
privatecharoriginNumber[];//用来记录原始的数字串
privateStringresultNumber=newString();
privateintrealnumberAmount=0;//用来记录识别出的实数的个数
privateintrealnumberFlag=0;//用于标识该实数是正数还是负数
privateinteFlag=0;//用来标识该实数是不是指数实数
privateintpointFlag=0;//用来标识该实数是否是小数
privateintbasePlusMinus=1;//用来标识底数的符号
privateintcount=0;//用来记录已经识别数字串的位数
privateintcurrentState=S_0;//用来记录当前所处于的状态
/*---------------------------------------------------------------------------------------*/
/*-------------------------该方法用来初始化一些参数------------------------------------*/
privatevoidinit()
{
resultNumber=newString();
basePlusMinus=1;
eFlag=0;
pointFlag=0;
}
/*----------------------------------------------------------------------------------------*/
/*---------------------init()方法用于去除实数串开始和结尾的无效的空格----------------*/
privatevoidinitOriginNumber(Stringstr)
{
str=str.trim();
str+='#';
originNumber=str.toCharArray();
}
/*-----------------------------------------------------------------------------------------*/
/*---------------------------printResult()方法用来输出识别的结果------------------------*/
privatevoidprintResult()
{
if(realnumberFlag==0)
System.out.println("\n识别结束,您所输入的字符串中不包含任何实数!
");
else
{
realnumberAmount++;
if(realnumberAmount==1)
System.out.println("\n识别结束,您所输入的字符串中所包含的实数如下:
");
if(resultNumber.length()!
=0)
{
if(eFlag==1)
if(basePlusMinus==1)
System.out.println("正指数实数:
"+Double.parseDouble(resultNumber));
else
System.out.println("负指数实数:
"+Double.parseDouble(resultNumber));
else
if(pointFlag==1)
System.out.println("小数:
"+Double.parseDouble(resultNumber));
else
{
if(basePlusMinus==1)
System.out.println("正整数:
"+Long.parseLong(resultNumber));
else
System.out.println("负整数:
"+Long.parseLong(resultNumber));
}
}
}
}
/*-----------------------------------------------------------------------------------------*/
/*--------------------------------识别该实数串的过程-------------------------------------*/
privatevoididentifiedProcess(Stringstr)
{
initOriginNumber(str);
while(count{
switch(currentState)
{
caseS_0:
{
if(originNumber[count]=='+')
{
resultNumber=resultNumber+originNumber[count];
currentState=S_1;
}
else
{
if(originNumber[count]=='-')
{
resultNumber=resultNumber+originNumber[count];
basePlusMinus=0;
currentState=S_1;
}
else
if(originNumber[count]>=48&&originNumber[count]<=57)
{
resultNumber=resultNumber+originNumber[count];
realnumberFlag=1;
currentState=S_2;
}
else
{
currentState=S_0;
}
}
count++;
break;
}
caseS_1:
{
if(originNumber[count]>=48&&originNumber[count]<=57)
{
resultNumber=resultNumber+originNumber[count];
realnumberFlag=1;
currentState=S_2;
}
else
{
resultNumber=resultNumber.substring(0,resultNumber.length()-1);
currentState=S_0;
}
count++;
break;
}
caseS_2:
{
if(originNumber[count]=='.')
{
resultNumber=resultNumber+originNumber[count];
currentState=S_3;
}
else
if(originNumber[count]>=48&&originNumber[count]<=57)
{
resultNumber=resultNumber+originNumber[count];
currentState=S_2;
}
else
if(originNumber[count]=='E'||originNumber[count]=='e')
{
resultNumber=resultNumber+originNumber[count];
currentState=S_5;
}
else
{
if(originNumber[count]=='+'||originNumber[count]=='-')
count--;
printResult();
init();
currentState=S_0;
}
count++;
break;
}
caseS_3:
{
if(originNumber[count]>=48&&originNumber[count]<=57)
{
resultNumber=resultNumber+originNumber[count];
pointFlag=1;
currentState=S_4;
}
else
{
resultNumber=resultNumber.substring(0,resultNumber.length()-1);
printResult();
init();
currentState=S_0;
}
count++;
break;
}
caseS_4:
{
if(originNumber[count]>=48&&originNumber[count]<=57)
{
resultNumber=resultNumber+originNumber[count];
currentState=S_4;
}
else
{
if(originNumber[count]=='E'||originNumber[count]=='e')
{
resultNumber=resultNumber+originNumber[count];
currentState=S_5;
}
else
{
if(originNumber[count]=='+'||originNumber[count]=='-')
count--;
printResult();
init();
currentState=S_0;
}
}
count++;
break;
}
caseS_5:
{
if(originNumber[count]=='+')
{
resultNumber=resultNumber+originNumber[count];
currentState=S_6;
}
else
if(originNumber[count]=='-')
{
resultNumber=resultNumber+originNumber[count];
currentState=S_6;
}
else
if(originNumber[count]>=49&&originNumber[count]<=57)
{
resultNumber=resultNumber+originNumber[count];
eFlag=1;
currentState=S_7;
}
else
{
resultNumber=resultNumber.substring(0,resultNumber.length()-1);
printResult();
init();
currentState=S_0;
count--;
}
count++;
break;
}
caseS_6:
{
if(originNumber[count]>=49&&originNumber[count]<=57)
{
resultNumber=resultNumber+originNumber[count];
eFlag=1;
currentState=S_7;
}
else
{
resultNumber=resultNumber.substring(0,resultNumber.length()-2);
printResult();
init();
currentState=S_0;
count-=2;
}
count++;
break;
}
caseS_7:
{
if(originNumber[count]>=48&&originNumber[count]<=57)
{
resultNumber=resultNumber+originNumber[count];
currentState=S_7;
}
else
{
if(originNumber[count]=='+'||originNumber[count]=='-')
count--;
printResult();
init();
currentState=S_0;
}
count++;
break;
}
}
}
printResult();
}
/*------------------------------------------------------------------------------------------*/
/*----------------------------------------主方法-------------------------------------------*/
publicstaticvoidmain(String[]args)throwsIOException{
System.out.print("请输入欲识别的实数:
");
BufferedReaderbuf=newBufferedReader(newInputStreamReader(System.in));
newRealNumberIdentified().identifiedProcess(buf.readLine());
}
/*------------------------------------------------------------------------------------------*/
}
三、实验结果
四、讨论、分析和心得
在本次试验我并没有采用课本中提供的算法,而是将在课本中学到的状态转化图和自动机的理论加以利用以基本实现本次实验的要求。
b
a
b
a
b
…
#
读头
控制器
将上面自动机的思想配上前面我画的状态转化图可以明白,初始设置currentStack位于S0处,每识别一个完整的数字会将currentStack重新赋值为S0,有事也有读头往回的情况发生例如:
9E1.1,应该读成数字9和1.1,但是在识别过程中会一直识别到’.’才会发现这个数不是一个指数实数,这样一直读下去即可将整个符号串中数字识别出来。