编译原理实验语法分析器

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include<string.h>
#include<fstream>
#include<map>
using namespace std;
const int N=10010;
string words[N];
string vlaue[N];
int wordsnums=0;
string KEYWORD[19]={"const","if","else","void","return","while","then","for","do",      //关键字
                    "int","char","double","float","case","cin","cout","main","scanf","printf"};
char OPERATOR[8]={'+','-','*','/','>','<','=','!'};     //运算符
string OPERRATOR1[11]={"+","-","*","/",">","<","=","<=",">=","==","!="};
char FILTER[4]={' ','\t','\r','\n'};                    //过滤符
      //过滤字符值
 

/**判断是否为关键字**/
bool IsKeyword(string word){
    for(int i=0;i<19;i++){
        if(KEYWORD[i]==word){
            return true;
        }
    }
    return false;
}

 
/**判断是否为运算符**/
bool IsOperator(char ch){
    for(int i=0;i<8;i++){
        if(OPERATOR[i]==ch){
            return true;
        }
    }
    return false;
}
/**判断是否为过滤符**/
bool IsFilter(char ch){
    for(int i=0;i<4;i++){
        if(FILTER[i]==ch){
            return true;
        }
    }
    return false;
}
/**判断是否为大写字母**/
bool IsUpLetter(char ch){
    if(ch>='A' && ch<='Z') return true;
    return false;
}
/**判断是否为小写字母**/
bool IsLowLetter(char ch){
    if(ch>='a' && ch<='z') return true;
    return false;
}
/**判断是否为数字**/
bool IsDigit(char ch){
    if(ch>='0' && ch<='9') return true;
    return false;
}
/**返回每个字的值**/
template <class T>
int value(T *a,int n,T str){
	for(int i=0;i<n;i++){
		if(a[i]==str) return i;
	}
	return -1;
}
int value1(string str1,string a[])
{
	for(int i=0;i<11;i++)
	{
		if(a[i]==str1) return i;
		
	}
	return true;
}
/**词法分析**/
void analyse(FILE * fpin){
    char ch=' ';
    string arr="";
    while((ch=fgetc(fpin))!=EOF){
        arr="";
        if(IsFilter(ch)){}              //判断是否为过滤符
        else if(IsLowLetter(ch)){       //判断是否为关键字
            while(IsLowLetter(ch)||IsDigit(ch)||IsUpLetter(ch)||ch=='_'){
				arr += ch;
				ch=fgetc(fpin);
            }
			//fseek(fpin,-1L,SEEK_CUR);
			if(IsKeyword(arr)){
				int flag;
				flag=value(KEYWORD,19,arr);
				switch(flag)
				{
					case 0: words[wordsnums]="CONSTTK";break;
					case 1: words[wordsnums]="IFTK";break;
					case 2: words[wordsnums]="ELSETK";break;
					case 3: words[wordsnums]="VOIDTK";break;
					case 4: words[wordsnums]="RETURNTK";break;
					case 5: words[wordsnums]="WHILETK";break;
					case 6: words[wordsnums]="THENTK";break;
					case 7: words[wordsnums]="FORTK";break;
					case 8: words[wordsnums]="DOTK";break;
					case 9: words[wordsnums]="INTTK";break;
					case 10: words[wordsnums]="CHARTK";break;
					case 11:words[wordsnums]="DOUBLETK";break;
					case 12: words[wordsnums]="FLOATTK";break;
					case 13: words[wordsnums]="CASETK";break;
					case 14: words[wordsnums]="CINTK";break;
					case 15: words[wordsnums]="COUTTK";break;
					case 16: words[wordsnums]="MAINTK";break;
					case 17: words[wordsnums]="SCANFTK";break;
					case 18:words[wordsnums]="PRINTFTK";break;
				}
				fseek(fpin,-1L,SEEK_CUR);
				
			}
			else
            {
                
                words[wordsnums]="IDENFR";
                fseek(fpin,-1L,SEEK_CUR);
            }
            vlaue[wordsnums]=arr;
            wordsnums++;
        }
        else if(IsDigit(ch)){           //判断是否为数字
            while(IsDigit(ch)||(ch=='.'&&IsDigit(fgetc(fpin)))){
                arr += ch;
                ch=fgetc(fpin);
            }
            fseek(fpin,-1L,SEEK_CUR);
            words[wordsnums]="INTCON";
            vlaue[wordsnums]=arr;
            wordsnums++;
            
			
			 
        }
        else if(IsUpLetter(ch)||IsLowLetter(ch)||ch=='_'){
            while(IsUpLetter(ch)||IsLowLetter(ch)||ch=='_'||IsDigit(ch)){
                arr += ch;
                ch=fgetc(fpin);
            }
            fseek(fpin,-1L,SEEK_CUR);
            words[wordsnums]="IDENFR";
            vlaue[wordsnums]=arr;
            wordsnums++;
        }
        
		
		else if(IsOperator(ch))
			{
				do
				{
					arr+=ch;
					ch=fgetc(fpin);
				}while(IsOperator(ch)&&ch!='+');
				int flag1;
			    flag1=value1(arr,OPERRATOR1);
		 	    
			    switch(flag1)
			   {
				case 0: words[wordsnums]="PLUS";break;
				case 1: words[wordsnums]="MINU";break;
				case 2: words[wordsnums]="MULT";break;
				case 3: words[wordsnums]="DIV";break;
				case 4: words[wordsnums]="GRE";break;
				case 5: words[wordsnums]="LSS";break;
				case 6: words[wordsnums]="ASSIGN";break;
				case 7: words[wordsnums]="LEQ";break;
				case 8: words[wordsnums]="GEQ";break;
				case 9: words[wordsnums]="EQL";break;
				case 10: words[wordsnums]="NEQ";}
				fseek(fpin,-1L,SEEK_CUR);
				vlaue[wordsnums]=arr;
				wordsnums++;
			}
		else if(ch=='"')
		{
			ch=fgetc(fpin);
			string str2;
			while(ch!='"')
			{
				str2+=ch;
				ch=fgetc(fpin);
			}
			words[wordsnums]="STRCON";
			vlaue[wordsnums]=str2;
			wordsnums++;
		}
		else if(ch==39)
		{
			ch=fgetc(fpin);
			string str3;
			while(ch!=39)
			{
				str3+=ch;
				ch=fgetc(fpin);
			}
			words[wordsnums]="CHARCON";
			vlaue[wordsnums]=str3;
			wordsnums++;
			
		
		}
					
		
			
			
			
			
		else {
			switch(ch){
			case ';': 
			          words[wordsnums]="SEMICN";
			          vlaue[wordsnums]=ch;
			          wordsnums++;
			          break;
            case ',': 
			          words[wordsnums]="COMMA";
			          vlaue[wordsnums]=ch;
			          wordsnums++;
			          break;
            case '(': 
			          words[wordsnums]="LPARENT";
			          vlaue[wordsnums]=ch;
			          wordsnums++;
			          break;
            case ')': 
			          words[wordsnums]="RPARENT";
			          vlaue[wordsnums]=ch;
			          wordsnums++;
			          break;
            case '[': 
			          words[wordsnums]="LBRACK";
			          vlaue[wordsnums]=ch;
			          wordsnums++;
			          break;
            case ']': 
			          words[wordsnums]="RBRACK";
			          vlaue[wordsnums]=ch;
			          wordsnums++;
			          break;
            case '{': 
			          words[wordsnums]="LBRACE";
			          vlaue[wordsnums]=ch;
			          wordsnums++;
			          break;
            case '}': 
			          words[wordsnums]="RBRACE";
			          vlaue[wordsnums]=ch;
			          wordsnums++;
			          break;
            default :{}}
            }
        
        
    }
 
}
int q;
map <string,int>Choose;
void digui0();		//<字符串>
void digui1();		//<程序>
void digui2();		//<常量说明>
void dugui3();		//<常量定义>
void digui4();		//<无符号整数>	
void digui5();		//<整数>
void digui6();		//<声明头部>
void digui7();		//<变量说明>
void digui8();		//<变量定义>
void digui9();		//<有返回值函数定义>
void digui10();		//<无返回值函数定义>
void digui11();		//<复合语句>
void digui12();		//<参数表>
void digui13();		//<主函数>
void digui14();		//<表达式>
void digui15();		//<项>
void digui16();		//<因子>
void digui17();		//<语句>
void digui18();		//<赋值语句>
void digui19();		//<条件语句>
void digui20();		//<条件>
void digui21();		//<循环语句>
void digui22();		//<步长>
void digui234();	//<有无返回值函数调用语句>
void digui25();		//<值参数表> 
void digui26();     //<语句列>
void digui27();     //<读语句>
void digui28();     //<写语句>
void digui29();		//<返回语句>
fstream fout("output.txt",ios::out);
void string_analyse()
{
	q=0;
	digui1();
	return;
}
void output(string str)
{
	if(words[q]==str)
	{
		fout<<words[q]<<" "<<vlaue[q]<<endl;
		q++;
	}
	else cout<<"error"<<endl;
}
void digui0()
{
	output("STRCON");
	fout<<"<字符串>"<<endl;
}
void digui1()
{
	//[<常量说明>][<变量说明>]{<有返回值函数定义>|<无返回值函数定义>}<主函数>
	//常量说明:
	if(words[q]=="CONSTTK") digui2();
	//变量说明: 
	if((words[q]=="INTTK"||words[q]=="CHARTK")&&words[q+1]=="IDENFR"&&words[q+2]!="LPARENT")
	{
		digui7();
	} 
	//有无返回值函数定义
	while((words[q]=="VOIDTK"||words[q]=="CHARTK"||words[q]=="INTTK")&&words[q+1]=="IDENFR"&&words[q+2]=="LPARENT")
	{
		if(words[q]=="CHARTK"||words[q]=="INTTK") digui9();
		else digui10();
	}
	//主函数
	if((words[q]=="VOIDTK"||words[q]=="INTTK")&&words[q+1]=="MAINTK") 
	{
		digui13();
	}
	if(q==wordsnums)
	{
		fout<<"<程序>"<<endl;
		return;
	}
	else
	{
		cout<<"qerror"<<endl;
	}
}
void digui3(); //距离太远重新声明 
void digui2() //常量说明
{
	//const<常量定义>;{ const<常量定义>;}
	do
	{
		output("CONSTTK");
		digui3();
		output("SEMICN");	
	}while(words[q]=="CONSTTK");
	fout<<"<常量说明>"<<endl;
} 
void digui3() //常量定义 
{
    //int<标识符>=<整数>{,<标识符>=<整数>}
    //char<标识符>=<字符>{,<标识符>=<字符>}
	if(words[q]=="INTTK")
	{
		output("INTTK");output("IDENFR");output("ASSIGN");
		digui5();//整数 
		while(words[q]=="COMMA")
		{
			output("COMMA");
			output("IDENFR");
			output("ASSIGN");
			digui5();
		}
	}
	if(words[q]=="CHARTK")
	{
		output("CHARTK");output("IDENFR");output("ASSIGN");output("CHARCON");
		while(words[q]=="COMMA")
		{
			output("COMMA");output("IDENFR");output("ASSIGN");output("CHARCON"); 
		}
		
	}
	fout<<"<常量定义>"<<endl;
	
		
}
void digui4()
{
	//<非零数字>{<数字>}| 0
	output("INTCON");
	fout<<"<无符号整数>"<<endl;
	
}
void digui5()
{
	//[+|-]<无符号整数>
	if(words[q]=="PLUS") output("PLUS"); 
	else if(words[q]=="MINU") output("MINU");
	digui4();
	fout<<"<整数>"<<endl;
}
void digui6()
{
	//int<标识符> |char<标识符>
	if(words[q]=="INTTK") output("INTTK");
	else if(words[q]=="CHARTK") output("CHARTK");
	output("IDENFR");
	fout<<"<声明头部>"<<endl;
}
void digui7()
{
	//<变量定义>;{<变量定义>;}
	do
	{
		digui8();
		output("SEMICN");
	}while((words[q]=="INTTK"||words[q]=="CHARTK")&&words[q+1]=="IDENFR"&&words[q+2]!="LPARENT");
	fout<<"<变量说明>"<<endl;
}
void digui8()
{
	//<类型标识符>(<标识符>|<标识符>'['<无符号整数>']'){,(<标识符>|<标识符>'['<无符号整数>']' )} 
	//||<无符号整数>表示数组元素的个数,其值需大于0
	//<类型标识符>      ::=  int | char
	if(words[q]=="INTTK") output("INTTK");
	else if(words[q]=="CHARTK") output("CHARTK");
	output("IDENFR");
	if(words[q]=="LBRACK")  
	{
		output("LBRACK");
		digui4();
		output("RBRACK");
	}
	while(words[q]=="COMMA")
	{
		output("COMMA");
		output("IDENFR");
		if(words[q]=="LBRACK")
		{
			output("LBRACK");
			digui4();
			output("RBRACK");
		}		
	}
	fout<<"<变量定义>"<<endl;
}
void digui9()
{
	//<声明头部>'('<参数表>')' '{'<复合语句>'}'
	digui6();
	output("LPARENT");
	digui12();
	output("RPARENT");
	output("LBRACE");
	digui11();
	output("RBRACE");
	fout<<"<有返回值函数定义>"<<endl;
	
}
void digui10()
{
	//<无返回值函数定义>  ::= void<标识符>'('<参数表>')''{'<复合语句>'}'
	output("VOIDTK");
	Choose[vlaue[q]]=1;
	output("IDENFR");
	output("LPARENT");
	digui12();
	output("RPARENT");
	output("LBRACE");
	digui11();
	output("RBRACE");
	fout<<"<无返回值函数定义>"<<endl;
	
}
void digui11()
{
	//[<常量说明>][<变量说明>]<语句列>
	if(words[q]=="CONSTTK") digui2();
	if((words[q]=="INTTK"||words[q]=="CHARTK")&&words[q+1]=="IDENFR"&&words[q+2]!="LPARENT")
	{
		digui7();
	}
	digui26();
	fout<<"<复合语句>"<<endl;
}
void digui12()
{
	//<类型标识符><标识符>{,<类型标识符><标识符>}| <空>
	if(words[q]!="RPARENT")
	{
		if(words[q]=="INTTK") output("INTTK");
		else if(words[q]=="CHARTK") output("CHARTK");
		output("IDENFR");
		while(words[q]=="COMMA")
		{
			output("COMMA");
			if(words[q]=="INTTK") output("INTTK");
		    else if(words[q]=="CHARTK") output("CHARTK");
		    output("IDENFR");
		}
	}
	fout<<"<参数表>"<<endl;

}
void digui13()
{
	//<主函数>    ::= void main‘(’‘)’ ‘{’<复合语句>‘}’
	output("VOIDTK");output("MAINTK");output("LPARENT");output("RPARENT");
	output("LBRACE");
	digui11();
	output("RBRACE");
	fout<<"<主函数>"<<endl;
	
}
void digui14()
{
	//<表达式>    ::= [+|-]<项>{<加法运算符><项>}   //[+|-]只作用于第一个<项>
	if(words[q]=="PLUS") output("PLUS");
	else if(words[q]=="MINU") output("MINU");
	digui15();
	while(words[q]=="PLUS"||words[q]=="MINU")
	{
		if(words[q]=="PLUS") output("PLUS");
	    else if(words[q]=="MINU") output("MINU");
	    digui15();
	}
	fout<<"<表达式>"<<endl;
}
void digui15()
{
	//<项>     ::= <因子>{<乘法运算符><因子>}
	digui16();
	while(words[q]=="MULT"||words[q]=="DIV")
	{
		if(words[q]=="MULT") output("MULT");
		else if(words[q]=="DIV") output("DIV");
		digui16();
	} 
	fout<<"<项>"<<endl;
}
void digui16()
{
	//<因子>    ::= <标识符>|<标识符>'['<表达式>']'
	//|'('<表达式>')'|<整数>|<字符>|<有返回值函数调用语句>
	if(words[q]=="IDENFR")
	{
		if(words[q+1]=="LBRACK")
		{
			output("IDENFR");
			output("LBRACK");
			digui14();
			output("RBRACK");
		}
		else if(words[q+1]=="LPARENT") digui234();
		else output("IDENFR");
	}
	else if(words[q]=="LPARENT") {output("LPARENT");digui14();output("RPARENT");}
	else if(words[q]=="INTCON"||words[q]=="PLUS"||words[q]=="MINU") digui5();
	else if(words[q]=="CHARCON") output("CHARCON");
	fout<<"<因子>"<<endl;
}
void digui17()
{
	//<语句>    ::= <条件语句>|<循环语句>| '{'<语句列>'}'| <有返回值函数调用语句>; 
	// |<无返回值函数调用语句>;|<赋值语句>;|<读语句>;|<写语句>;|<空>;|<返回语句>;
	if(words[q]=="IFTK") digui19();
	else if(words[q]=="WHILETK"||words[q]=="DOTK"||words[q]=="FORTK") digui21();
	else if(words[q]=="LBRACE")
	{
		output("LBRACE");
		digui26();
		output("RBRACE");
	}
	else if(words[q]=="IDENFR")
	{
		if(words[q+1]=="LPARENT") {digui234();output("SEMICN");}//有无返回值函数调用语句 
		else{
			digui18();
			output("SEMICN"); //赋值语句 
		}
	}
	else if(words[q]=="SCANFTK")
	{
		digui27();output("SEMICN");
	}
	else if(words[q]=="PRINTFTK")
	{
		digui28();output("SEMICN");
	}
	else if(words[q]=="SEMICN") output("SEMICN");
	else if(words[q]=="RETURNTK")
	{
		digui29();output("SEMICN");
	}
	fout<<"<语句>"<<endl;
	
}
void digui18()
{
	//<赋值语句>   ::=  <标识符>=<表达式>|<标识符>'['<表达式>']'=<表达式>
	output("IDENFR");
	if(words[q]=="LBRACK")
	{
		output("LBRACK");
		digui14();
		output("RBRACK");
	}
	output("ASSIGN");
	digui14();
	fout<<"<赋值语句>"<<endl;

}
void digui19()
{
	//<条件语句>  ::= if '('<条件>')'<语句>[else<语句>]
	output("IFTK");
	output("LPARENT");
	digui20();
	output("RPARENT");
	digui17();
	if(words[q]=="ELSETK")
	{	
	  output("ELSETK");
	  digui17();}
	fout<<"<条件语句>"<<endl;
}
void digui20()
{
	// <表达式><关系运算符><表达式> (整型表达式之间才能进行关系运算)
	//<表达式>    (表达式为整型,其值为0条件为假,值不为0时条件为真)
	digui14();
	if(words[q]=="LSS"||words[q]=="LEQ"||words[q]=="GRE"||words[q]=="GEQ"
	||words[q]=="EQL"||words[q]=="NEQ")
	{
		output(words[q]);
		digui14();
	}
	fout<<"<条件>"<<endl;
}
void digui21()
{
	//<循环语句>   ::=  while '('<条件>')'<语句>
	//| do<语句>while '('<条件>')' 
	//|for'('<标识符>=<表达式>;<条件>;<标识符>=<标识符>(+|-)<步长>')'<语句>
	if(words[q]=="WHILETK")
	{
		output("WHILETK");
		output("LPARENT");
		digui20();
		output("RPARENT");
		digui17();
	}
	else if(words[q]=="DOTK")
	{
		output("DOTK");
		digui17();
		output("WHILETK");
		output("LPARENT");
		digui20();
		output("RPARENT");
	}
	else if(words[q]=="FORTK")
	{
		output("FORTK");output("LPARENT");output("IDENFR");output("ASSIGN");digui14();output("SEMICN");
		digui20();output("SEMICN");
		output("IDENFR");output("ASSIGN");output("IDENFR");
		if(words[q]=="PLUS") output("PLUS");
		else if(words[q]=="MINU") output("MINU");
		digui22();
		output("RPARENT");
		digui17();
		
	}
	fout<<"<循环语句>"<<endl;
}
void digui22()
{
	//<步长>::= <无符号整数>  
	digui4();
	fout<<"<步长>"<<endl;
}
void digui234()
{
	//<标识符>'('<值参数表>')'
	int chooseresult=Choose[vlaue[q]];
	output("IDENFR");
	output("LPARENT");
	digui25();
	output("RPARENT");
	if(chooseresult==1) fout<<"<无返回值函数调用语句>"<<endl;
	else fout<<"<有返回值函数调用语句>"<<endl;
}
void digui25()
{
	//<值参数表>   ::= <表达式>{,<表达式>}|<空>
	if(words[q]!="RPARENT")
	{
	
	    digui14();
	    while(words[q]=="COMMA")
	  {
		 output("COMMA");
		 digui14();
	  }
    }
    fout<<"<值参数表>"<<endl;

}
void digui26()
{
	//{<语句>}
	while(words[q]!="RBRACE")
	{
		digui17();
	}
	fout<<"<语句列>"<<endl;

}
void digui27()
{
	//<读语句>    ::=  scanf '('<标识符>{,<标识符>}')'
	output("SCANFTK");
	output("LPARENT");
	output("IDENFR");
	while(words[q]=="COMMA")
	{
		output("COMMA");
		output("IDENFR");
	}
	output("RPARENT");
	fout<<"<读语句>"<<endl;
}
void digui28()
{
	//<写语句>    ::= printf '(' <字符串>,<表达式> ')'
	//| printf '('<字符串> ')'| printf '('<表达式>')'
	output("PRINTFTK");
	output("LPARENT");
	if(words[q]=="STRCON") digui0();
	else digui14();
	if(words[q]=="COMMA") {output("COMMA");digui14();}
	output("RPARENT");
	fout<<"<写语句>"<<endl;
}
void digui29()
{
	//<返回语句>   ::=  return['('<表达式>')']   
	output("RETURNTK");
	if(words[q]=="LPARENT")
	{
		output("LPARENT");
		digui14();
		output("RPARENT");
	}
	fout<<"<返回语句>"<<endl;
}

int main()
{
    FILE *fpin=fopen("testfile.txt","r");
    if(NULL==fpin) cout<<"false"<<endl;
    analyse(fpin);
    string_analyse();
    fclose(fpin);
    
    return 0;
}

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值