编译原理--词法分析C++

一、实验项目要求

1.实验目的

通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。

编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。并依次输出各个单词的内部编码及单词符号自身值。(遇到错误时可显示"Error",然后跳过错误部分继续显示)

2.实验要求

识别保留字:if、int、for、while、do、return、break、continue,等C语言的保留字;单词种别码为1。

其他的都识别为标识符;单词种别码为2。

常数为无符号整形数;单词种别码为3。

运算符包括:+、-、*、/、=、>、<、>=、<=、!= ;单词种别码为4。

分隔符包括:,、;、{、}、(、)、[、]; 单词种别码为5。

二、理论分析或算法分析

在词法分析中,自文件头开始扫描源程序字符,一旦发现符合"单词"定义的源程序字符串时,将它翻译成固定长度的单词内部表示,并查填适当的信息表。经过词法分析后,源程序字符串(源程序的外部表示)被翻译成具有等长信息的单词串(源程序的内部表示),并产生两个表格:常数表和标识符表,它们分别包含了源程序中的所有常数和所有标识符。

0.定义部分:定义常量、变量、数据结构。

1.初始化:从文件将源程序全部输入到字符缓冲区中。

2.取单词前:去掉多余空白。

3.取单词:利用实验一的成果读出单词的每一个字符,组成单词,分析类型。(关键是如何判断取单词结束?取到的单词是什么类型的单词?)

4.显示结果。

三.实现方法

程序流程图如图所示:

四.实验结果分析

实验结果图

遇到的问题

(1)当第一次将代码写进去之后,出现如图所示的错误。

(2)一直找不到example.txt文件,一直出现那个error;

解决办法

(1)将Test1的属性下的C/C++下面的语言的符合模式改为"否"即可。

(2)在目录下导入并且在自建目录下导入,就可以解决这个问题。

在这次实验中,对之前学到的词法分析有了进一步的了解,加深了对于词法分析的步骤的理解与领悟,对于今后对编译原理的学习有很大的帮助。,刚开始把已有代码导入的时候,各种错误,然后就在网上一个一个搜索直到解决问题,在同学的帮助下,顺利的把代码问题搞对。

五、代码

cpp 复制代码
#include <stdio.h>
#include <ctype.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
#define NULL 0
#pragma warning(disable:4996)

FILE *fp;
char cbuffer;
char *key[32] = { "if","else","for","break","continue","int","float","double","auto","case","char","const","default","do","enum","long","extern","goto","register","return","short","signed","sizeof","static","struct","switch","typedef","union","unsigned","void","volatile","while" };
char *border[8] = { ",",";","{","}","(",")","[","]" };
char *arithmetic[4] = { "+","-","*","/" };
char *relation[6] = { "<","<=","=",">",">=","<>" };
char *consts[20];
char *label[20];
int constnum = 0, labelnum = 0;
int search(char searchchar[], int wordtype)
{
	int i = 0;
	switch (wordtype)
	{
	case 1:for (i = 0; i <= 31; i++)
	{
		if (strcmp(key[i], searchchar) == 0)
			return(i + 1);
	}
		   return 0;
	case 2:
	{
		for (i = 0; i <= 7; i++)
		{
			if (strcmp(border[i], searchchar) == 0)
				return(i + 1);
		}
		return(0);
	}

	case 3:
	{
		for (i = 0; i <= 3; i++)
		{
			if (strcmp(arithmetic[i], searchchar) == 0)
			{
				return(i + 1);
			}
		}
		return(0);
	}
	case 4:
	{
		for (i = 0; i <= 5; i++)
			if (strcmp(relation[i], searchchar) == 0)
				return(i + 1);
		return(0);
	}
	case 5:
	{
		for (i = 0; i <= constnum; i++)
		{
			if (consts[i] && (strcmp(consts[i], searchchar) == 0))
				return(i + 1);
		}
		consts[i - 1] = (char *)malloc(sizeof(searchchar));
		strcpy(consts[i - 1], searchchar);
		constnum++;
		return(i);
	}
	case 6:
	{
		for (i = 0; i <= labelnum; i++)
			if (label[i] && (strcmp(label[i], searchchar) == 0))
				return(i + 1);
		label[i - 1] = (char *)malloc(sizeof(searchchar));
		strcpy(label[i - 1], searchchar);
		labelnum++;
		return(i);
	}
	default: return 0;
	}
}
char alphaprocess(char buffer)
{
	//	int atype;
	int i = -1;
	char alphatp[20];
	while ((isalpha(buffer)) || (isdigit(buffer)))
	{
		alphatp[++i] = buffer;
		buffer = fgetc(fp);
	}
	alphatp[i + 1] = '\0';
	if (/*atype=*/search(alphatp, 1))
		//		printf("%s (1,%d)\n",alphatp,atype-1);
		printf("(1,  \"%s\")\n", alphatp);
	else
	{
		search(alphatp, 6);
		//		printf("%s (6,%d)\n",alphatp,atype-1);
		printf("(2,  \"%s\")\n", alphatp);
	}
	return(buffer);
}

char digitprocess(char buffer)
{
	int i = -1;
	char digittp[20];
	//	int dtype;
	while ((isdigit(buffer)))
	{
		digittp[++i] = buffer;
		buffer = fgetc(fp);
	}
	digittp[i + 1] = '\0';
	search(digittp, 5);
	//	printf("%s (5,%d)\n",digittp,dtype-1);
	printf("(3,  \"%s\")\n", digittp);
	return(buffer);
}

char otherprocess(char buffer)
{
	int i = -1;
	char othertp[20];
	//	int otype,otypetp;
	othertp[0] = buffer;
	othertp[1] = '\0';
	if (/*otype=*/search(othertp, 3))
	{
		//		printf("%s (3,%d)\n",othertp,otype-1);
		printf("(4,  \"%s\")\n", othertp);
		buffer = fgetc(fp);
		goto out;
	}
	if (/*otype=*/search(othertp, 4))
	{
		buffer = fgetc(fp);
		othertp[1] = buffer;
		othertp[2] = '\0';
		if (/*otypetp=*/search(othertp, 4))
		{
			//		printf("%s (4,%d)\n",othertp,otypetp-1);
			printf("(4,  \"%s\")\n", othertp);
			goto out;
		}
		else
			othertp[1] = '\0';
		//		printf("%s (4,%d)\n",othertp,otype-1);
		printf("(4,  \"%s\")\n", othertp);
		goto out;
	}
	if (buffer == ':')
	{
		buffer = fgetc(fp);
		if (buffer == '=')
			printf(":= (2,2)\n");
		buffer = fgetc(fp);
		goto out;
	}
	else
	{
		if (/*otype=*/search(othertp, 2))
		{
			//			 printf("%s (2,%d)\n",othertp,otype-1);
			printf("(5,  \"%s\")\n", othertp);
			buffer = fgetc(fp);
			goto out;
		}
	}
	if ((buffer != '\n') && (buffer != ' '))
		printf("%c error,not a word\n", buffer);
	buffer = fgetc(fp);


out:      return(buffer);
}

void main()
{
	int i;

	for (i = 0; i <= 20; i++)
	{
		label[i] = NULL;
		consts[i] = NULL;
	}
	if ((fp = fopen("example.txt", "r")) == NULL)
		printf("error");
	else
	{
		cbuffer = fgetc(fp);
		while (cbuffer != EOF)
		{
			if (isalpha(cbuffer))
				cbuffer = alphaprocess(cbuffer);
			else if (isdigit(cbuffer))
				cbuffer = digitprocess(cbuffer);
			else cbuffer = otherprocess(cbuffer);
		}
		printf("over\n");
		getchar();
	}
}

example.txt

#inlclude<stdio.h>

int main()

{

int b, a, c;

a = 10;

c=a+b;

printf("%d%d",a,b);;

return 0;

}

相关推荐
暮色_年华2 分钟前
Modern Effective C++item 9:优先考虑别名声明而非typedef
c++
重生之我是数学王子10 分钟前
QT基础 编码问题 定时器 事件 绘图事件 keyPressEvent QT5.12.3环境 C++实现
开发语言·c++·qt
我们的五年34 分钟前
【Linux课程学习】:进程程序替换,execl,execv,execlp,execvp,execve,execle,execvpe函数
linux·c++·学习
做人不要太理性1 小时前
【C++】深入哈希表核心:从改造到封装,解锁 unordered_set 与 unordered_map 的终极奥义!
c++·哈希算法·散列表·unordered_map·unordered_set
程序员-King.1 小时前
2、桥接模式
c++·桥接模式
chnming19871 小时前
STL关联式容器之map
开发语言·c++
程序伍六七1 小时前
day16
开发语言·c++
小陈phd2 小时前
Vscode LinuxC++环境配置
linux·c++·vscode
火山口车神丶2 小时前
某车企ASW面试笔试题
c++·matlab
是阿建吖!2 小时前
【优选算法】二分查找
c++·算法