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

📄 bianyi.cpp

📁 编译原理的语法生成器
💻 CPP
字号:

#include<iostream.h>
#include<stdlib.h>
#include<string.h>

enum words{        id,          // 标识符      0
                   mainsy,      // 主函数      1
		   ifsy,        // if          2
		   elsesy,      // else        3
		   intsy,       // int         4
		   intconst,	// 整形常量    5
                   addop,       // +           6
		   subop,       // -           7
                   timeop,      // *           8
		   divop,       // /           9
                   lpar,        // (           10
		   rpar,        // )           11
                   lbpar,       // {           12
		   rbpar,       // }           13
                   geop,	// >=          14
                   goop,	// >           15
		   leop,	// <=          16
		   loop,	// <           17
		   neop,	// !=          18
		   eqop,	// =           19
		   comma,	// ,           20
		   semicolon,   // ;           21
		   eoline,	// 回车转行    22
		   eofile,	// 文件结束    23
                   other        // 其他错误    24
           };

int CODE[200]={0};       // 词法分析生成的代码表,最大长度为200
char ID[50][10]={0};     // 标识符表最大长度为50,一个标识符的最多有效位为10
char KEYWORD[][5]={"\0","main","if","else","int"}; // 关键字表

int NEXT=0;              // 代码表的当前位置
int ID_NUMBER=1;         // 标识符表的当前长度
int error=0,overflow=0;  // 出错和常数溢出标志

int G_next=0;            // 记录语法分析读代码表的当前位置
int Line=1;              // 记录源程序当前行数

int Isdigit(char);       // 判断输入字符是否为数字
int Isletter(char);      // 判断输入字符是否为字母
int Find_Keyword(char *);// 查找关键字表
int Find_ID(char *);     // 查找标识符表
void WORD_ananlyse();    // 词法分析器

                         // 语法分析器子函数
void Complex_Sentence();
void Declare();
void ID_List();
void Sentence_Sec();
void Sentence();
void Condition();
void Evaluate();
void Expression();
void Exp_Item();
void Exp_Item_();
void E_Item();
void Item();
void Item_();


void WORD_analyse()      // 词法分析
{
	char ch;             // 取输入的字符
        int c_number;        // 计算标识符或常数的位数
	char word[10]="";    // 存放单词
	while((ch=cin.peek())!='#')     // 判断是否结束
	{
		if (ch==10)      // 将eoline填入代码表
		{
			CODE[NEXT]=eoline;
			NEXT++;
		}

		cin>>ch;         // 读入字符





	    if (Isdigit(ch)) // 处理整型常数
		{
			int value=0; // 常数值
			c_number=0;  // 计算常数的位数
			while(Isdigit(ch))
			{
				if(c_number>5||(value>3276&&ch>7))   // 判断常数是否溢出
				   overflow=1;  
				value=value*10+ch-48;
			    cin>>ch;
			    c_number++;
			} 		    cin.putback(ch);    // 放回刚取的字符
                        CODE[NEXT]=intconst;// 将intconst填入代码表
			NEXT++;
			CODE[NEXT]=value;   // 将常数值填入代码表
			NEXT++;
		}





	    else if(Isletter(ch))   // 接受字符串
		{   int re_w;           // 记录单词在关键字表或标识符表中的位置
		    word[0]=ch;
			c_number=1;
			while ((ch=cin.peek())!=' '&&c_number<10)
			{
				if(Isletter(ch)||Isdigit(ch))
				{
					word[c_number]=ch;
				    c_number++;
					cin>>ch;
				}
				else break;
			}
		        word[c_number]=0;
			if((re_w=Find_Keyword(word))!=-1) // 若单词为关键字
			{  
				CODE[NEXT]=re_w;
				NEXT++;
			}
			else if((re_w=Find_ID(word))!=-1) // 若单词为标识符
			{  
                                CODE[NEXT]=id;                // 将id填入代码表
				NEXT++;
				CODE[NEXT]=re_w;     // 将标识符在ID[]数组的位置填入代码表
				NEXT++;
			}           
                             else                              // 定义新的标识符
			{
				CODE[NEXT]=id;                // 将id填入代码表
				NEXT++;
				strcpy(ID[ID_NUMBER],word);   // 将标识符填入ID[]数组
				CODE[NEXT]=ID_NUMBER; // 将标识符在ID[]数组的位置填入代码表
				NEXT++;
				ID_NUMBER++;
			}
		}



	    else if(ch=='!')
		{
			if(ch=='=') 
			{
				cin>>ch;
				CODE[NEXT]=neop;              // 将neop填入代码表
				NEXT++;
			}
		}




		else if(ch=='>')
		{
   			if(cin.peek()=='=') 
			{
				cin>>ch;
				CODE[NEXT]=geop;              // 将geop填入代码表
				NEXT++;
			}
			else                              // 将goop填入代码表
			{	CODE[NEXT]=goop; NEXT++;}
		}




		else if(ch=='<')
		{
			if(cin.peek()=='=') 
			{
				cin>>ch;
				CODE[NEXT]=neop;              // 将leop填入代码表 
				NEXT++;
			}
			else                              // 将loop填入代码表
			{	CODE[NEXT]=loop; NEXT++;}
		}




	    else if(ch=='=')                      // 将eqop填入代码表
		             {	CODE[NEXT]=eqop; NEXT++;}


	    else if(ch=='+')                      // 将addop填入代码表
                             {	CODE[NEXT]=addop; NEXT++;}
                                                    		
	    else if(ch=='-')                      // 将subop填入代码表
		             {	CODE[NEXT]=subop; NEXT++;}

	    else if(ch=='*')                      // 将timeop填入代码表
		             {	CODE[NEXT]=timeop; NEXT++;}

	    else if(ch=='/')                      // 将divop填入代码表
		             {	CODE[NEXT]=divop; NEXT++;}
	    else if (ch==',')

        	             {	CODE[NEXT]=comma; NEXT++;}

	    else if(ch==';')                      // 将semicolon填入代码表
		             {	CODE[NEXT]=semicolon; NEXT++;}

	    else if(ch=='(')                      // 将lpar填入代码表
		             {	CODE[NEXT]=lpar; NEXT++;}

	    else if(ch==')')                      // 将rpar填入代码表
		             {	CODE[NEXT]=rpar; NEXT++;}

             else if(ch=='{')                      // 将lbpar填入代码表
		             {	CODE[NEXT]=lbpar; NEXT++;}

	     else if(ch=='}')                      // 将rbpar填入代码表
		             {	CODE[NEXT]=rbpar; NEXT++;}
      
	          else              
		             {	CODE[NEXT]=other; NEXT++;}
      }
	  CODE[NEXT]=eofile;                      // 装入文件结束符
}



int Find_Keyword(char *word)
{	int i;
	for (i=0 ; i<=5 ; i++)
	{	if (!strcmp(KEYWORD[i],word))         // 找到匹配的关键字
	    	return i;     
	}
	return -1;	                              // 匹配失败
}

int Find_ID(char *word)
{
	int i;
	for (i=1 ; i<=ID_NUMBER ; i++)
	{
		if (!strcmp(ID[i],word))
			return i;                         // 找到匹配的标识符
	}
	return -1;	                              // 匹配失败
}



int Isletter(char ch)	 // 是否为字母,是返回1 ,否返回0
{
	if(((ch>='a')&&(ch<='z'))||((ch>='A')&&(ch<='Z')))
		return(1);
	else return(0);
}


int Isdigit(char ch)	 // 是否为数字,是返回1 ,否返回0
{
	if((ch>='0')&&(ch<='9'))
		return(1);
	else return(0);
}


void match(enum words word) // 匹配当前代码
{
	if (CODE[G_next]==word)
	{
		G_next++;
		if(word==intconst||word==id)
			G_next++;
	}
	else  error=1;          // 出错
	while (CODE[G_next]==eoline)
	{                       // 记录行数
		G_next++;
		Line++;
	}
}


void GRAMMAR_analyse()  // 程序->main(){复合语句}
{
	match(mainsy);
	if (!error)
		match(lpar);
	if (!error)
		match(rpar);
	if (!error)
		match(lbpar);
	if (!error)
		Complex_Sentence();
	if (!error)
		match(rbpar);
	if (!error)
		match(eofile);
}


void Complex_Sentence()  // 复合语句->说明部分;复合语句|语句部分
{
	if (CODE[G_next]==intsy)
	{
		Declare();		 // 说明部分,声明变量
        match(semicolon);
	    if (CODE[G_next]!=rbpar && CODE[G_next]!=eofile && !error)
		    Complex_Sentence();// 复合语句
	}
	else
		Sentence_Sec();
}


void Declare()           // 说明部分->int 变量列
{
	match(intsy);
	if (!error)  ID_List(); 
}


void Sentence_Sec()     // 语句部分->语句 语句部分|语句
{
	while (!error && CODE[G_next]!=eoline && CODE[G_next]!=rbpar )
	       Sentence();
}

void Sentence()          // 语句->条件语句|赋值语句|;
{
	if (CODE[G_next]==ifsy)
		Condition();     // 条件语句
	else if (CODE[G_next]==semicolon)
		match(semicolon);// 空语句
	else
		Evaluate();      // 赋值语句
}


void ID_List()           // 变量列->id,变量列|id
{
	match(id);
	if(!error&&CODE[G_next]==comma)
	{
		match(comma);
	    if (!error)		ID_List();
	}
}


void Condition()         // 条件语句->if(表达式)语句  else 语句 | if(表达式)语句
{
	match(ifsy);
	if (!error)
		match(lpar);
	if (!error)
		Expression();
	if (!error)
		match(rpar);
	if (!error)
		Sentence();
	if (!error && CODE[G_next]==elsesy)
	{
		match(elsesy); 		if (!error)
			Sentence();
	}
}



void Expression()        // 表达式->表达项>表达项|表达项>=表达项|表达项<表达项
{                        //        |表达项<=表达项|表达项!=表达项|表达项=表达项
	Exp_Item();
	if (!error)
		switch(CODE[G_next])
		{
		case geop:	match(geop);
			        break;
		case goop:	match(goop);
			        break;
		case leop:	match(leop);
			        break;
		case loop:	match(loop);
			        break;
		case neop:	match(neop);
			        break;
		case eqop:	match(eqop);
			        break;
		default:	return;
		}
	if (!error)		Exp_Item();
}


void Exp_Item()          //表达项->项  表项
{
	Item();
	if (!error)
		Exp_Item_();
}


void Exp_Item_()         // 表项->+项|表项   表项->-项|表项
{
	if (CODE[G_next]==addop)
	{
		match(addop);
		if (!error)
			Item();
		if (!error)
			Exp_Item_();
	}


	else if (CODE[G_next]==subop)
	{
		match(subop);
		if (!error)
			Item();
		if (!error)
			Exp_Item_();
	}
}



void Item()              // 项->子项  项’
{
	E_Item();
	if (!error)
		Item_();
}


void Item_()            // 项’->* 子项 项’      项’->/子项 项’
{
	if (CODE[G_next]==timeop)
	{
		match(timeop);
		if (!error)
			E_Item();
		if (!error)
			Item_();
	}

	else if (CODE[G_next]==divop)
	{
		match(divop);
		if (!error)
			E_Item();
		if (!error)
			Item_();
	}
}


void E_Item()            // 子项->id|num|(表项)
{
	switch(CODE[G_next])
	{   case id:        match(id);
		                break;
	    case intconst:  match(intconst);
		                break;
	    default:        match(lpar);
		if (!error)		Exp_Item();
		if (!error)		match(rpar);
	}
}


void Evaluate()          // 赋值语句->id=表达式
{
	match(id);
	if (!error)
		match(eqop);
	if (!error)
		Expression();
	if (!error)
		match(semicolon);
}




void main()
  {
	cout<<"enter the origial codes"<<endl;
	WORD_analyse();                // 词法分析
	GRAMMAR_analyse();             // 语法分析
	cout<<"the coding table is   "<<endl;
	for(int i=0; i<NEXT;i++)       // 输出代码表
	{
		cout<<CODE[i]<<"  ";
		if(CODE[i]==22)  cout<<endl;
	}
	if (overflow)                  // 输出结果
		cout <<"\n something wrong about int." <<endl;
	else if (error)
		cout <<"\n the " <<Line<<"th line  is wrong" <<endl;
	else
		cout <<"\n all right!" <<endl;
}

⌨️ 快捷键说明

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