基于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");
}



四:运行结果及分析

在这里插入图片描述

五.实验心得

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

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
毕业设计基于Java的C语言词法分析器可以实现C语言程序中的词法单元进行识别、分类和分析。在设计该词法分析器时,可以利用Java语言的强大特性、丰富的类库和易于扩展的特点。 首先,我们需要定义C语言的词法规则,包括关键字、标识符、运算符、常量、分隔符等。然后,可以使用Java中的正则表达式(regex)来匹配和识别这些词法单元。通过读取C语言源代码文件,我们可以逐个字符地处理,根据不同的规则进行匹配和分类。 在词法分析器中,可以使用Java中的InputStream、FileReader等类来读取源代码文件,并使用Java中的Scanner类来逐个字符地进行分析。通过提供一个状态机(state machine)来跟踪词法分析的过程,我们可以逐个字符地进行匹配并识别词法单元。 对于不同的词法单元,可以设计相应的处理逻辑。如遇到标识符,可以使用Java的HashMap等数据结构来保存已经识别的标识符,并为每个标识符分配一个唯一的标识符编号;对于关键字,可以使用预定义好的关键字列表进行匹配;对于运算符,可以使用正则表达式进行匹配等。 最后,词法分析器应该能够输出识别出的词法单元,并可在命令行窗口或文件中保存结果。可以使用Java中的I/O流来实现这一功能。 综上所述,基于Java的C语言词法分析器可以通过利用Java语言的特性和类库来方便地实现C语言程序中的词法单元进行识别和分析。它可以通过逐个字符地匹配和分类来实现对不同类型的词法单元的识别,并可以输出结果。这个词法分析器可以作为其他编译工具的基础,如语法分析器和编译器。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

十一.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值