编译原理实验——词法分析程序

编译原理实验——词法分析程序

1、程序功能介绍

此程序主要功能是将字符串类型的源码转换为****这样的二元组,以便后续的编译步骤能够更轻松地理解和处理源代码的结构和语法。

输入:

编译原理实验——词法分析程序_第1张图片

输出:
编译原理实验——词法分析程序_第2张图片

2、主要数据结构

1、使用string对象存放保留字并使用数组存放对应的id值

vector reserve = { "void","int","float","double","if","else","for","do","while" };
const int num_reserve[] = { 2,3,4,5,6,7,8,9,10 };

2、使用string类对象管理字符串,便于向文件中打印

string temp("");
temp += ch;
fprintf(fp, "<%d,%s>", 11, temp.c_str());

3、程序主要内容以及调用关系

1、函数内容介绍

函数名称 主要功能
int main(); 负责实际的词法分析工作,将源代码中的不同部分分类并输出到文件以供后续的语法分析或其他处理使用。
int is_reserve(string& temp); 用于判断给定的字符串 temp 是否是保留字(关键字)。它会在预定义的保留字列表中查找 temp,如果找到匹配项,则返回相应的类别编码;否则返回0。
int is_letter(char& ch); 用于判断一个字符 ch 是否是字母。如果字符是字母,它返回1,否则返回0。
int is_number(char ch); 用于判断一个字符 ch 是否是数字。如果字符是数字,它返回1,否则返回0。
int is_single_delimiter(char& ch); 用于判断一个字符 ch 是否是单字符分界符。如果字符是单字符分界符,它返回1,否则返回0。

2、函数调用关系:main 函数内部调用函数来帮助判断字符的类型:

  • is_reserve 用于判断是否是关键字。

  • is_letter 用于判断是否是字母。

  • is_number 用于判断是否是数字。

  • is_single_delimiter 用于判断是否是单字符分界符。

程序的实现方法

该程序主要根据文法来写出程序,main函数通过从文件中不断的读出字符,进行类别的判断,最后输出二元组到文件中

改编后的文法如下:

<单词符号>→<标识符>|<无符号整数>|<单字符分界符>|<双字符分界符>

<标识符>→字母|<标识符>字母|<标识符>d

<无符号整数>→数字︱ <无符号整数>数字

<单字符分界符>→+ ︱- ︱* ︱;︱, ︱(︱) ︱{︱}|/|!|>|<|=|&

<双字符分界符>→<大于>=︱<小于>=︱<感叹号>=︱<等于>=︱<斜竖>* |<加号>+|<减号>-|

<大于> >|<小于><|<加号>=|<减号>=|<乘号>=|<斜竖>=|<与>&|<竖线>| |

<小于>→<

<等于>→=

<大于>→>

<斜竖> →/

<感叹号>→!

<加号>→+

<减号>→-

<乘号>→*

<与>→&

<竖线>→|

每类字符的类别编码如下:

单词符号 类别编码
标识符 1
void 2
int 3
float 4
double 5
if 6
else 7
for 8
do 9
while 10
无符号数 11
单字符分界符 12
双字节分界符 13

4、测试用例

输入:
编译原理实验——词法分析程序_第3张图片
输出:
编译原理实验——词法分析程序_第4张图片

5、源代码如下

#define _CRT_SECURE_NO_WARNINGS 1
#include 
#include 
#include 
#include 
using namespace std;
vector<string> reserve = { "void","int","float","double","if","else","for","do","while" };
const int num_reserve[] = { 2,3,4,5,6,7,8,9,10 };
//判断是否是保留字 如果是的话返回对应的类别编码,否则返回0
int is_reserve(string& temp)
{
	for (int i = 0; i < reserve.size(); i++)
	{
		if (reserve[i] == temp)
		{
			return num_reserve[i];
		}
	}
	return 0;
}
//是字母返回值为1 否则返回值为0
int is_letter(char& ch)
{
	if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
	{
		return 1;
	}
	return 0;
}
//如果是数字返回1 否则返回0
int is_number(char ch)
{
	if (ch >= '0' && ch <= '9')
	{
		return 1;
	}
	return 0;
}
//判断是否是单字符分界符,如果是返回1,否则返回0
int is_single_delimiter(char& ch)
{
	switch (ch)
	{
	case ';':
		return 1;
	case ',':
		return 1;
	case '(':
		return 1;
	case ')':
		return 1;
	case '{':
		return 1;
	case '}':
		return 1;
	case '[':
		return 1;
	case ']':
		return 1;
	default:
		return 0;
	}
}
int main()
{
	char ch;
	FILE* ptr = fopen("input.txt", "r");
	if (!ptr)
	{
		perror("input文件打开失败");
		return -1;
	}
	FILE* fp = fopen("output.txt", "a+");
	if (!fp)
	{
		perror("output文件打开失败");
		return -1;
	}
	ch = fgetc(ptr);
	while (ch != EOF)
	{
		if (ch == ' ' || ch == '\t')
		{
			ch = fgetc(ptr);
			continue;
		}
		else if (ch == '\n')
		{
			fprintf(fp, "%c", ch);
			ch = fgetc(ptr);
			
		}
		else if (is_letter(ch))
		{
			string temp("");
			temp += ch;
			ch = fgetc(ptr);
			while (is_letter(ch) || is_number(ch))
			{
				temp += ch;
				ch = fgetc(ptr);
			}
			//fseek(ptr, -1, SEEK_CUR);
			int id = is_reserve(temp);
			if (id != 0)
			{
				fprintf(fp, "<%d,%s>", id, temp.c_str());
			}
			else
			{
				fprintf(fp, "<%d,%s>", 1, temp.c_str());
			}

		}
		else if (is_number(ch))
		{
			string temp("");
			temp += ch;
			ch = fgetc(ptr);
			while (is_number(ch))
			{
				temp += ch;
				ch = fgetc(ptr);
			}
			fprintf(fp, "<%d,%s>", 11, temp.c_str());
		}
		else if (is_single_delimiter(ch))
		{
			fprintf(fp, "<12,%c>", ch);
			ch = fgetc(ptr);
		}
		else if (ch == '<')
		{
			string temp("");
			temp += ch;
			ch = fgetc(ptr);
			if (ch == '<')
			{
				temp += ch;
				fprintf(fp, "<13,%s>", temp.c_str());
				ch = fgetc(ptr);

			}
			else if (ch == '=')
			{
				temp += ch;
				fprintf(fp, "<13,%s>", temp.c_str());
				ch = fgetc(ptr);
			}
			else
			{
				fprintf(fp, "<13,%s>", temp.c_str());
			}
		}
		else if (ch == '=')
		{
			string temp("");
			temp += ch;
			ch = fgetc(ptr);
			if (ch == '=')
			{
				temp += ch;
				fprintf(fp, "<13,%s>", temp.c_str());
				ch = fgetc(ptr);
			}
			else
			{
				fprintf(fp, "<13,%s>", temp.c_str());
			}
		}
		else if (ch == '>')
		{
			string temp("");
			temp += ch;
			ch = fgetc(ptr);
			if (ch == '>')
			{
				temp += ch;
				fprintf(fp, "<13,%s>", temp.c_str());
				ch = fgetc(ptr);

			}
			else if (ch == '=')
			{
				temp += ch;
				fprintf(fp, "<13,%s>", temp.c_str());
				ch = fgetc(ptr);
			}
			else
			{
				fprintf(fp, "<13,%s>", temp.c_str());
			}
		}
		else if (ch == '/')
		{
			string temp("");
			temp += ch;
			ch = fgetc(ptr);
			if (ch == '*')
			{
				fprintf(fp, "注释处理开始");
				ch = fgetc(ptr);
				while (ch != EOF)
				{
					if (ch == '*')
					{
						ch = fgetc(ptr);
						if (ch == '/')
						{
							break;
						}
						else
						{
							continue;
						}
					}
					ch = fgetc(ptr);
				}
				if (ch == '/')
				{
					fprintf(fp, "注释处理完成");
					ch = fgetc(ptr);
				}
			}
			else if (ch == '=')
			{
				temp += ch;
				fprintf(fp, "<13,%s>", temp.c_str());
				ch = fgetc(ptr);
			}
			else
			{
				fprintf(fp, "<12,%s>", temp.c_str());
			}
		}
		else if (ch == '!')
		{
			string temp("");
			temp += ch;
			ch = fgetc(ptr);
			if (ch == '=')
			{
				temp += ch;
				fprintf(fp, "<13,%s>", temp.c_str());
				ch = fgetc(ptr);
			}
			else
			{
				fprintf(fp, "<12,%s>", temp.c_str());
			}
		}
		else if (ch == '+')
		{
			string temp("");
			temp += ch;
			ch = fgetc(ptr);
			if (ch == '=')
			{
				temp += ch;
				fprintf(fp, "<13,%s>", temp.c_str());
				ch = fgetc(ptr);
			}
			else if (ch == '+')
			{
				temp += ch;
				fprintf(fp, "<13,%s>", temp.c_str());
				ch = fgetc(ptr);
			}
			else
			{
				fprintf(fp, "<12,%s>", temp.c_str());
			}
		}
		else if (ch == '-')
		{
			string temp("");
			temp += ch;
			ch = fgetc(ptr);
			if (ch == '=')
			{
				temp += ch;
				fprintf(fp, "<13,%s>", temp.c_str());
				ch = fgetc(ptr);
			}
			else if (ch == '-')
			{
				temp += ch;
				fprintf(fp, "<13,%s>", temp.c_str());
				ch = fgetc(ptr);
			}
			else
			{
				fprintf(fp, "<12,%s>", temp.c_str());
			}
		}
		else if (ch == '*')
		{
			string temp("");
			temp += ch;
			ch = fgetc(ptr);
			if (ch == '=')
			{
				temp += ch;
				fprintf(fp, "<13,%s>", temp.c_str());
				ch = fgetc(ptr);
			}
			else
			{
				fprintf(fp, "<12,%s>", temp.c_str());
			}
		}
		else if (ch == '&')
		{
			string temp("");
			temp += ch;
			ch = fgetc(ptr);
			if (ch == '&')
			{
				temp += ch;
				fprintf(fp, "<13,%s>", temp.c_str());
				ch = fgetc(ptr);
			}
			else
			{
				fprintf(fp, "<12,%s>", temp.c_str());
			}
		}
		else if (ch == '|')
		{
			string temp("");
			temp += ch;
			ch = fgetc(ptr);
			if (ch == '|')
			{
				temp += ch;
				fprintf(fp, "<13,%s>", temp.c_str());
				ch = fgetc(ptr);
			}
			else
			{
				fprintf(fp, "<12,%s>", temp.c_str());
			}
		}
	}
	fclose(ptr);
	fclose(fp);
	return 0;
}

你可能感兴趣的:(编译原理实验,c++)