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

📄 实验一词法分析.cpp

📁 编译原理词法分析程序
💻 CPP
字号:
#include<conio.h>
#include<iostream>
#include<iomanip>
#include<string.h>
#include<fstream>
#include <stdlib.h> 
using namespace std;
int checkprotect(char t[]);
void checkicon(char t[]);

struct node
{
	char t[10];
};
struct node1
{
	char item[15];
	node1 *next;
};
int hr=0;
int kline=0;
int op=0;
node1 *head=NULL;//保存标识符的指针
static int init=0;
void main()
{
  
char filename[30];
		cout<<"*******************"<<endl;
	cout<<"姓名: 张  帆"<<endl;
	cout<<"班级: 04(3)班"<<endl;
	cout<<"学号: 200433101093"<<endl;
	cout<<"*******************"<<endl;
	cout<<"输入要编译的程序名: ";
	char c[20];
	cin>>c;
	fstream file;
	file.open(c,ios::in);
	char newline[80]=" ";
	char word[80]=" ";
	char temp[80]=" ";
	int em;
	node1 *p=NULL;
	node1 *q=NULL;

	int j=0;
	int m=0;
	int n=0;
	int newlength=0;
	int wordlength=0;
	int flag;
	int nextline=0;
	while(1)
	{	
		
		file.getline(newline,80);
		if(strcmp(newline,"")==0)
			break;
	    kline++;//记录当前的行数
		newlength=strlen(newline);//读取新的一行的长度

	
		//下面进行单行的分析,以空格为界
		//每次读入一段字符,进行相应的操作
		for(j=0;j<newlength;j++)
		{
			m=0;//保存每一个单词都是从t字符数组的第一位开始的

			while(newline[j]==' ')
			{
				j++;
			}
//****************************************************************************************************
//字符常数缺右边的单引号(字符常数要求左、右边用单引号界定,不能跨行);
			if(newline[j]==39)
			{
				m=0;
				for(j++;(j<newlength)&&(newline[j]!=39);j++,m++)
						temp[m]=newline[j];
				if(j==newlength)
				{
					
					if(hr==0)
					{
						hr=1;
					   
					}
					cout<<"miss right ' at line "<<kline<<endl;
					flag=strlen(temp);
				    for(em=0;em<flag;em++)
					{
						temp[em]=0;
					}
					flag=strlen(word);
				    for(em=0;em<flag;em++)
					{
						word[em]=0;
					}
				    break;
				}
				else
				{
					p=head;
					for(m=1;p!=NULL;q=p,p=p->next,m++)
					{
						if(strcmp(p->item,temp)==0)
						{   
							if(hr==0){
								cout<<"(38,"<<m<<") ";
							op++;
					        if(op%5==0)
						       cout<<endl;
							break;}
						}
					}
					if(head==NULL)
					{
						head=new node1;
						strcpy(head->item,temp);
						head->next=NULL;
						if(hr==0){
						cout<<"(38,1) ";
						op++;
						if(op%5==0)
							cout<<endl;}
					}
					else
						if(p==NULL&&q!=NULL)
						{
							q->next=new node1;
						    strcpy(q->next->item,temp);
						    q->next->next=NULL;
							if(hr==0){
						    cout<<"(38,"<<m<<") ";
							op++;
					        if(op%5==0)
								cout<<endl;}
						}
					j++;
					flag=strlen(temp);
				    for(em=0;em<flag;em++)
					{
						temp[em]=0;
					}
					flag=strlen(word);
				    for(em=0;em<flag;em++)
					{
						word[em]=0;
					}

				}

			}
//*************************************************************************************************
//注释部分缺右边的界符*/(注释要求左右边分别用/*和*/界定,不能跨行)。
			if(newline[j]=='/'&&newline[j+1]=='*')
			{
				for(j=j+2;j<newlength-1;j++)
					if(newline[j]=='*'&&newline[j+1]=='/')
					break;
				if(j==newlength-1)
				{
					
					if(hr==0)
					{
						hr=1;
					
					}
					cout<<"miss right '*/' at line "<<kline<<endl;
				    break;
				}
				else
				{ 
					j++;
					continue;
				}

			}


//**************************************************************************************************

//**************************************************************************************************
	        //以空格为界,将读入的一行字符进行隔离分析
			while(newline[j]!=' '&&newline[j]!=39&&j<newlength)
			{
				word[m]=newline[j];
				m++;
				j++;
			}
			if(newline[j]==39)
				j--;
			wordlength=strlen(word);
			for(m=0;m<wordlength;m++)
			{
			if(!(
				(word[m]>=65&&word[m]<=91)
				||(word[m]>=97&&word[m]<=122)
				||(word[m]>=39&&word[m]<=62)
				||(word[m]==32)
				||(word[m]==93)
				))
			{
				if(hr==0)
				{
					hr=1;
				}
				cout<<"illegal sympol at line"<<kline<<endl;
				wordlength=0;
				break;
			}
			}

			//对读出来的的单词进行分析
	
			//读取要分析的字符串长度
			for(n=0;n<wordlength;n++)
			{
				m=0;
				while(
					(n<wordlength)&&(word[n]!='+')
					&&(word[n]!='-')&&(word[n]!='*')
					&&(word[n]!='/')&&(word[n]!='=')
					&&(word[n]!='<')&&(word[n]!='>')
					&&(word[n]!=':')&&(word[n]!='.')
					&&(word[n]!=';')&&(word[n]!=','))
				{
					 temp[m]=word[n];
					 n++;
					 m++;
				}//当字符不是单界符且字符还没有读完时,就将其读到temp中
				if(m!=0)//m不等于零,表示在temp中有东西
				{//判断读到的字符是啥东西
				
					m=checkprotect(temp);
					if(m==36)
					{
						checkicon(temp);
					}

				}
				if(n<=wordlength)
				{
				
					switch(word[n])
					{
					case '+':{if(hr==0){cout<<"(43,-) ";op++;if(op%5==0)cout<<endl;break;}}
					case '-':{if(hr==0){cout<<"(45,-) ";op++;if(op%5==0)cout<<endl;break;}}
					case '*':{if(hr==0){cout<<"(41,-) ";op++;if(op%5==0)cout<<endl;break;}}
					case '=':{if(hr==0){cout<<"(56,-) ";op++;if(op%5==0)cout<<endl;break;}}
					case '<':{
						if(n+1<=wordlength)
							if(word[n+1]=='=')
							{if(hr==0){cout<<"(54,-) ";op++;if(op%5==0)cout<<endl;n++;}}
							else if(word[n+1]=='>')
							{if(hr==0){cout<<"(55,-) ";op++;if(op%5==0)cout<<endl;n++;}}
							else
							{if(hr==0){cout<<"(53,-) ";op++;if(op%5==0)cout<<endl;}}
							break;
							 }
					case '>':{
						if(n+1<=wordlength)
							if(word[n+1]=='=')
							{if(hr==0){cout<<"(58,-) ";op++;if(op%5==0)cout<<endl;n++;}}
							else
							{if(hr==0){cout<<"(57,-) ";op++;if(op%5==0)cout<<endl;}}
							break;
							 }
					case ':':{
						if(n+1<=wordlength)
							if(word[n+1]=='=')
							{if(hr==0){cout<<"(51,-) ";op++;if(op%5==0)cout<<endl;n++;}}
							else
							{if(hr==0){cout<<"(50,-) ";op++;if(op%5==0)cout<<endl;}}
							break;
						
							 }
					case '.':{
						if(n+1<=wordlength)
							if(word[n+1]=='.')
							{if(hr==0){cout<<"(47,-) ";op++;if(op%5==0)cout<<endl;n++;}}
							else
							{if(hr==0){cout<<"(46,-) ";op++;if(op%5==0)cout<<endl;}}
							break;
							 }
					case ';':{if(hr==0){cout<<"(52,-) ";op++;if(op%5==0)cout<<endl;break;}}
					case ',':{if(hr==0){cout<<"(44,-) ";op++;if(op%5==0)cout<<endl;break;}}
					case '/':{if(hr==0){cout<<"(48,-) ";op++;if(op%5==0)cout<<endl;break;}}
		


					}
				}
			

                 flag=strlen(temp);
				for(em=0;em<flag;em++)
				{
				    temp[em]=0;
				}

			}
			flag=strlen(word);
			for(em=0;em<flag;em++)
			{
				word[em]=0;
			}
		
		
		}
		for(em=0;em<strlen(newline);em++)
		{
			newline[em]=' ';
		}
		

	}	
	file.close();
	_getch();
	


}
void checkicon(char ty[])
{
	int length=strlen(ty);
	int number=1;
    node1 *p=NULL;
	node1 *q=NULL;
	int k=1;
	if(length==1)
	{
		if(ty[0]=='('){if(hr==0){cout<<"(39,-) ";op++;if(op%5==0)cout<<endl;return;}}
		if(ty[0]==')'){if(hr==0){cout<<"(40,-) ";op++;if(op%5==0)cout<<endl;return;}}
		if(ty[0]=='['){if(hr==0){cout<<"(59,-) ";op++;if(op%5==0)cout<<endl;return;}}
		if(ty[0]==']'){if(hr==0){cout<<"(60,-) ";op++;if(op%5==0)cout<<endl;return;}}
	    if(ty[0]=='/'){if(hr==0){cout<<"(48,-) ";op++;if(op%5==0)cout<<endl;return;}}
		
	}

	for(int qw=0;qw<length;qw++)
	{
		if(ty[qw]<'0'||ty[qw]>'9')
		{
			number=0;
			break;
		}
	}
    if(number==0)			
	{
		if(ty[0]>='0'&&ty[0]<='9')
		{
			
			if(hr==0)
			{
				hr=1;
				
			}
			cout<<"illegal id at line"<<kline<<endl;
		    return;
		}
		for(qw=0;qw<length;qw++)
		{
			if((ty[qw]=='(')||(ty[qw]==')')||(ty[qw]=='/')||(ty[qw]=='[')
				||(ty[qw]==']')||(ty[qw]==39))
			{
			if(hr==0)
			{
				hr=1;
			
			}
				cout<<"illegal id at line"<<kline<<endl;
				return;
			}
		}
	}
    for(p=head;p!=NULL;q=p,p=p->next,k++)
	{
		if(strcmp(p->item,ty)==0)
		{
			if(number==0)
			{
				if(hr==0){cout<<"(36,"<<k<<") ";op++;if(op%5==0)cout<<endl;}
				
			}
			else
			{
				if(hr==0){cout<<"(37,"<<k<<") ";op++;if(op%5==0)cout<<endl;}
			}
			break;
		}
	}
	if(head==NULL)
	{
		head=new node1;
		strcpy(head->item,ty);
		head->next=NULL;
	    if(number==0)
		{
			if(hr==0){cout<<"(36,"<<k<<") ";op++;if(op%5==0)cout<<endl;}
		}
		else
		{
			if(hr==0){	cout<<"(37,"<<k<<") ";op++;if(op%5==0)cout<<endl;}
		}
	}
	else 
		if(p==NULL&&head!=NULL)
		{
			q->next=new node1;
		    strcpy(q->next->item,ty);
		    q->next->next=NULL;
		    if(number==0)
			{
				if(hr==0){cout<<"(36,"<<k<<") ";op++;if(op%5==0)cout<<endl;}
			}
			else
			{
				if(hr==0){cout<<"(37,"<<k<<") ";op++;if(op%5==0)cout<<endl;}
			}
		}
	
}

int checkprotect(char ty[])
{
	 static node f[36];
     if(init==0)
	 {  
		
	     strcpy(f[1].t,"and");
	     strcpy(f[2].t,"array");
	     strcpy(f[3].t,"begin");
	     strcpy(f[4].t,"bool");
	     strcpy(f[5].t,"call");
	     strcpy(f[6].t,"case");
	     strcpy(f[7].t,"char");
	     strcpy(f[8].t,"constant");
	     strcpy(f[9].t,"dim");
	     strcpy(f[10].t,"do");
	     strcpy(f[11].t,"else");
	     strcpy(f[12].t,"end");
	     strcpy(f[13].t,"false");
	     strcpy(f[14].t,"for");
	     strcpy(f[15].t,"if");
	     strcpy(f[16].t,"input");
	     strcpy(f[17].t,"integer");
	     strcpy(f[18].t,"not");
	     strcpy(f[19].t,"of");
	     strcpy(f[20].t,"or");
	     strcpy(f[21].t,"output");
	     strcpy(f[22].t,"procedure");
	     strcpy(f[23].t,"program");
	     strcpy(f[24].t,"read");
	     strcpy(f[25].t,"real");
	     strcpy(f[26].t,"repeat");
	     strcpy(f[27].t,"set");
	     strcpy(f[28].t,"stop");
	     strcpy(f[29].t,"then");
	     strcpy(f[30].t,"to");
	     strcpy(f[31].t,"true");
	     strcpy(f[32].t,"until");
	     strcpy(f[33].t,"var");
	     strcpy(f[34].t,"while");
		 strcpy(f[35].t,"write");
	     init++;
	 }
	 for(int i=1;i<36;i++)
		 if(strcmp(f[i].t,ty)==0)
		 {
			 if(hr==0){
				 if(i<10)
					 cout<<"("<<i<<" ,-) ";
				 else 
					 cout<<"("<<i<<",-) ";
				 op++;if(op%5==0)cout<<endl;}
			 break;
		 }

	return i;
}	

⌨️ 快捷键说明

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