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

📄 parser.h

📁 编译原理最常见的大作业
💻 H
字号:
#include<fstream>
#include<iostream>
#include<iomanip>
using namespace std;
#define longest 50
#define maxone  50

class Parser
{
protected:
	fstream fin;
public:
	int parser(char *filename);
	int get_value();//读取文件的所有单词
    int parseroff();
};



int Parser::parser(char *filename)
{
	fin.open(filename);
	if(!fin)
	{
		cerr<<"open error"<<endl;
		exit(0);
	}
	return 1;
}

int Parser::parseroff()
{
	fin.close();
	return 0;
}


//char *name,char *str
int Parser::get_value()//读取文件里的所有单词
{
	char ch,ch1,nametest[50];
    int i,count=0;
	bool flag;

	while(fin.get(ch))//每次的行开头或者一个空格后读的第一个字母,即单词的第一个字母
	{
		if('a'<=ch&&ch<='z')//有可能是关键字或标识符
		{
			i=0;
			nametest[i]=ch;
			while('a'<=nametest[i]&&nametest[i]<='z'||'A'<=nametest[i]&&nametest[i]<='Z'||'0'<=nametest[i]&&nametest[i]<='9')
            nametest[++i]=fin.get();
			ch1=nametest[i];//记录其是空格还是换行,等等输出用
			
			if(ch1!=' '||ch1!='\n'||ch1!='\t')//如果不是,则可能是其他符号,要重新读
				fin.seekg(-1,ios::cur);
			
			nametest[i]='\0';//覆盖刚刚读到的空格或换行符或其他符号

			switch (nametest[0])
			{//下面看它是关键字还是标识符
			case 'a':
				if(strcmp(nametest,"and")==0)cout<<"(1,-)";
				else if(strcmp(nametest,"array")==0)cout<<"(2,-)";
				//否则是标识符
				else cout<<"(36,"<<nametest<<")";
				break;
			case'b'://begin	3,bool	4
				if(strcmp(nametest,"begin")==0)cout<<"(3,-)";
				else if(strcmp(nametest,"bool")==0)cout<<"(4,-)";
				else cout<<"(36,"<<nametest<<")";
				break;
			case'c'://call	5 ,case	6 ,char	7 ,constant	8
				if(strcmp(nametest,"call")==0)cout<<"(5,-)";
				else if(strcmp(nametest,"case")==0)cout<<"(6,-)";
				else if(strcmp(nametest,"char")==0)cout<<"(7,-)";
				else if(strcmp(nametest,"constant")==0)cout<<"(8,-)";
				else cout<<"(36,"<<nametest<<")";
				break;
			case'd'://dim	9,do	10
				if(strcmp(nametest,"dim")==0)cout<<"(9,-)";
				else if(strcmp(nametest,"do")==0)cout<<"(10,-)";
				else cout<<"(36,"<<nametest<<")";
				break;
			case'e'://else	11,end	12
				if(strcmp(nametest,"else")==0)cout<<"(11,-)";
				else if(strcmp(nametest,"end")==0)cout<<"(12,-)";
				else cout<<"(36,"<<nametest<<")";
				break;
			case'f'://false	13,for	14
				if(strcmp(nametest,"false")==0)cout<<"(13,-)";
				else if(strcmp(nametest,"for")==0)cout<<"(14,-)";
				else cout<<"(36,"<<nametest<<")";
				break;
			case'i'://if	15,input	16,integer	17
				if(strcmp(nametest,"if")==0)cout<<"(15,-)";
				else if(strcmp(nametest,"input")==0)cout<<"(16,-)";
				else if(strcmp(nametest,"integer")==0)cout<<"(17,-)";
				else cout<<"(36,"<<nametest<<")";
				break;
			case'n'://not	18
				if(strcmp(nametest,"not")==0)cout<<"(18,-)";
				else cout<<"(36,"<<nametest<<")";
				break;
			case'o'://of	19,or	20,output	21
				if(strcmp(nametest,"of")==0)cout<<"(19,-)";
				else if(strcmp(nametest,"or")==0)cout<<"(20,-)";
				else if(strcmp(nametest,"output")==0)cout<<"(21,-)";
				else cout<<"(36,"<<nametest<<")";
				break;
			case'p'://procedure	22,program	23
				if(strcmp(nametest,"procedure")==0)cout<<"(22,-)";
				else if(strcmp(nametest,"program")==0)cout<<"(23,-)";
				else cout<<"(36,"<<nametest<<")";
				break;
			case'r'://read	24,real	25,repeat	26
				if(strcmp(nametest,"read")==0)cout<<"(24,-)";
				else if(strcmp(nametest,"real")==0)cout<<"(25,-)";
				else if(strcmp(nametest,"repeat")==0)cout<<"(26,-)";
				else cout<<"(36,"<<nametest<<")";
				break;
			case's'://set	27,stop	28
				if(strcmp(nametest,"set")==0)cout<<"(27,-)";
				else if(strcmp(nametest,"stop")==0)cout<<"(28,-)";
				else cout<<"(36,"<<nametest<<")";
				break;
			case't'://then	29,to	30,true	31
				if(strcmp(nametest,"then")==0)cout<<"(29,-)";
				else if(strcmp(nametest,"to")==0)cout<<"(30,-)";
				else if(strcmp(nametest,"true")==0)cout<<"(31,-)";
				else cout<<"(36,"<<nametest<<")";
				break;
			case'u'://until	32
				if(strcmp(nametest,"until")==0)cout<<"(32,-)";
				else cout<<"(36,"<<nametest<<")";
				break;
			case'v'://var	33
				if(strcmp(nametest,"var")==0)cout<<"(33,-)";
				else cout<<"(36,"<<nametest<<")";
				break;
			case'w'://while	34,write	35
				if(strcmp(nametest,"while")==0)cout<<"(34,-)";
				else if(strcmp(nametest,"write")==0)cout<<"(35,-)";
				else cout<<"(36,"<<nametest<<")";
				break;
			default://如果不属于上面的小字母,则为标识符
				cout<<"(36,"<<nametest<<")";
				break;
			}//switch (nametest[0])
			cout<<" ";
		}//if('a'<=ch&&ch<='z')//有可能是关键字或标识符
		

		else if('A'<=ch&&ch<='Z')//是关键字
		{
			i=0;
			nametest[i]=ch;
			while('a'<=nametest[i]&&nametest[i]<='z'||'A'<=nametest[i]&&nametest[i]<='Z'||'0'<=nametest[i]&&nametest[i]<='9')
            nametest[++i]=fin.get();
			ch1=nametest[i];//记录其是空格还是换行,等等输出用
			if(ch1!=' '||ch1!='\n'||ch1!='\t')//如果都不是,则可能是其他符号,要重新读
				fin.seekg(-1,ios::cur);
			nametest[i]='\0';//覆盖刚刚读到的空格或换行符
			cout<<"(36,"<<nametest<<")";
			cout<<" ";
		}

		else if('0'<=ch&&ch<='9')//是整数
		{
			i=0;
			nametest[i]=ch;
			while('0'<=nametest[i]&&nametest[i]<='9')
            nametest[++i]=fin.get();
			ch1=nametest[i];//记录其是空格还是换行,等等输出用
			if(ch1!=' '||ch1!='\n'||ch1!='\t')//如果不是,则可能是其他符号,要重新读
				fin.seekg(-1,ios::cur);
			nametest[i]='\0';//覆盖刚刚读到的空格或换行符
			cout<<"(37,"<<nametest<<")";
			cout<<" ";
		}

		else if(ch==39)//是字符常数
		{
			fin.get(ch);
			i=0;
			nametest[i]=ch;
			while(nametest[i]!=39&&nametest[i]!=' '&&nametest[i]!='\n')
            nametest[++i]=fin.get();
			//要求查出字符常数缺右边的单引号
			if(nametest[i]!=39)//不是因为'字符结束,所以可知其缺了右边'
			{
				cout<<"Lack a ' at the right! ";
			}
			else
			{
			nametest[i]='\0';//覆盖刚刚读到的'或空格或换行
			cout<<"(38,"<<nametest<<")";
			cout<<" ";
			}
		}

		else if(ch!=' '&&ch!='\n'&&ch!='\t')
		{
			//接下来是一些符号
			switch (ch)
			{
			case '(':
				cout<<"(39,-)";
				break;
			case')':
				cout<<"(40,-)";
				break;
			case'*'://判别其是'*'还是'*/'
				ch1=NULL;
				fin.get(ch1);
				if(ch1=='/')
					cout<<"(42,-)";
				else
				{
					fin.seekg(-1,ios::cur);
					cout<<"(41,-)";
				}
				break;
			case'+':
				cout<<"(43,-)";
				break;
			case',':
				cout<<"(44,-)";
				break;
			case'-':
				cout<<"(45,-)";
				break;

			case'.':
				//看是一点还是两点
				ch1=NULL;
				fin.get(ch1);
				if(ch1=='.')//两点
					cout<<"(47,-)";
				else//一点
				{
					fin.seekg(-1,ios::cur);
					cout<<"(46,-)";
				}
				break;

			case'/'://判断其是简单的乘号,还是注释符
				ch1=NULL;
				fin.get(ch1);
			    if(ch1=='*')//是注释符
				{//能找出注释部分缺右边的界符*/
					flag=false;
					while(fin.get(ch))
						if(ch=='*')
						{
							ch=fin.get();
							if(ch=='/')
							flag=true;//注释正确
							break;
						}
					if(!flag)//注释出错
						cout<<"Error,lack '*/' or '/'! ";
					
					count--;//为使得输出界面一致,注释不算作输出count的部分
					
				}
				
				else//不是注释符
				{
					fin.seekg(-1,ios::cur);
					cout<<"(48,-)";
				}
				break;
			case':':
				ch1=NULL;
				fin.get(ch1);
				if(ch1=='=')//是:=
				cout<<"(51,-)";
				else
				{
					fin.seekg(-1,ios::cur);
					cout<<"(50,-)";
				}
				break;
			case';':
				cout<<"(52,-)";
				break;
			case'<':
				ch1=NULL;
				fin.get(ch1);
				if(ch1=='=')//为<=
					cout<<"(54,-)";
				else if(ch1=='>')//为<>
					cout<<"(55,-)";
				else
				{
					fin.seekg(-1,ios::cur);
					cout<<"(53,-)";
				}
				break;
			case'=':
				ch1=NULL;
				cout<<"(56,-)";
				break;
			case'>':
				ch1=NULL;
				fin.get(ch1);
				if(ch1=='=')
					cout<<"(58,-)";
				else
				{
					fin.seekg(-1,ios::cur);
					cout<<"(57,-)";
				}
				break;
			case'[':
				cout<<"(59,-)";
				break;
			case']':
				cout<<"(60,-)";
				break;
			default:
				cout<<"Enter error! ";
				break;
			}//switch (ch)
			ch1=NULL;
			fin.get(ch1);
			cout<<" ";
			if(ch1!=' '||ch1!='\n'||ch1!='\t')//如果不是,则可能是其他符号,要重新读
			fin.seekg(-1,ios::cur);
		}//else

		if(ch!=' '&&ch!='\n')
		{
			count++;
			if(count%5==0)
				cout<<endl;
		}

	}//while(fin.get(ch))

	return 0;
}

⌨️ 快捷键说明

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