基于C语言的词法分析器

一.实验题目

设计基于C语言的词法分析器

二.实验目的

通过设计编制调试 C 语言的词法分析程序,加
深对词法分析原理的理解。并掌握在对程序设计语言源程
序进行扫描过程中将其分解为各类单词的词法分析方法。
编制一个读单词过程,从输入的源程序中,识别出各个具
有独立意义的单词,即基本字、标识符、常数、运算符、
分隔符五大类。并依次输出各个单词的内部编码及单词符
号自身值.

三:程序代码


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <string>
#include <iostream>
//#include<iostream.h>
using namespace std;
string keywords[20] = { "include","void","main","int",
					"char","float","double","if",
					"else","then","break","continue",
					"for","do","while","printf","scanf",
					"begin","end","return" };
char rz[99999] = " ";
string id[10000];
int pp = 0;
string nu[10000];
int qq = 0;
int isLetter(char a) //判断是否是字母
{
	if ((a >= 'a' && a <= 'z')||(a >= 'A'&& a <= 'Z')) {
		return 1;
	}
	return 0;
}
int isDigit(char a) //判断是否是数字
{
	if (a <= '9' && a >= '0') {
		return 1;
	}
	return 0;
}
int alpha(int st) //识别保留字和标识符,给此函数的的语句加上注释
{
	char wordbuf[20] = " ";//定义一个数组wordbuf,用来接收rz中的字符
	int n = 0;//用n来记录wordbuf的数组下标
	for (;;)//用for循环,循环下列语句
	{
		wordbuf[n] = rz[st];//将rz数组中的元素录入wordbuf中
		st++;//数组下标进行移动
		n++;//数组下标进行移动
		if ((isDigit(rz[st]) == 1) || (isLetter(rz[st]) == 1) || (rz[st] == '_'))
//判断是字母,数字还是_
			wordbuf[n] = rz[st];//将数字,字母或'_'录入wordbuf中
		else
			break;//否则跳出循环
	}
	int flag = 0;//定义一个flag变量
	for (int k = 0; k < 20; k++)//循环下列语句
	{
		if (strcmp(keywords[k].c_str(), wordbuf) == 0)//判断是否为关键字
			flag = 1;//若是关键字flag被赋为1
	}
	if (flag == 0)//判断flag是否为0,等于0执行下列语句
	{
		int flagg = -1;//定义变量flagg,并赋值为-1
		for (int t = 0; t < pp; t++)//循环下列语句
		{
			if (strcmp(id[t].c_str(), wordbuf) == 0)//判断字母是否相等
			{
				flagg = t;//相等的话把t赋给flagg
			}
		}
		if (flagg != -1)//判断flagg的值是否不等于-1
			printf(" (id,%d) ", flagg);//若不等于-1打印flagg的值
		Else//flagg == -1
		{
			id[pp] = wordbuf;//将wordbuf数组元素赋给id数组
			printf(" (id,%d) ", pp);//打印pp当前的值
			pp++;//pp自增
		}
	}
	Else//flag不等于0
	{
		printf(" (");//打印 (
		for (int i = 0; i < n; i++)//循环打印wordbuf数组中的字符
		{
			printf("%c", wordbuf[i]);
		}
		printf(",-) ");//循环结束打印 -)
	}
		return st;//返回st当前的值
}
int number(int st) //识别整数
{
	char numbuf[20] = " ";
	int n = 0;
	int k = 0;
	int flag = 0;
	for (;;)
	{
		numbuf[n] = rz[st];
		st++;
		n++;
		if (isDigit(rz[st]) == 1)
		{
			numbuf[n] = rz[st];
		}
		else if ((k == 0) && (rz[st] == '.'))
		{
			numbuf[n] = rz[st];
			k++;
		}
		else if (isLetter(rz[st]) == 1)
		{
			numbuf[n] = rz[st];
			flag = 1;
			continue;
		}
		else
			break;
	}
	if (flag == 0)
	{
		int flagg = -1;
		for (int t = 0; t < qq; t++)
			if (strcmp(nu[t].c_str(), numbuf) == 0)
				flagg = t;
		if (flagg != -1)
			printf(" (nu,%d) ", flagg);
		else
		{
			nu[qq] = numbuf;
			printf(" (nu,%d) ", qq);
			qq++;
		}
	}
	else {
		printf(" (");
		for (int i = 0; i < n; i++)
			printf("%c", numbuf[i]);
		printf(",error digital!) ");
	}
	return st;
}
int anotation(int st) //处理除号/和注释,给此函数的语句加上注释
{
	char tabuf[9999] = " ";//定义一个tabuf数组
	int n = 0;
	st++;
	if (rz[st] == '/')//判断rz数组中st下标对应的元素是否为 / ,是执行下列语句
	{
		printf(" (//,-)");//打印注释符号 '//'
		st++;//st自增
		while (rz[st] != 10)//循环直到rz数组中st下标对应的元素为10为止
		{
			tabuf[n] = rz[st];//将rz数组中st下标对应的元素赋给tabuf
			st++;//st自增
			n++;//n自增
		}
		printf(" \n 注释");//换行打印"注释"
		for (int i = 0; i < n; i++)//循环打印出注释的句子
			printf("%c", tabuf[i]);
	}
	else if (rz[st] == '*')//否则判断rz数组中st下标对应的元素是否为 * ,是执行下列语句
	{
		printf(" (/*,-) ");//打印注释符号 '/*'
		st++;//st自增
		int stt = st + 1;//定义变量stt,把st + 1赋给stt
		while (1)//循环
		{
			if (rz[st] == '*' && rz[st + 1] == '/')//判断当前是否为注释结束符,是执行语句
				break;//跳出循环
			tabuf[n] = rz[st];//将rz数组中st下标对应的元素赋给tabuf
			st++;//st自增
			n++;//n自增
			if (rz[st + 1] == '\0')//判断rz数组中st + 1下标对应的元素是否为'\n',是执行语句
			{
				printf("(/* error!!\n)");//打印错误
				return st + 1;//返回 st + 1
			}
		}
		printf(" \n 注释");//换行打印"注释"
		for (int i = 0; i < n; i++)//循环打印注释内容
			printf("%c", tabuf[i]);
		printf(" (*/,-) ");//打印注释结束符
		st = st + 2;//st + 2
	}
	else if (rz[st] == '=')//否则判断rz数组中st下标对应的元素是否为 = ,是执行下列语句
	{
		st++;//st自增
		printf(" (/*,-) ");//打印注释开始符号
	}
	else printf(" (/,-) ");//否则为除号并打印
	return st;//返回st
}
int other(int st) //函数识别其他特殊字符
{
	switch (rz[st])
	{
	case'=':
		st++;
		if (rz[st] == '=')
		{
			st++;
			printf(" (rlop,==) ");
		}
		else
			printf(" (rlop,=) ");
		break;
	case'+':
		st++;
		if (rz[st] == '=')
		{
			st++;
			printf(" (+=,-) ");
		}
		else if (rz[st] == '+')
		{
			st++;
			printf(" (++,-) ");
		}
		else printf(" (+,-) ");
		break;
	case'-':
		st++;
		if (rz[st] == '=')
		{
			st++;
			printf(" (-=,-) ");
		}
		else if (rz[st] == '-')
		{
			st++;
			printf(" (--,-) ");
		}
		else
			printf(" (-,-) ");
		break;
	case'*':
		st++;
		if (rz[st] == '=')
		{
			st++;
			printf(" (*=,-) ");
		}
		else
			printf(" (*,-) ");
		break;
	case'>':
		st++;
		if (rz[st] == '=')
		{
			st++;
			printf(" (rlop,>=) ");
		}
		else printf(" (rlop,>) ");
		break;
	case'<':
		st++;
		if (rz[st] == '=')
		{
			st++;
			printf(" (rlop,<=) ");
		}
		else
			printf(" (rlop,<) ");
	break;
	case'%':
		st++;
		if (rz[st] == '=')
		{
			st++;
			printf(" (\%=,-) ");
		}
		else
			printf(" (\%,-) ");
		break;
	case'!':
		st++;
		if (rz[st] == '=')
		{
			st++;
			printf(" (!=,-) ");
		}
		else
			printf(" (!,wrong thing!) ");
		break;
	case'&':
		st++;
		if (rz[st] == '&')
		{
			st++;
			printf(" (&&,-) ");
		}
		else printf(" (&,worng word!) ");
		break;
	case'|':
		st++;
		if (rz[st] == '|')
		{
			st++;
			printf(" (||,-) ");
		}
		else
			printf(" ( |,worng word ! ) ");
		break;
		case'{':
		st++;
		printf(" ({,-) ");
		break;
	case'}':
		st++;
		printf(" (},-) ");
		break;
	case'(':
		st++;
		printf(" ((,-) ");
		break;
	case')':
		st++;
		printf(" (),-) ");
		break;
	case'[':
		st++;
		printf(" ([,-) ");
		break;
	case']':
		st++;
		printf(" (],-) ");
		break;
	case':':
		st++;
		printf(" (:,-) ");
		break;
	case'#':st++;
		printf(" (#,-) ");
		break;
	case';':
		st++;
		printf(" (;,-) ");
		break;
	case'.':
		st++;
		printf(" (.,-) ");
		break;
	case',':
		st++;
		printf(" (,,-) ");
		break;
	case' ':
		st++;
		break;
	case '  ':
		st++;
		break;
	case 10:
		st++;
		printf("\n");
		break;
	case 34:
		st++;
		printf(" (\",-) ");
		break;
	case 39:
		st++;
		printf(" (',-) ");
		break;
	default:
		printf(" (%c,worngthing) ", rz[st]);
		st++;
	}
	return st;
}
int choice(int st) //根据读入的单词的第一个字符确定调用不同的单词识别函数
{
	if (isLetter(rz[st]) == 1)
		st = alpha(st);
	else if (isDigit(rz[st]) == 1)
		st = number(st);
	else if (rz[st] == '/')
		st = anotation(st);
	else
		st = other(st);
	return st;
}
int main()
{
	int i = 0;
	FILE* fp;
	char name[10];
	printf("请输入文件名:\n");
	scanf("%s", &name);
	if ((fp = fopen(name, "r")) == NULL)
	{
		printf("Open error!");
		exit(0);
	}
	char ch = fgetc(fp);
int main()
{
	int i = 0;
	FILE* fp;
	char name[10];
	printf("请输入文件名:\n");
	scanf("%s", &name);
	if ((fp = fopen(name, "r")) == NULL)
	{
		printf("Open error!");
		exit(0);
	}
	char ch = fgetc(fp);
while (ch != EOF)
	{
		rz[i] = ch;
		i++;
		ch = fgetc(fp);
	}
	fclose(fp);
	int j = 0;
	while (rz[j] != '\0')
		j = choice(j);
	cout << endl << " 程序中标示符如下 " << endl;
	for (i = 0; i < pp; i++)
		cout << i << " " << id[i] << endl;
	cout << " 程序中数字如下" << endl;
	for (j = 0; j < qq; j++)
		cout << j << " " << nu[j] << endl;
	system("pause");
}



四:运行结果及分析

在这里插入图片描述

五.实验心得

在词法分析器实验过程中,不仅仅提高了我的编程技能,而且也加深了我对编译原理的理解,通过这次实验,我更加坚信,只有通过实践才能真正掌握知识,将理论与实践相结合.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十一.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值