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

📄 yufayuyi.cpp

📁 基本实现基于LL(1)法的语法及语义分析程序设计
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//基于LL(1)法的条件语句语法语义分析程序 
#include<iostream.h>
#include<fstream.h>
#include<string.h>
#include<iomanip.h>
#include<malloc.h>

enum keyword{ $right_paren,$left_paren,$mul,$div,$add,$sub,$fenhao,
              $equal,$IF,$THEN,$ELSE,$greater,$less,$id,$num,$end};

typedef struct Token
{
	keyword type;
	char ch;
}Token;

typedef enum{JUMP,JG,JL,equal,END,add,mul,sub,div}OpKind;
typedef struct
{
	int label;               //标号
	OpKind op;               //操作符
	char par1,par2;          //操作数
	union
	{
		char result;         //结果
		int address;         //地址
	};
}Quad;                       //四元式入口

#define MAX_TOKEN 256        //Token表大小
#define MAX_QUAD 256         //四元式数组大小

Token tokentable[MAX_TOKEN];
Quad quad[MAX_QUAD];
int token_index;             //token表索引
int total_len;               //token表有效长度

int quad_len;                //四元式表有效长度
int quad_index;              //四元式索引
Token cur;
Token queue[10];
int label,k,one;             //标记接口
char curchar;                //存储当前待比较字符
char curtocmp;               //存储当前栈顶字符


ifstream ins;
int trueadd,falseadd,end;     
int table[5][8]={{1,0,0,0,0,1,0,0},
				{0,1,1,0,0,0,1,1},
				{1,0,0,0,0,1,0,0},
				{0,1,1,1,1,0,1,1},
				{1,0,0,0,0,1,0,0}}; //存储预测分析表,1为有产生式,0为没有
int i,j;
int flag;
struct Lchar
{
	char char_ch;
	struct Lchar *next;
}Lchar,*temp,*top,*base;
int right;            //定义开关项


bool initialize(char filename[255]);
bool accidence();
void print();
void backpath(int,int);
void ERROR();
void sentence();
void boolean();
bool nexttoken();
char newchar();
void push();
char dosome(void);         //算法函数
void pushs(char pchar);    //入栈函数
void pop(void);            //出栈函数
void doforpush(int t);     //根据数组下标计算的值产生式入栈
void changchartoint();     //根据curchar,curtocmp转为数字以判断是否有产生式
void semantic();           //语法语义分析
char LL1();               //LL(1)文法分析
void printQuad();          //输出四元式
void ERROR(char str[20]);
void AD_ADDRESS(int nlabel,OpKind nop,char npar1,char npar2,int naddress);
void AD_RESULT(int nlabel,OpKind nop,char npar1,char npar2, char nresult);


void main()
{   
	cout<<"                                                         "<<endl
	    <<"                                                         "<<endl
        <<"          基于LL(1)法的条件语句语法语义分析程序          "<<endl
	    <<"                                                         "<<endl
        <<"                                                         "<<endl
	    <<"输入待编译文件名:";
	char fname[100];
	cin>>fname;
	if(!initialize(fname))
		return;
	if(!accidence())
		return;
	char ch;
	while(1)
	{
		if(ins.eof())
			break;
		ins>>ch;
	}
	cout<<endl<<"词法分析结果如下:";
	print();
	cout<<endl;
	cout<<"词法分析结束。"<<endl<<endl;
	semantic();          //语法语义分析
	cout<<endl<<"输出四元式:"<<endl;
	printQuad();
	if(right==1)
		cout<<"分析成功"<<endl;
	else
		cout<<"分析失败"<<endl;
	cout<<"语法语义分析结束"<<endl;
}//main

char newchar()
{   char p;
    p=char(k);
	k++;
	return p;	 
}

//文件打开初始化
bool initialize(char filename[100])
{   
	one=0;
	token_index=0;
	total_len=0;
	quad_len=0;
	quad_index=0;
	label=0;
	end=0;
	k=48;
	ins.open(filename,ios::nocreate | ios::in);
	if(ins.fail())
	{
		cout<<"文件打开出错!"<<endl;
		return false;
	}
	return true;
}

//词法分析
bool accidence()
{
	int k=0;
	char buf[16];
	char ch;
	while(1)
	{
		ins>>ch;
		if(ins.fail())
			break;
		while(ch==' ')
		{	ins>>ch;}
		if(ch=='I')
		{
			ins>>buf;
			if(strcmp(buf,"F")==0)
				tokentable[total_len++].type=$IF;
		}
		else if(ch=='T')
		{
			ins>>buf;
			if(strcmp(buf,"HEN")==0)
				tokentable[total_len++].type=$THEN;
		}
		else if(ch=='E')
		{
			ins>>buf;
			if(strcmp(buf,"LSE")==0)
				tokentable[total_len++].type=$ELSE;
		}
		else if(ch=='>')
		{
			tokentable[total_len++].type=$greater;
		}
			else if(ch=='<')
		{
			tokentable[total_len++].type=$less;
		}
		else if(ch=='=')
		{
			tokentable[total_len++].type=$equal;
		}
		else if((ch>='A'&& ch<='Z' )|| (ch>='a' && ch<='z'))
		{
			tokentable[total_len].type=$id;
			tokentable[total_len++].ch=ch;
		}
		else if(ch>='0' && ch<='9')
		{	tokentable[total_len].type=$num;
		    tokentable[total_len++].ch =ch;
		}
		else
		switch (ch)
		{case '+' :
			tokentable[total_len].type=$add;
		    tokentable[total_len++].ch =ch;
	     	break;
		   case '-' :
			tokentable[total_len].type=$sub;
		    tokentable[total_len++].ch =ch;
	    	break;
			 case '/' :  	
			tokentable[total_len].type=$div;
		    tokentable[total_len++].ch =ch;
	    	break;
			 case '*' :
			tokentable[total_len].type=$mul;
		    tokentable[total_len++].ch =ch;
			break;
			 case ';' :
			tokentable[total_len].type=$fenhao;
		    tokentable[total_len++].ch =ch;
			break;
			case '(' :
			tokentable[total_len].type=$left_paren;
		    tokentable[total_len++].ch =ch;
	    	break;
			case ')' :
			tokentable[total_len].type=$right_paren;
		    tokentable[total_len++].ch =ch;
			break;
			 default:cout<<"!"<<endl;		  
		}
	}
	return true;
	
}

//语法语义分析
void semantic()
{   
	if(!nexttoken())
		ERROR("s(0)");
   	cout<<"开始进行语法语义分析:"<<endl 
        <<"所使用的产生式:"<<endl
	    <<"<if语句> -> if E then S else S"<<endl
  	    <<"S->i=E"<<endl
        <<"E->TA"<<endl
        <<"A-> +TA|-TA|e"<<endl
        <<"T->FB"<<endl
        <<"B->*FB|/FB|e"<<endl
        <<"F->M|(E)"<<endl
	    <<"M->id|num"<<endl
	    <<"语法语义分析过程如下:"<<endl;
   	 if(cur.type==$IF)
	{	    
		    boolean();            //分析布尔语句
	     	if(!nexttoken())
			ERROR("S(0)");
			if(cur.type==$THEN)
			{  
				backpath(trueadd,quad_len);	           //回填出口			
				sentence();        //分析语句
				end=quad_len;
                AD_ADDRESS(quad_len,JUMP,'-','-',end); //产生跳转地址的四元式             
				if(cur.type==$ELSE)
				{
					backpath(falseadd,quad_len);
				    sentence();
				    backpath(end,quad_len);   
				}
				else
				ERROR("S(else)");

			}
			else
			{
				ERROR("S(then)");
			}
	}	 
	else
				ERROR("S(if)");
		
	AD_RESULT(quad_len,END,0,0,'-');  //产生数值语句的四元式
}

//读下一单词
bool nexttoken()
{
	if(token_index>=total_len)
		return false;
	if(tokentable[token_index].type==$fenhao)
		token_index++;
	cur.type=tokentable[token_index].type;
	cur.ch=tokentable[token_index].ch;
	token_index++;
	return true;
}

//进队列
void push()
{ one=0;
  while(tokentable[token_index].type!=$fenhao)
  {
	queue[one].type=tokentable[token_index].type;
	queue[one].ch=tokentable[token_index].ch;
	cout<<queue[one].ch;
	token_index++;
	one++;
  }
    queue[one].type=$end;
    queue[one].ch='#';
	cout<<queue[one].ch;
}

//队列下一个字符
void next()
{
 cur.type=queue[one].type;
 cur.ch =queue[one].ch ;
 one++;
 
}

// 分析E->id < id | id > id语句
void boolean()
{  
 	char a,b;
	int c;	
    if(!nexttoken())
	ERROR("E(0)");
	if(cur.type==$id||cur.type==$num)
	{
		a=cur.ch;
		if(!nexttoken())
			ERROR("E(0)");
	 if(cur.type==$greater||cur.type==$less)
	 {	
		  c=cur.type ;		
		if(!nexttoken())
		 ERROR("E(0)");
		if(cur.type==$id||cur.type==$num)   
			b=cur.ch;
		else
		    ERROR("E(id/num)");
        if(c==$greater)
		{
	     trueadd=quad_len-1;
		 falseadd=quad_len;
		 AD_ADDRESS(quad_len,JG,a,b,trueadd);
		 AD_ADDRESS(quad_len,JUMP,0,0,falseadd);
        }
		else
		{
		 trueadd=quad_len;
		 falseadd=quad_len+1;

⌨️ 快捷键说明

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