📄 dfa.cpp
字号:
//本程序应用有穷自动机原理对用户输入无符号数进行词法分析。
//由于课题对文法的规定,所以本程序仅实现无符号整型数、无符号实型数
//及科学计数法表示的无符号实型数,其格式如:123、123.12、.214、12E+2、
//2.23e-32、34.5e34,但将1234.及12.E23作为非法数据。
//
//本程序由一个主程序和两个函数组成:
//函数 int IfNum(int ch) 用于判断字符是否为数字、+、-、E、e、.及空格;
//函数 void Vdfa(char ch[],int clen)应用自动机原理DFA对数据进行词法分析;
//
#include<iostream.h> //头文件说明;
const int SIZE=80; //常量SIZE定义;
int IfNum(int ch); //函数IfNum说明;
void Vdfa(char ch[],int clen); //函数Vdfa说明;
//
//主程序说明:
//程序中变量说明如下:
//INnum:记录用户输入数据的个数;
//INbiao[40][2]:记录每个数据在输入字符串中的起始、结束位置;
//ICount:记录输入字符串中共有多少个字符;
//IIsame:用于判断整个输入字符串中有几个数据段;
//INcount:记录每个字符段字符个数;
//i、j:用于数组下标,循环调用;
void main()
{
int INnum(0),INbiao[40][2],ICount(0);
int IIfsame(5),i;
char CBuf[SIZE],CNch[SIZE];
cout<<"**本程序应用有穷自动机原理对用户输入无符号数进行词法分析**"<<endl;
cout<<" 作者:樊志平 二零零四年六月十日"<<endl;
cout<<'\n'<<"请以空格为界符输入一个或多个无符号数:\n";
cin.getline(CBuf,SIZE); //getline(char,int)函数读取一行字符串;
ICount=cin.gcount(); //gcount()函数得到getline函数读入字符串长度;
for(i=0;i<ICount-1;i++) //由空格与其它字符间的交替变化获取字符串中独
{ //立字符段的个数,并将各字符段位置存入数组;
if(IfNum(CBuf[i])!=5 && IIfsame==5)
{
INnum++;
IIfsame=0;
INbiao[INnum-1][0]=i;
}
if(IfNum(CBuf[i])==5 && IIfsame!=5)
{
IIfsame=5;
INbiao[INnum-1][1]=i-1;
}
}
if(IfNum(CBuf[ICount-2])!=5) //当字符串结尾无空格时的特殊处理;
INbiao[INnum-1][1]=ICount-2;
cout<<'\n'<<"用户共输入了"<<INnum<<"个数据,进行词法分析结果如下:"<<endl;
for(i=0;i<INnum;i++) //对所获各字符段进行分析;
{
int INcount,j;
INcount=INbiao[i][1]-INbiao[i][0]+1; //获取该段字符段字符个数;
for(j=0;j<INcount;j++)
{
CNch[j]=CBuf[INbiao[i][0]+j]; //获取该段字符段字符到CNch;
}
CNch[j]='\0'; //添加字符串结束标记;
cout<<"["<<i+1<<"] "<<CNch<<": "<<"\n ";
Vdfa(CNch,INcount); //调用Vdfa()函数进行词法分析;
}
}
//
//
//函数 int IfNum(int ch) 用于判断字符是否为数字、+、-、E、e、.及空格;
//若是其它字符返回0,数字返回1,.返回2,e或E返回3,+或-返回4,空格返回5;
//变量说明:
//ch:对应调用函数需分析字符的ASCII码;
//result:记录返回值;
int IfNum(int ch)
{
int result(0);
if(ch>=48 && ch<=57)
result=1; //数字返回1;
else if(ch==46)
result=2; //.返回2;
else if(ch==69 || ch==101)
result=3; //e或E返回3;
else if(ch==43 || ch==45)
result=4; //+或-返回4;
else if(ch==32)
result=5; //空格返回5;
else
result=0; //其它字符返回0;
return result;
}
//
//函数 void Vdfa(char ch[],int clen)应用自动机原理DFA对数据进行词法分析;
//根据课题规定文法的要求,共提供22种错误信息,三种正确分析结果;
//正确结果有:无符号整型数、无符号实型数、科学计数法表示的无符号实型数;
//变量说明:
//ch[]:需进行词法分析的字符段;
//clen:该字符段的的长度;
//IState:词法分析中所对应的状态,从0—6共七种状态,其中0状态为起始状态;
// 1、3、6为三种终态,分别对应三种正确结果;
//IZero:记录首字符是否为“0”;
//i:为循环用变量;
void Vdfa(char ch[SIZE],int clen)
{
int IState(0),IZero;
for(int i=0;i<clen;i++) //验证字符段中是否有非法字符;
{
if(!IfNum(ch[i]))
{
cout<<"ERROR20:用户在数据中输入了非法字符:"<<ch[i]<<endl;
return;
}
switch(IState) //根据7种状态进行不同的分析;
{
case 0:
switch(IfNum(ch[i]))
{
case 1:
if(ch[i]!='0') //验证起始字符是否为“0”;
IZero=1;
else
IZero=0;
IState=1;break;
case 2:IState=2;break;
case 3:IState=4;break;
case 4:cout<<"ERROR01:用户在数据前错误输入了符号:"<<ch[i]<<"!\n";
return;
case 5:cout<<"ERROR00:程序错误!\n";
return; //因字符段中不应有空格,所以若有则定是程序错误;
}
break;
case 1:
switch(IfNum(ch[i]))
{
case 1:
if(IZero) //判断首字符是否为0;
{ IState=1;break;}
else
cout<<"ERROR21:用户在数据中第一个字符错误输入0!\n";
return;
case 2:IState=2;break;
case 3:
if(IZero)
{ IState=4;break;}
else
cout<<"ERROR21:用户在数据中第一个字符错误输入0!\n";
return;
case 4:
cout<<"ERROR02:用户在整数部分错误输入了符号:"<<ch[i]<<"!\n";
return;
case 5:cout<<"ERROR00:程序错误!\n";
return;
}
break;
case 2:
switch(IfNum(ch[i]))
{
case 1:IState=3;break;
case 2:cout<<"ERROR03:用户在数据中重复输入了两个小数点!\n";
return;
case 3:cout<<"ERROR04:用户在数据中小数点后错误输入了符号:"<<ch[i]<<"!\n";
return;
case 4:cout<<"ERROR05:用户在数据中小数点后错误输入了符号:"<<ch[i]<<"!\n";
return;
case 5:cout<<"ERROR00:程序错误!\n";
return;
}
break;
case 3:
switch(IfNum(ch[i]))
{
case 1:IState=3;break;
case 2:cout<<"ERROR06:用户在数据中小数部分错误输入了小数点!\n";
return;
case 3:IState=4;break;
case 4:cout<<"ERROR07:用户在数据中小数部分错误输入了符号:"<<ch[i]<<"!\n";
return;
case 5:cout<<"ERROR00:程序错误!\n";
return;
}
break;
case 4:
switch(IfNum(ch[i]))
{
case 1:IState=6;break;
case 2:cout<<"ERROR08:用户使用科学计数法时在指数部分错误输入了小数!\n";
return;
case 3:cout<<"ERROR09:用户使用科学计数法时重复输入了:"<<ch[i]<<"!\n";
return;
case 4:IState=5;break;
case 5:cout<<"ERROR00:程序错误!\n";
return;
}
break;
case 5:
switch(IfNum(ch[i]))
{
case 1:IState=6;break;
case 2:cout<<"ERROR10:用户使用科学计数法时在指数部分错误输入了小数!\n";
return;
case 3:cout<<"ERROR11:用户使用科学计数法时在指数部分错误输入:"<<ch[i]<<"!\n";
return;
case 4:cout<<"ERROR12:用户使用科学计数法时错误输入:"<<ch[i]<<"!\n";
return;
case 5:cout<<"ERROR00:程序错误!\n";
return;
}
break;
case 6:
switch(IfNum(ch[i]))
{
case 1:IState=6;break;
case 2:cout<<"ERROR13:用户使用科学计数法时在指数部分输入了小数!\n";
return;
case 3:cout<<"ERROR14:用户使用科学计数法时在指数部分错误输入了:"<<ch[i]<<"!\n";
return;
case 4:cout<<"ERROR15:用户使用科学计数法时在指数部分错误输入:"<<ch[i]<<"!\n";
return;
case 5:cout<<"ERROR00:程序错误!\n";
return;
}
}
}
switch(IState) //当字符段全部字符分析无误是,由结束时不同状态确定不同结果;
{
case 0:cout<<"ERROR16:用户输入数据为空!\n";break;
case 1:cout<<"RESULT1:无符号整型数。\n";break;
case 2:cout<<"ERROR17:用户输入数据为无小数部分实型数,在此为错误!\n";break;
case 3:cout<<"RESULT2:无符号实型数。\n";break;
case 4:cout<<"ERROR18:用户使用科学计数法表示实型数,但没有指数部分!\n";break;
case 5:cout<<"ERROR19:用户使用科学计数法表示实型数,在指数部分仅有正负号!\n";break;
case 6:cout<<"RESULT3:科学计数法表示的无符号实型数。\n";
}
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -