⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dfa.cpp

📁 有穷自动机识别源码
💻 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 + -