最简单的词法分析器

1、 实验目的:

设计、编制、调试一个词法分析程序,对单词进行识别和编码,加深对词法分析原理的理解。

 

2、 实验要求

(1) 允许用户自己输入源程序并保存为文件

(2) 系统能够输出经过预处理后的源程序(去掉注释、换行、空格等)

(3) 能够将该源程序中所有的单词根据其所属类型(整数、保留字、运算符、标识符等。定义的类C语言中的标识符只能以字母或下划线开头)进行归类显示,例如:识别保留字:ifintforwhiledoreturnbreakcontinue等,其他的都识别为标识符;常数为无符号整形数;运算符包括:+-*/=><>=<=!=等;分隔符包括:,;{}()等。

实现文件的读取操作,而不是将文本以字符串形式预存于程序中。文本内容为待分析的类C语言程序。

设计并实现一个词法分析器,实现对指定位置的类C语言源程序文本文件的读取,并能够对该源程序中的所有单词进行分类,指出其所属类型,实现简单的词法分析操作。

例如下面为一段C语言源程序:

main()

{

int  a,b;

a = 10;

b = a + 20;

}

要求输出如下

(1,’main’)

(5,’(’)

(5,’)’)

(5,’{ ’)

(1,’int’)

(2,’a’)

(5,’,’)

(2,’b’)

(5,’;’)

(2,’a’)

(4,’=’)

(3,’10’)

(5,’;’)

(2,’b’)

(4,’=’)

(2,’a’)

(4,’+’)

(3,’20’)

(5,’;’)

(5,’}’)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef struct Word
{
	int num;//词所属类型
	char w[20];//词
}Word;

int main()
{
	char ch,word_temp[20]="";
	int i=0,j=0,k=0,key=0,chioce;
	char ktt[28][20]={"int","do","else","main","if","while","break","continue","for","return",
	",",";",":","(",")","[","]","{","}","+","-","*","/","=","<",">","<=",">="};
	FILE *fp;
	Word word[100];
	printf("1:输入源程序保存成文件\n");
	printf("2:打开文件进行词法分析\n");
	printf("请输入你的选择:");
	scanf("%d",&chioce);
	switch(chioce)
	{
	case 1:
		fp=fopen("F:\\编程小试\\C语言\\词法分析\\C_program.txt","w");
		if(!fp)
		{
			printf("can't open file C_program.txt\n");
			exit(1);
		}
		printf("请输入一段程序(以#结束):\n");
		ch=getchar();
		while(ch!='#')
		{
			fputc(ch,fp);
			ch=getchar();
		}
		fclose(fp);break;
	case 2:
		fp=fopen("F:\\编程小试\\C语言\\词法分析\\C_program.txt","r");
		if(!fp)
		{
			printf("can't open file C_program.txt\n");
			exit(1);
		}
		printf("源程序如下:");
		while((ch=fgetc(fp))!=EOF)
		{
			putchar(ch);
		}
		fclose(fp);
		printf("\n词法分析结果如下:\n");
		fp=fopen("F:\\编程小试\\C语言\\词法分析\\C_program.txt","r");
		if(!fp)
		{
			printf("can't open file C_program.txt\n");
			exit(1);
		}
		while((ch=fgetc(fp))!=EOF)
		{   
			if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')||(ch>='0'&&ch<='9'))
			{
				
				word_temp[key++]=ch;//连续几个字母的连成单词
				word_temp[key]='\0';
				continue;
			}
			else
			{   if(strcmp(word_temp,"")!=0)
				{
					strcpy(word[i].w,word_temp);//将单词拷贝到结构数组中
					strcpy(word_temp,"");
					key=0;//回到临时数组的开始位置
					i++;//结构数组的下标加1
					
				}
				if(ch==' '||ch==10||ch=='	')//去掉空格、回车和tab键
				{	
					continue;
				}			
				else
				{
					word_temp[0]=ch;
					word_temp[1]='\0';//字符串结束符
					strcpy(word[i].w,word_temp);//将非字母数字符号拷贝到结构数组中
					strcpy(word_temp,"");
					key=0;//回到临时数组的开始位置
					i++;
				}
			}
		}break;
	default: printf(" 输入错误!");
	}
	
	for(j=0;j<i;j++)
	{
		for(k=0;k<28;k++)
		{
			if((strcmp(word[j].w,ktt[k]))==0)
			{
				if(k>=0&&k<10)
					word[j].num=1;//保留字
				else if(k>=10&&k<19)
					word[j].num=5;//分隔符
				else if(k>=19&&k<28)
					word[j].num=4;//运算符
				else if(word[j].w[0]>='0'&&word[j].w[0]<='9')
					word[j].num=3;//数字
				break;
			}
			else 
				word[j].num=2;//变量
		}
	}
	for(j=0;j<i;j++)//按格式要求打印输出
	{
		printf("(%d,'%s')\n",word[j].num,word[j].w);
	}


	fclose(fp);
	return 0;
}


评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值