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

📄 b05513 36 张晓 词法分析器最终版.cpp

📁 词法分析的一个实现方法
💻 CPP
字号:
#include<iostream>
#include<stdio.h>
#include<string>
#include<fstream>
using namespace std;
ifstream infile("123.txt",ios::out);
string getWorld(string&,int&);//取连续的字符和数字。
static int line = 1; //表示光标所在的行数 
struct ID{ string name; int count;int worldLine[30];}id[300];//用于存放ID号码--ID符号表
static int ID = 0; //用于记录ID存放的数量 
int Number[250]; //用于存放数字 ,常数表
static int N = 0; //用于记录存放数字的个数 
void Error(string &); //记录非法字符错误
void loginID(string&); //注册ID号 
void loginNumber(string&); //记录数字 
bool same(string&); //判断单词是否已经存在
void yunsuan(string &,string &,int &);//对于运算符的分析
bool isKey(string&);//判断是不是关键字
void expline(string&,int&,string&,int&);// 对于注释错误的判断,注释没有结束标志
struct errorWorld{string name;int line;}ed[250];//记录非法符号的名称及所在行
int worldNumber=0;//记录非法字符个数
////////////////////////////////////////////////////
void ifBlank(string &str,int &i)//跳过空格
{
	while(str[i]==' ')
		i++;
}
////////////////////////////////////////////////////////
string getWorld(string &str,int &i)
{
	string s;
	if(('0'<=str[i] && str[i]<= '9')||('a'<=str[i]&&str[i] <= 'z')||('A'<=str[i]&&str[i]<='Z'))
	while(('0'<=str[i] && str[i]<= '9')||('a'<=str[i]&&str[i] <= 'z')||('A'<=str[i]&&str[i]<='Z'))
	{
		s+=str[i];
		i++;
	}
	else
	while(str[i]!=EOF&&str[i]!=' '&&str[i]!='\n'&&!('0'<=str[i] && str[i]<= '9')&&!('a'<=str[i]&&str[i] <= 'z')&&!('A'<=str[i]&&str[i]<='Z'))
	{
		s+=str[i];
		i++;
	}
	ifBlank(str,i);
	return s;
}
//////////////////////////////////////////////////
void Error(string &ch)//记录非法字符错误的行
{
	ed[worldNumber].name=ch;
	ed[worldNumber].line=line;
	worldNumber++;
}
//////////////////////////////////////////////////
bool isKey(string &str)//判断是不是关键字
{
	string p[14]={"char","int","float","void","const","for","if","else","then","while","switch","break","begin","end"};
	for(int i=0;i<14;i++)
	{
		if(!str.compare(p[i]))
		{
			cout<<"\t\t"<<"_"<<"\t\t"<<str<<endl;
			return true;
		}
	}
	return false;
}
/////////////////////////////////////////////////////
bool same(string &str)//判断该单词是否出现过
{
	for(int i=0;i<ID;i++)
	{
		if(!str.compare(id[i].name))
		{
			id[i].count++;
			id[i].worldLine[id[i].count]=line;
			cout<<"\t\t"<<i<<"\t\t"<<str<<endl;
			return true;
		}
	}
	return false;
}
/////////////////////////////////////////////////////
void loginID(string &str)//注册ID号
{
	if(!same(str))
	{
		id[ID].name=str;
		id[ID].count=1;
		id[ID].worldLine[id[ID].count]=line;
		cout<<"\t\t"<<ID<<"\t\t"<<str<<endl;
		ID++;
	}
}
///////////////////////////////////////////////////
void loginNumber(string &str)//记录数字
{
	int i=0;
	while(i<str.length())
	{
		if('0'<=str[i] && str[i]<= '9')
			i++;
		else break;
	}
	if(i==str.length())
	{
		for(int j=0;j<str.length();j++)
		Number[N]=Number[N]* 10 + (str[j]-'0');
		N++;
		cout<<"\t\t"<<N-1<<"\t\t"<<Number[N-1]<<endl;
	}
	else
	{
		Error(str);
	}
}
//////////////////////////////////////////////////
void yunsuan(string &str,string &str1,int &j)//对于运算符及其他符号的判断
{
	string s;
	for(int i=0;i<str.length();i++)
	{
		if(str[i]=='('||str[i]==')'||str[i]=='['||str[i]==']'||str[i]==';')
			cout<<"\t\t"<<"_"<<"\t\t"<<str[i]<<endl;
		else
		if(str[i]=='<'||str[i]=='>'||str[i]=='!'||str[i]=='=')
		{
			if(i+1<str.length()&&str[i+1]=='=')
				cout<<"\t\t"<<"rlop"<<"\t\t"<<str[i++]<<str[i+1]<<endl;	
			else
			{
				if(str[i]=='<'||str[i]=='>')
					cout<<"\t\t"<<"rlop"<<"\t\t"<<str[i]<<endl;
				if(str[i]=='!')
					cout<<"\t\t"<<"not"<<"\t\t"<<str[i]<<endl;
				if(str[i]=='=')  
					cout<<"\t\t"<<"_"<<"\t\t"<<str[i]<<endl;
			}
		}
		else
		if(str[i]=='+'||str[i]=='-'||str[i]=='*'||str[i]=='%')
		{
			if(i+1<str.length()&&str[i+1]=='=')
				cout<<"\t\t"<<"rlop"<<"\t\t"<<str[i++]<<str[i+1]<<endl;
			else
				cout<<"\t\t"<<"_"<<"\t\t"<<str[i]<<endl;
		}
		else
		if(str[i]=='|')
		{
			if(i+1<str.length()&&str[i+1]=='|')
				cout<<"\t\t"<<"or"<<"\t\t"<<str[i++]<<str[i+1]<<endl;
			else
			{
				s=str[i];	
				Error(s);
			}
		}
		else
		if(str[i]=='&')
		{
			if(i+1<str.length()&&str[i+1]=='&')
				cout<<"\t\t"<<"or"<<"\t\t"<<str[i++]<<str[i+1]<<endl;
			else
			{
				s=str[i];	
				Error(s);
			}
		}
		else
		if(str[i]=='/')
		{
			if(i+1<str.length()&&str[i+1]=='=')
				cout<<"\t\t"<<"rlop"<<"\t\t"<<str[i++]<<str[i+1]<<endl;
			if(i+1<str.length()&&str[i+1]=='*')
			{
				i++;
				expline(str,i,str1,j);
			}
				
			else
				cout<<"\t\t"<<"_"<<"\t\t"<<str[i]<<endl;
		}
		else
		{
			s=str[i];	
			Error(s);
		}
	}
}
///////////////////////////////////////////////////
void expline(string &str1,int &j,string &str2,int&i)//str1代表当前的一个单词,j代表当前的分析道本单词的下标,str2代表当前缓冲区中的一行,i代表str2分析到的位置 
{
	int flag=0;
	for(;j<str1.length();j++)//在当前单词中寻找注释结束符
	{
		if(str1[j]=='*'&&str1[j+1]=='/'&&j+1<str1.length())
		{
			j++;flag=1;break;
		}	
	}
	int l;
	char ch;
	while(!infile.eof()&&flag!=1)
	{
		l=line;
		if(i==0)
		{
			string s;
			
			do//取文件中的一行字符串进行分析
			{
				ch=infile.get();
				s+=ch;
				str2=s;
			}
			while(ch!='\n'&&ch!=EOF);
		}
		do
		{
			str1=getWorld(str2,i);
			for(j=0;j+1<str1.length();j++)//在以后文本中寻找注释结束符
			{
				if(str1[j]==EOF)break;
				if(str1[j]=='*'&&str1[j+1]=='/'&&j+1<str1.length())
				{
					j++;flag=1;
					break;
				}
			}
			if(str2[i]=='\n'&&flag==0){line++;i=0;}//分析完一行后换行
		}
		while(l==line&&flag==0);
		if(ch==EOF&&flag==0)
		{
			ed[worldNumber].line=l;
			ed[worldNumber].name="'/*'注释开始,未发现匹配注释结束符";
			worldNumber++;break;
		}
	}
}
///////////////////////////////////////////////////////
void main()
{	
	string oneworld;
	int i=0;
	int j;
	char ch;
	cout<<"\t\t"<<"分析结果如下:"<<endl;
	while(!infile.eof())
	{
		string worldline;
		do//取文件中的一行字符串进行分析
		{	
			if(ch==EOF)break;
			ch=infile.get();
			worldline+=ch;
		}
		while(ch!='\n'&&ch!=EOF);
		j=line;
		while(line==j&&worldline[i]!=EOF)
		{
			oneworld=getWorld(worldline,i);//取单个的变量进行分析
			if(!isKey(oneworld))
			{
				if(('a'<=oneworld[0]&&oneworld[0] <= 'z')||('A'<=oneworld[0]&&oneworld[0]<='Z'))
					loginID(oneworld);
				else
					if('0'<=oneworld[0] && oneworld[0]<= '9')
						loginNumber(oneworld);
					else
					{
						yunsuan(oneworld,worldline,i);
						if(line!=j&&worldline[i]!=EOF)j=line;
					}
			}
			if(worldline[i]==EOF)break;
			if(worldline[i]=='\n'){line++;i=0;}//分析完一行后换行
		}
	}
	cout<<endl;
	cout<<"分析完毕,共有 "<<worldNumber<<" 处错误。"<<endl;
	if(worldNumber>0)
	{
		for(int i=0;i<worldNumber;i++)
		cout<<"  第 "<<ed[i].line<<" 行:"<<ed[i].name<<"\t\t非法!"<<endl;
	}
}

⌨️ 快捷键说明

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