simple.cpp

来自「基于simple语言的简单词法分析器源代码」· C++ 代码 · 共 225 行

CPP
225
字号
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <iomanip>

using namespace std;

void main()
{
	cout<<"                       ***********************************\n";
	cout<<"                          欢迎使用SAMPLE语言的词法分析器\n";
	cout<<"                       ***********************************\n\n";
	cout<<"       姓名:刘达魁   班级:05计算机科学与技术(1)班    学号:200530754034\n\n\n";

    
	string key[35]={"and","array","begin","bool","call","case","char","constant","dim","do","else","end",
		            "false","for","if","input","integer","not","of","or","output","procedure","program",
					"read","real","repeat","set","stop","then","to","true","until","var","while","write"};
	
	string limit[22]={"(",")","*","*/","+",",","-",".","..","/","/*",":",
		              ":=",";","<","<=","<>","=",">",">=","[","]"};

	fstream file;
	char fileName[20];
	cout<<"请输入待检测的文件名:\n";
	cin>>fileName;
	cout<<"\n分析结果为:\n";
	file.open(fileName,ios::in);                           //打开文件
	if(! file)
	{
		cerr<<"文件不能被打开!"<<endl;
		abort();
	}
	char buffer[20];
	char* s=new char [100];
	int line=0;//记录已从文件中读取的行数
	
	char* check[50];                 //存储检测过的标志符,整数,字符常数
	int e=0;                         //记录已存标志符,整数,字符常数的个数
	for(int x=0;x<50;x++)            //初始化check数组
	{
		check[x]="^_^";
	}

/******************************判断模块******************************/
	while(! file.eof())
	{
		line++;
		file.getline(s,100);
		int n=strlen(s);
	    //cout<<n<<endl;
	    for(int j=0;j<n;j++)
		{
			int k=0;
			if(((s[j]>='A')&&(s[j]<='Z'))||((s[j]>='a')&&(s[j]<='z')))//字母开头
			{
				while(((s[j]>='A')&&(s[j]<='Z'))||((s[j]>='a')&&(s[j]<='z'))||((s[j]>='0')&&(s[j]<='9'))) 
				{
					buffer[k++]=s[j];                                 //将输入字符逐个放入数组buffer中 
					j++;
				}
				buffer[k++]='\0';
				char* array=new char;
				strcpy(array,buffer);
				
				int p=1;
				for(int i=0; i<35; i++)
				{
					if(!key[i].compare(array))                        //判断是否为关健字
					{
						cout<<setw(10)<<"("<<i+1<<",-)"<<'\t';
						p++;
					}
				}
				int d=0;          //标记d=0时,向check[]中插入新的标志符,整数,字符常数
				if(p==1)
				{
					for(int z=0;z<50;z++)
					{
						if(!strcmp(check[z],array))
						{
							cout<<setw(13)<<"(36,"<<z+1<<")"<<'\t';
							d++;
						}						
					}
					if(d==0) 
					{
						check[e++]=array;
						cout<<setw(13)<<"(36,"<<e<<")"<<'\t';
					}
				}
				j--;//退一格
			}
			else if(s[j]>='0'&&s[j]<='9')                             //数字开头
			{
				while(s[j]>='0'&&s[j]<='9')
				{
					buffer[k++]=s[j];                                   
					j++;
				}
				buffer[k++]='\0';
				char* array=new char;
				strcpy(array,buffer);

				int d=0;          //标记,同上
				for(int z=0;z<50;z++)
				{
					if(!strcmp(check[z],array))
					{
						cout<<setw(13)<<"(37,"<<z+1<<")"<<'\t';
						d++;
					}					
				}
				if(d==0)
				{
					check[e++]=array;
					cout<<setw(13)<<"(37,"<<e<<")"<<'\t';
				}
				j--;
			}
			else if(s[j]=='\'')                                        //单引号开头
			{
				int q=0;//q=0时,字符常数缺右边的单引号
				int m1=j;
				for(m1++;m1<n;m1++)                                    //检测单引号是否匹配
				{
					if(s[m1]=='\'')
					{
                        for(int z=j;z<=m1;z++)
						{
							buffer[k++]=s[z];                                   
							z++;
						}
						buffer[k++]='\0';
						char* array=new char;
						strcpy(array,buffer);
						
						int d=0;  //标记,同上
						for(z=0;z<50;z++)
						{
							if(!strcmp(check[z],array))
							{
								cout<<setw(13)<<"(38,"<<z+1<<")"<<'\t';
								d++;
							}							
						}
						if(d==0) 
						{
							check[e++]=array;
							cout<<setw(13)<<"(38,"<<e<<")"<<'\t';
						}
						q++;
						j=m1;
					}
				}
				if(q==0) cout<<"第"<<line<<"行字符常数缺右边的单引号!";
			}
			else if(s[j]=='/'&&s[j+1]=='*')                            //检测注释符是否匹配
			{
				int d=0;//d=0时,行注释部分缺右边界
				int m=j;
				for(m=m+2;m<n;m++)
				{
					if(s[m]=='*'&&s[m+1]=='/') d=1;
					j=m+1;
				}
                if (d==0)  cout<<"第"<<line<<"行行注释部分缺右边界!";
			}
            else if(s[j]=='.'||s[j]==':'||s[j]=='<'||s[j]=='>')        //符号. : < > 开头
			{
				if(s[j+1]!='.' && s[j+1]!='=' && s[j+1]!='>')          //单符号
				{
					buffer[k++]=s[j];
					buffer[k++]='\0';
					char* array=new char;
					strcpy(array,buffer);
					for(int b=0;b<22;b++)
					{
						if(!limit[b].compare(array))
						{
							cout<<setw(10)<<"("<<b+39<<",-)"<<'\t'; 
						}
					}
				}
				else                                                    //双符号
				{
					buffer[k++]=s[j++];
					buffer[k++]=s[j++];
					buffer[k++]='\0';
					char* array=new char;
					strcpy(array,buffer);
					for(int b=0;b<22;b++)
					{
						if(!limit[b].compare(array))                        
						{
							cout<<setw(10)<<"("<<b+39<<",-)"<<'\t';
						}
					}
					j--;
				}
			}
			else if(s[j]==' ');
			else                                                        //其他界符
			{
				buffer[k++]=s[j];
				buffer[k++]='\0';
				char* array=new char;
				strcpy(array,buffer);
				int pp=0;//标记
				for(int b=0;b<22;b++)
				{
					if(!limit[b].compare(array))
					{
						cout<<setw(10)<<"("<<b+39<<",-)"<<'\t';
						pp++;
					}
				}
				if(pp==0) cout<<"第"<<line<<"行中存在非法字符!";
			}
		}
	}
	file.close();                        //关闭文件
}

⌨️ 快捷键说明

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