栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

词法分析器

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

词法分析器

一、实验目的

编制一个词法识别程序

二、实验题目

假设某语言允许的标识符为字母开头的字母数字串,允许的数据为无符号的十进制或十六进制整数。其中规定十六进制数必须以数字打头、以H结尾,数中允许使用的字母为A,B,C,D,E,F(分别表示10~15)。试设计一个DFA,使它能识别标识符、无符号的十进制和十六进制整数(假定各单词之间用界限符或空格分开),并编制相应的词法识别程序。

输入:可以自定义符号串的输入形式,如键盘输入、文本文件、字符数组等。

输出:标识出规范的符号串与不合规范的符号串。

三、分析与设计

0状态是初始状态。1,2,3是终止状态。
在初始状态0时,输入数字会进入状态2,即将输出十进制或十六进制的整数,输入字母会进入状态1,即将输出字母开头的标识符
在状态2时,术后如数字仍然进入2,输入A-F的字母或H,即将输出十六进制的整数,作为终止状态之一,如果输入空格,就输出该字符串,并重新进入到状态0
在状态1时,允许输入字母或是数字,并仍然处于状态1,如果输入空格,就输出该字符串,并重新进入到状态0
在状态4时,输出的应为十六进制,但结尾要为H,故而输入数字或是A-F仍然进入状态4,但输入H会进入状态3
在状态3时,如果输入空格就输出,并重新加入状态0,其他非空格外的输入都是非法输入

四、源代码
#include
#include

enum type {digit,space,Hh,AF,letter} ;

//判断.数字:1 ﹔空格:2;H(h):3;字母A,B,C,D,E,F:4;其它字母:5
int isDigitOrChar (char ch) {
	//数字
	if(ch>=48 && ch<=57)
		return digit;
	//空格
	else if( ch == 32 )
		return space;
	//H or h
	else if( ch == 72 || ch == 104 )
		return Hh;
	//字母A,B,C,D,E,F
	else if((ch>=65 && ch<=70)||(ch>=97 && ch<=102))
		return AF;
	//除A~F外的其它字母
	else if((ch>=65 && ch<=90)||(ch>=97 && ch<=122))
		return letter;
}

int main() {
	//测试的输入符号串
	char words[100]=" Ae35 6638 5392H A10 83A2Eh 65Ha 3G2H 80 ";
	printf("Input string is: %snn",words);
	//指向输入符号串中当前的字符
	char *q;
	//存储当前识别的单词
	char word[20];
	//表示所处的状态
	int state=0;
	//单词的下标
	int i;
	q = words;
	while(*q) {
		switch(state) {
			case 0: //当前为0状态
				switch( isDigitOrChar(*q)) {
					case digit: //数字
						word[i++]=*q;
						state = 2;
						break;
					case Hh: //H or h
					case AF: //字母A,B,C,D,E, F or a, b, c, d,e,f
					case letter: //字母
						word[i++] =*q;
						state = 1;
						break;
					case space: //空格
						state = 0;
						break;
					default: //其它(非法字符)
						word[i++]=*q ;
						state = 5; //转移到出错状态
				}
				break ;
			case 1: //当前为1状态
				switch ( isDigitOrChar (*q)) {
					case digit : //数字
					case Hh: //H or h
					case AF: //字母A,B,C, D,E,F or a, b, c, d,e,
					case letter: //字母
						word[i++]= *q;
						state = 1;
						break ;
					case space://空格
						word[i]=''; //当前单词结束
						printf("%s is an identifier. n" , word) ;
						strcpy(word,""); //单词清空
						i=0; //重新计数
						state = 0;
						break;
					default: //其它(非法字符)
						word[i++] =*q;
						state = 5; //转移到出错状态
				}
				break;
			case 2: //当前为2状态
				switch( isDigitOrChar(*q)) {
					case digit: //数字
						word[i++] = *q ;
						state = 2;
						break;
					case Hh: //H or h
						word[i++]= *q ;
						state = 3;
						break;
					case AF: //字母A,B,C,D,E,F or a, b, c,d,e,f
						word[i++] =*q ;
						state = 4;
						break;
					case space: //空格
						word[i]=''; //当前单词结束
						printf("%s is an Integer. n" , word) ;
						strcpy (word,""); //单词清空
						i=0; //重新计数
						state = 0;
						break;
					default: //其它(非法字符)
						word[i++] =*q;
						state = 5; //转移到出错状态
				}
				break ;
			case 3: //当前为3状态
				switch ( isDigitOrChar (*q)) {
					case space: //空格
						word[i]=''; //当前单词结束
						printf("%s is a Hex digit. n" , word) ;
						strcpy (word,""); //单词清空
						i=0; //重新计数
						state = 0;
						break;
					default: //其它(非法字符)
						word[i++]=*q ;
						state = 5; //转移到出错状态
				}
				break;
			case 4: //当前为4状态
				switch ( isDigitOrChar (*q)) {
					case digit: //数字
						word[i++] =*q;
						state = 4;
						break;
					case AF: //字母A,B,C,D,E, F or a, b, c,d, e,f
						word[i++]=*q ;
						state = 4;
						break;
					case Hh: //H or h
						word[i++]=*q;
						state = 3;
						break ;
					default: //其它(非法字符)
						word[i++]=*q;
						state = 5; //转移到出错状态
				}
				break;
			case 5: //出错状态
				if(*q == 32 ) { //空格(当前单词结束)
					word[i]='';
					printf("%s is not an identifier. n",word);
strcpy (word,"")); //单词清空
					i=0; //重新计数
					state = 0 ; //重新开始提取单词
				} else { //当前单词还未结束
					word[i++] =*q;
					//添加到单词尾部
					q++;
					continue;
				}
		}
		q++;//指针下移(指向输入符号串中的下一字符)
	}
}
五、实验结果(运行截屏)

六、实验总结

(1)重点与难点
画出DFA图,并进行分析

(2)存在的不足
没有将case中的switch封装,导致主函数语句太多

(3)未来改进方案
封装switch语句
封装case space的输出语句

(4)结论(开发体验、收获、感想等)
本次实验之前,对教材上DFA相关理论知识进行了复习,并在实验中通过实践,进一步巩固了所学知识。通过本次实验,我巩固复习了if-else switch-case语句的逻辑结构,初步学会了如何通过c语言编写一个基础的词法识别程序,还学会了先创建代码的主体框架,再对每部分细节进行填充的程序编写方法。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1004537.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号