【编译原理】- 词法分析器的实现

本文详细描述了一种设计有限状态自动机(DFA)的过程,用于识别符合特定语言规则的标识符、十进制和十六进制整数。通过分析给定的语言规范,创建了相应的正规式,并转化为最小化的DFA,进而实现了词法分析程序。实例演示了如何处理输入字符串,输出合规与不合规的部分。
摘要由CSDN通过智能技术生成

目录

一、题目

二、分析与设计

三、源代码


一、题目

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

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

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

例:

若输入:"  Ae35 6638 5392H A10 83A2Eh 65Ha 3G2H 80 "

则输出:

Ae35是一个标识符(Identifier)

6638是一个十进制整数(DecimalInteger)

5392H是一个十六进制数(HexDigit)

A10是一个标识符(Identifier)

83A2Eh是一个十六进制数(HexDigit)

65Ha非法输入(InvalidInput)

3G2H非法输入(InvalidInput)

80是一个十进制整数(DecimalInteger)

二、分析与设计

(1)   分析与设计  

    a)根据给定的语言求出其正规式(或文法)

G[S]:

                        S->lA | dB

                        A-> lA | dA | ε

                        B-> hC | dB |  (a,f)D

                        C->ε

                      D-> dD | (a,f)D | hC

    c)   给出最小化的DFA

(2)   编程

    a)     根据最小化的DFA绘制程序流程图(核心部分)

    b)     编写词法分析程序

(3)   系统调试

三、源代码

#include "stdio.h"
#include "string.h"
#include "conio.h"

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

//测试的输入字符串
char words[100] = "   Ae35 6638 5392H A10 83A2Eh 65Ha 3G2H 80  ";
char* q;//指向输入符号串中当前的字符
char word[20];//存储当前识别的单词
int state = 0;//表示所处的状态,初始状态为0
int i;//单词的下标

int isDigitOrChar(char ch) {
	if (ch >= 48 && ch <= 57)   //数字
		return digit;
	else if (ch == 32)
		return space;           //空格
	else if (ch == 72 || ch == 104)
		return Hh;              //Hh
	else if ((ch >= 65 && ch <= 70) || (ch >= 97 && ch <= 102))//ABCDEF或者abcdef
		return AF;
	else if ((ch >= 65 && ch <= 90) || (ch >= 97 && ch <= 122))//除A-F外的其他字母
		return letter;
}

int main() {
	printf("%s \n", words);
	q = words;
	while (*q) {
		switch (state) {
		case 0:   //当前为0状态
			switch (isDigitOrChar(*q)) {
			case digit://数字
				word[i++] = *q;
				state = 2;
				break;
			case Hh:           //Hh
			case AF:           //ABCDEF或者abcdef
			case letter:       //除A-F外的其他字母
				word[i++] = *q;
				state = 1;
				break;
			case space:        //空格
				state = 0;
				memset(word, 0, sizeof(word));
				i = 0;
				break;
			default:           //其他字符(非法)
				word[i++] = *q;
				state = 5;     //转到出错状态
				break;
			}
			break;
		case 1:   //当前为1状态
			switch (isDigitOrChar(*q)) {
			case digit://数字
				word[i++] = *q;
				state = 1;
				break;
			case Hh:           //Hh
			case AF:           //ABCDEF或者abcdef
			case letter:       //除A-F外的其他字母
				word[i++] = *q;
				state = 1;
				break;
			case space:        //空格,1状态可以为标识符的结束状态
				word[i++] = *q;
				state = 0;
				for (int m = 0;m < sizeof(word);m++) {
					printf("%c", word[m]);
				}
				memset(word, 0, sizeof(word));
				i = 0;
				printf("是一个标识符(Identifier)\n");
				break;
			default:           //其他字符(非法)
				word[i++] = *q;
				state = 5;     //转到出错状态
				break;
			}
			break;
		case 2:   //当前为2状态
			switch (isDigitOrChar(*q)) {
			case digit://数字
				word[i++] = *q;
				state = 2;
				break;
			case Hh:           //Hh
				word[i++] = *q;
				state = 3;
				break;
			case AF:           //ABCDEF或者abcdef
				word[i++] = *q;
				state = 4;
				break;
			case space:        //空格,2状态可以为十进制整数的结束状态
				word[i++] = *q;
				state = 0;
				for (int m = 0;m < sizeof(word);m++) {
					printf("%c", word[m]);
				}
				memset(word, 0, sizeof(word));
				i = 0;
				printf("是一个十进制整数(DecimalInteger)\n");
				break;
			default:           //其他字符(非法)
				word[i++] = *q;
				state = 5;     //转到出错状态
				break;
			}
			break;
		case 3:   //当前为3状态
			switch (isDigitOrChar(*q)) {
			case space:        //空格,3状态可以为十六进制整数的结束状态
				word[i++] = *q;
				state = 0;
				for (int m = 0;m < sizeof(word);m++) {
					printf("%c", word[m]);
				}
				memset(word, 0, sizeof(word));
				i = 0;
				printf("是一个十六进制数(HexDigit)\n");
				break;
			default:           //其他字符(非法)
				word[i++] = *q;
				state = 5;
				break;
			}
			break;
		case 4:   //当前为4状态
			switch (isDigitOrChar(*q)) {
			case digit://数字
				word[i++] = *q;
				state = 4;
				break;
			case Hh:           //Hh
				word[i++] = *q;
				state = 3;
				break;
			case AF:           //ABCDEF或者abcdef
				word[i++] = *q;
				state = 4;
				break;
			case space:        //空格
				word[i++] = *q;
				state = 0;
				memset(word, 0, sizeof(word));
				i = 0;
				break;
			default:           //其他字符(非法)
				word[i++] = *q;
				state = 5;     //转到出错状态
				break;
			}
			break;
		case 5:   //出错状态
			switch (isDigitOrChar(*q)) {
			case space:        //空格
				word[i++] = *q;
				state = 0;
				for (int m = 0;m < sizeof(word);m++) {
					printf("%c", word[m]);
				}
				memset(word, 0, sizeof(word));
				i = 0;
				printf("非法输入\n");
				break;
			default:           //其他字符(非法)
				word[i++] = *q;
				state = 5;     //转到出错状态
				break;
			}
			break;
		}
		q++;     //指针下移(指向输入符号串的下一个字符)
	}
	printf("》》》分析结束《《《\n\n\n");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值