编译原理实验2 标识符的识别

【输入】字符串。
【输出】单词符号流,一行一个单词。
【题目】设计一个程序,从任意字符串中识别出所有可视为C语言“名字”的子串。注意:

  1. 构词规则:以字母打头,后跟任意多个字母、数字的单词;长度不超过15;不区分大小写;
    把下划线视为第27个字母。
  2. 关键字保留,即:语言定义中保留了某些单词用作关键字,程序员不可以将这些单词用作“名
    字“(变量名、常量名、函数名、标号名等等)。
#include <iostream>
#include <string.h>
using namespace std;

// 全局变量,关键字表
static char keyword[32][10] = {
	"auto", "break", "case", "char", "const", "continue", "default", "do", "double", "else", "enum", "extern",
	"float", "for", "goto", "if", "int", "long", "register", "return", "short", "signed", "sizeof", "static",
	"struct", "switch", "typedef", "union", "unsigned", "void", "volatile", "while"
};
static  char identifier[1000][50] = { "" };//标识符表

										   // 判断是否为关键字
int IsKeyword(char s[], char keyword[][10])
{
	for (int i = 0; i < 32; i++)
	{
		if (strcmp(s, keyword[i]) == 0)
			return 1;	// 关键字
	}
	return 0;		// 标识符
}

// 判断是否为字母
bool IsLetter(char ch)
{
	if (ch >= 'a'&&ch <= 'z' || ch >= 'A'&&ch <= 'Z' || ch == '_')
		return true;
	else
		return false;
}

// 判断是否为数字
bool IsDigit(char ch)
{
	if (ch >= '0' && ch <= '9')
		return true;
	else
		return false;
}

// 判断是否为标识符
void IsIdentifier(int &syn, char resourceCode[], char token[], int &p)
{
	char ch;
	int count = 0;
	ch = resourceCode[p];
	while (ch == ' ' || ch == '\n' || ch == '\t')
	{
		p++;
		ch = resourceCode[p];	// 跳过空格回车等继续读取
	}

	// 双引号里的
	while (ch == '\"')
	{
		do
		{
			p++;
			ch = resourceCode[p];
		} while (ch != '\"');
		break;
	}

	for (int i = 0; i < 15; i++)
	{
		token[i] = '\0';
	}
	if (IsLetter(resourceCode[p]))
	{
		token[count++] = resourceCode[p];	// 字符串数组
		p++;

		while (IsLetter(resourceCode[p]) || IsDigit(resourceCode[p]))
		{
			token[count++] = resourceCode[p];
			p++;
		}
		token[count] = '\0';
		syn = IsKeyword(token, keyword);
		if (syn == 0)
		{
			syn = 10;	// 是标识符
		}
		else
		{
			syn = 9;	// 是关键字
		}
		return;
	}
	else if (resourceCode[p] == '\0')
	{
		syn = 0;
		return;
	}
	else
	{
		p++;
		syn = 8;	// 其它的
		return;
	}
}// 保存了字符串


int main(void)
{
	char ch;
	FILE *fp1, *fp2;
	char resourceCode[10000];
	char token[15] = { 0 };
	int p = 0, syn = 0;	// 10.标识符 9.关键字

						// 文件操作
	if ((fp1 = fopen("input.txt", "r")) == NULL)
	{
		cout << "无法打开!" << endl;
		exit(0);
	}
	if ((fp2 = fopen("output.txt", "w")) == NULL)
	{
		cout << "无法写入!" << endl;
	}

	// 将字符存入数组并打印
	while ((ch = fgetc(fp1)) != EOF)
	{
		resourceCode[p] = ch;
		p++;
	}
	resourceCode[++p] = '\0';
	cout << "源代码为:" << endl;
	cout << resourceCode << endl;
	// 识别标识符
	p = 0;	// 指针置零
	cout << "\n标识符为:" << endl;


	IsIdentifier(syn, resourceCode, token, p);
	while (syn != 0)
	{
		if (syn == 10)
		{
			// 将标识符存入数组
			for (int i = 0; i < 1000; i++)
			{
				strcpy(identifier[i], token);
			}
			// 输出标识符
			printf("%s\n", token);
			fprintf(fp2, "%s\n", token);
		}
		IsIdentifier(syn, resourceCode, token, p);
	}
	fclose(fp2);

	system("pause");
	return 0;
}

运行结果展示
在这里插入图片描述
处理后
在这里插入图片描述

  • 3
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值