⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 词法分析.cpp

📁 这个是我们编译原理的实验.词法分析和语法分析.通过验收,含有实验报告,希望对大家有帮助.欢迎大家评论
💻 CPP
字号:
#include<iostream.h>
#include<fstream.h>
#include<string.h>

int m = 0;
int n = 0;
int x[50], y[50];

char * reservechar[] = {"PROGRAM", "CONST", "VAR", "INTEGER", "LONG", "PROCEDURE",
						 "IF", "THEN", "WHILE", "DO", "READ", "WRITE", "BEGIN", "END", "ODD"};
//关键字表

char id[50][10];	//符号表

char cst[50][10];	//常数表

class Scanner
{
private:
	int i, j;	//指针
	int length;
	char ch, buffer[100], strtoken[20];
public:
	Scanner(char str[], int n);//构造函数
	int isdigit();//判断是否整数
	int isletter();//首字母的判断
	int reserve();//对stroken进行关键字表的查找,返回其编码值
	int insertid();//将stroken中的标识符插入符号表,返回在符号表中的位置
	int insertconst();//将stroken中的常数插入常数表,返回在常数表中的位置
	void getchar();//将下一输入字符读 到ch中,指针后移一字符位置
	void getbc();//保证ch是一个非空白字符
	void concat();//将ch连接到字符串stroken的末尾
	void retract();//置ch为空白字符,指针前移一字符位置
	void scan();
};

Scanner::Scanner(char str[], int n)	//构造函数
{
	strcpy(buffer, str);
	length = n;
	i = j = 0;
}

int Scanner::isdigit()//判断是否整数
{
	if(ch>='0' && ch<='9')
		return 1;
	else
		return 0;
}

int Scanner::isletter()//首字母的判断
{
	if((ch>='a' && ch<='z') || (ch>='A' && ch<='Z'))
		return 1;
	else
		return 0;
}

void Scanner::getchar()	//将下一输入字符读 到ch中,指针后移一字符位置
{
	ch = buffer[i];
	i++;
}

void Scanner::getbc()	//保证ch是一个非空白字符
{
	while(ch == ' ')
		getchar();
}

void Scanner::concat()	//将ch连接到字符串stroken的末尾
{
	strtoken[j] = ch;
	j++;
}

void Scanner::retract()	//置ch为空白字符,指针前移一字符位置
{
	ch = ' ';
	i--;
}

int Scanner::reserve()	//对stroken进行关键字表的查找,返回其编码值
{
	int i, flag = 0;
	for(i=0; i<15; i++)
	{
		if( strncmp(reservechar[i],strupr(strtoken), j) == 0 )
		{
			flag = 1;
			break;
		}
	}
	if(flag == 1) return i+1;
	else return 0;
}

int Scanner::insertid()	//将stroken中的标识符插入符号表,返回在符号表中的位置
{
	for(int a = 0; a < m; a++)
		for(int b = 0; b < x[a]; b++)
			if( strncmp(&id[a][0], strtoken, j) == 0 )
			{
				return m+1;
				break;
			}
	for(a = 0; a < j; a++)
		id[m][a] = strtoken[a];

	x[m] = j;
	m++;
	return m;
}

int Scanner::insertconst()	//将stroken中的常数插入常数表,返回在常数表中的位置
{
	for(int i = 0; i < j; i++)
		cst[n][i] = strtoken[i];
	y[n] = j;
	n++;
	return n;
}

void Scanner::scan()
{
	while(i < length)
	{
		j = 0;
		int code, value;
		strcpy(strtoken, " ");	//置strtoken为空串
		getchar();
		getbc();
		if(isletter())	//如果打头的是字母
		{
			while(isletter() || isdigit())
			{
				concat();
				getchar();
			}
			retract();
			code = reserve();
			if(code == 0)	//如果扫描到的是标识符
			{
				value = insertid();
				cout<<"<34,"<<value<<">"<<'\n';
			}
			else cout<<"<"<<code<<",*>"<<'\n';	//如果扫描到的是关键字
		}
		else if(isdigit())	//如果打头的是数字
		{
			while(isdigit())
			{
				concat();
				getchar();
			}
			retract();
			value = insertconst();
			cout<<"<33,"<<value<<">"<<'\n';
		}
		else if(ch == '+')
			cout<<"<16,*>"<<'\n'; 
		else if(ch == '-')
			cout<<"<17,*>"<<'\n';
		else if(ch == '*')
			cout<<"<18,*>"<<'\n';
		else if(ch == '/')
			cout<<"<19,*>"<<'\n';
		else if(ch == '=')
			cout<<"<20,*>"<<'\n';
		else if(ch == '<')
		{
			getchar();
			if(ch == '>')
				cout<<"<21,*>"<<'\n';
			else if(ch == '=')
				cout<<"<23,*>"<<'\n';
			else
			{
				retract();
				cout<<"<22,*>"<<'\n';
			}
		}
		else if(ch == '>')
		{
			getchar();
			if(ch == '=')
				cout<<"<25,*>"<<'\n';
			else
			{
				retract();
				cout<<"<24,*>"<<'\n';
			}
		}
		else if(ch == '.')
			cout<<"<26,*>"<<'\n';
		else if(ch == ',')
			cout<<"<27,*>"<<'\n';
		else if(ch == ';')
			cout<<"<28,*>"<<'\n';
		else if(ch == ':')
		{
			getchar();
			if(ch == '=')
				cout<<"<30,*>"<<'\n';
			else
			{
				retract();
				cout<<"<29,*>"<<'\n';
			}
		}
		else if(ch == '(')
			cout<<"<31,*>"<<'\n';
		else if(ch == ')')
			cout<<"<32,*>"<<'\n';
		else if(ch == '{')
		{
			while(ch != '}')
				getchar();
		}
 		else cout<<"出错!"<<'\n';
	}
}

void main(void)
{	
	fstream file;
	file.open("F:/20032320/20032320.txt", ios::in||ios::nocreate);	//以只读方式打开
	file.unsetf(ios::skipws);	//不跳过文本中的空格
	char buffer[100];         //缓冲区定义
	cout<<"扫描结果如下所示"<<'\n';
	while(file.getline(buffer, 100))
	{
		Scanner SS(buffer, strlen(buffer));
		SS.scan();
	}

	cout<<"标识符表如下:\n"<<"编号\t"<<"值\n";
	for(int i=0; i<m; i++)
	{
		cout<<i+1<<'\t';
		for(int j=0; j<x[i]; j++)
			cout<<id[i][j];
		cout<<'\n';
	}

	cout<<"常数表如下:\n"<<"编号\t"<<"值\n";
	for(i=0; i<n; i++)
	{
		cout<<i+1<<'\t';
		for(int j=0; j<y[i]; j++)
			cout<<cst[i][j];
		cout<<'\n';
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -