亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? 預測分析.cpp

?? 編譯原理 :預測分析
?? CPP
字號:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
//===========================================================================================
typedef struct{
	char formule[6][15];			//用于存放產生式,從0到6對應+,*,(,),i,#;
	char word;						//用于存放非終結符
}Table;

typedef struct{						//定義棧(符號棧)
	char elem[20];					
	int top;
}SeqStack;

//==========================================================================================
char Letter[10];					 //定義全局變量,用來存放產生式里面出現的大寫字母
char LessLetter[10];                 //存放產生式里面出現的終結符                  
int LetterNumber;					//存放非終結符的數目
int LessNumber;                     //存放終結符的數目
int location;                        //存放express數組里的位置
int mark=0;							//作為標志位,mark=0 表示沒有左遞歸 mark=1 表示存在左遞歸
char FIRST[10][15];					//存放非終結符的FIRST集合
char FOLLOW[10][15];				//存放非終結符的FOLLOW集合
int k1=0;
int step=0;                         //記錄預測分析的步驟
SeqStack signStack;					//符號棧
//===========================================================================================
//函數聲明
void Search(char express[][15],char a);
void First(char a[],char express[][15],int i,int s);
void Follow(char express[][15],char a);
//===========================================================================================
void init(char a[][15]){              //對數組進行初始化
	for(int i=0;i<10;i++)
		for(int j=0;j<15;j++)
			a[i][j]='\0';
}

void InitTable(Table analyse[]){		//對預測分析表進行初始化
	int i,j,k;
	for(i=0;i<5;i++)
		for(j=0;j<6;j++)
			for(k=0;k<15;k++){
				analyse[i].word=' ';
				analyse[i].formule[j][k]='\0';
			}
}

void InitSeqStack(){				//對符號棧進行初始化
	int i;
	for(i=0;i<20;i++)
		signStack.elem[i]='\0';
	signStack.top=-1;
}
				
void input(char temp[][15],int number){
	for(int i=0;i<number;i++){
		printf("\n輸入產生式%d:",i+1);
		scanf("%s",temp[i]);
	}
}

void output(char temp[][15],int number){
	for(int i=0;i<number;i++)
		printf("%s\n",temp[i]);
}

bool IsLetter(char a){
	if((a<='Z')&&(a>='A'))
		return true;
	else
		return false;
}

bool judge(char a){					//判斷字母a是否出現在非終結字母表中
	int i;
	for(i=0;i<10;i++)
		if(a==Letter[i])
			return false;
	return true;
}

bool judgement(char a){				//判斷字母a是否出現在終結字母表中
	int i; 
	for(i=0;i<10;i++)
		if(a==LessLetter[i])
			return false;
	return true;
}

void MakeLetter(char temp[][15],int number){				//生成非終結符字母表
	int i,j;
	for(i=0;i<number;i++)
		for(j=0;j<15;j++){
			if(IsLetter(temp[i][j])){
				if(judge(temp[i][j]))
					Letter[LetterNumber++]=temp[i][j];
			}
		}
		Letter[LetterNumber]='\0';
}

void MakeLessLetter(char temp[][15],int number){			//生成終結符字母表
	int i,j;
	for(i=0;i<number;i++)
		for(j=3;j<15;j++){
			if(!IsLetter(temp[i][j])&&temp[i][j]!='|'){
				if(judgement(temp[i][j]))
					LessLetter[LessNumber++]=temp[i][j];
			}
		}
		LessLetter[LessNumber++]='#';
		LessLetter[LessNumber]='\0';
}

char DefineLetter(){						//查看還有哪個大寫字母沒有在字母表中出現
	for(char ch='A';ch<='Z';ch++)
			if(judge(ch)){
				Letter[LetterNumber++]=ch;
				return ch;
			}
	return 'Z';
}

void remove(char temp[],int number,char express[][15]){   //消除左遞歸
	int i,j,r,k,t;
	char ch;
	for(i=0;i<15;i++)
		if(temp[i]=='|'){
			r=i;
			for(j=r+1;j<15;j++)
				if(temp[j]=='|'||temp[j]=='\0'){
					k=j;
					break;
				}
		}
	ch=DefineLetter();
	for(i=0;i<3;i++)
		express[location][i]=temp[i];
	for(t=r+1;t<k;t++)
		express[location][i++]=temp[t];
	express[location][i]=ch;
	location++;
	express[location][0]=ch;
	express[location][1]='-';
	express[location][2]='>';
	i=3;
	for(j=4;j<r;j++)
		express[location][i++]=temp[j];
	express[location][i++]=ch;
	express[location][i++]='|';
	express[location][i++]='@';
	location++;
	
}
		
void manage(char temp[][15],int number,char express[][15]){
	int i,j,t;
	int flag[10];      //作為標志位,flag=0 表示沒有左遞歸 flag=1 表示存在左遞歸
	for(i=0;i<number;i++)
		flag[i]=0;
	for(i=0;i<number;i++)
		for(j=3;j<15;j++){
			if(temp[i][0]==temp[i][j]){
				flag[i]=1;
				mark=1;
				t=j;
				remove(temp[i],number,express);
			}
		}
		for(i=0;i<number;i++){
			if(flag[i]==0){
				for(j=0;j<15;j++)
					express[location][j]=temp[i][j];
				location++;
			}
		}
}

void Search(char express[][15],char a,int j){
	int i;
	for(i=0;i<location;i++)
		if(express[i][0]==a)
			First(express[i],express,i,j);
}

void First(char a[],char express[][15],int i,int s){						//求FIRST集合
	int j,k=0,t;
	if(IsLetter(a[3]))
		Search(express,a[3],s);
	else{
		FIRST[s][k++]=a[3];
		for(j=3;j<15;j++)
			if(a[j]=='|')
				FIRST[s][k++]=a[j+1];
		FIRST[s][k]='\0';
	}
	if(i!=s){										//表示求左遞歸時候進行了遞歸運算,即產生式右邊第一個是非終結符
		for(t=0;t<15;t++)
			if(FIRST[s][t]=='@')
				First(a,express,i,s);
	}
}

void outFIRST(char express[][15]){						//將FIRST集合輸出到屏幕上
	int i,j,k=0;
	printf("\nFIRST集合:\n");
	for(i=0;i<location;i++){
		printf("FIRST(%c)={",express[i][0]);
		for(j=0;j<15;j++)
			if(FIRST[i][j+1]=='\0'){
			printf("%c}\n",FIRST[i][j]);
			break;
			}
			else
				printf("%c,",FIRST[i][j]);
	
	}
}

bool estimate(char a[],char b){					//判斷字母b是否在數組a中
	for(int i=0;i<15;i++)
		if(b==a[i])
			return true;
	return false;
}

void addFollow(int i,int j){						//將FOLLOW[i]加到FOLLOW[j]中
	int a;
	for(a=0;a<15;a++)
		if(!estimate(FOLLOW[j],FOLLOW[i][a]))
			FOLLOW[j][k1++]=FOLLOW[i][a];
}

void Solve(char express[][15],char a[],int p,int j){	
	int i,t,r,temp;
	k1=0;
	if(a[j+1]=='\0'){			//若FOLLOW[p]已經求出,則直接加入到FOLLOW[a[j]]中
		if(FOLLOW[p][0]!='\0'){
			for(int r=0;r<location;r++)
				if(express[r][0]==a[j]){
					temp=r;
					break;
				}
				addFollow(p,temp);
		}
		else
			Follow(express,express[p][0]);			//若FOLLOW[p]還沒有求出,則先求出FOLLOW[p];
	}
	else if(!IsLetter(a[j+1])&&a[j+1]!='|'){
		if(a[j]==express[0][0]){
			k1++;
			FOLLOW[0][k1++]=a[j+1];
		}
		else{
			for(r=0;r<location;r++)
				if(express[r][0]==a[j]){
					FOLLOW[r][k1++]=a[j+1];
					break;
				}
		}
	}
	else if(IsLetter(a[j+1])){
		for(i=0;i<location;i++)
			if(express[i][0]==a[j+1]){
				for(int s=0;s<15;s++){
					if(express[i][s]=='@'&&express[i][s-1]=='|')	//若非終結符能直接推出@
						if(	FOLLOW[i][0]!='\0'){
							for(int r=0;r<location;r++)
								if(express[r][0]==a[j]){
									temp=r;
									break;
								}
							addFollow(i,temp);
						}
						else
							Follow(express,express[i][0]);
				}									          
				for(t=0;t<15;t++)				//將FIRST[a[j+1]]加入到FOLLOW[i]中    
					if(!estimate(FOLLOW[temp],FIRST[i][t]))
						if(FIRST[i][t]!='@')
							FOLLOW[temp][k1++]=FIRST[i][t];
			}
	}

}

void Follow(char express[][15],char a){					//求FOLLOW集合
	int i,j;
	if(a==express[0][0])				//若為開始符號則把#號加入到FOLLOW集合中
		FOLLOW[0][0]='#';
	for(i=0;i<location;i++)
		for(j=3;j<15;j++)
			if(express[i][j]==a&&express[i][0]!=a){
				Solve(express,express[i],i,j);
			}
}

void outFOLLOW(char express[][15]){						//將FIRST集合輸出到屏幕上
	int i,j,k=0;
	printf("\nFOLLOW集合:\n");
	for(i=0;i<location;i++){
		printf("FOLLOW(%c)={",express[i][0]);
		for(j=0;j<15;j++)
			if(FOLLOW[i][j+1]=='\0'){
			printf("%c}\n",FOLLOW[i][j]);
			break;
			}
			else
				printf("%c,",FOLLOW[i][j]);
	
	}
}

bool opinion(char a,int i){							//判斷字母a是否出現在FIRST集合中
	int j;
	for(j=0;j<15;j++)
		if(a==FIRST[i][j])
				return true;
	return false;
}

bool judgeFollow(char a,int i){					//判斷字母a是否出現在FOLLOW集合中
	int j,k;
	for(j=0;j<15;j++)
		if(FIRST[i][j]=='@'){
			for(k=0;k<15;k++)
				if(a==FOLLOW[i][k])
					return true;
		}
	return false;
}
	
int Creat(Table &tab,char express[],int j){					//將產生式放入分析表中
	int i;
	tab.word=express[0];
	for(i=0;i<15;i++)
		if(express[i]=='|')
			if(express[i+1]==LessLetter[j]){
					tab.formule[j][0]=express[0];
					tab.formule[j][1]='-';
					tab.formule[j][2]='>';
					tab.formule[j][3]=LessLetter[j];
					return 1;
				}
	for(i=0;i<15;i++){
		if(express[i]!='|')
			tab.formule[j][i]=express[i];
		else
			break;
	}
	return 0;
}

void CreatTable(Table analyse[],char express[][15]){				//構造預測分析表
	int i,j;
	for(i=0;i<location;i++)
		for(j=0;j<LessNumber;j++)
			if(opinion(LessLetter[j],i))
				Creat(analyse[i],express[i],j);
			else{
				if(judgeFollow(LessLetter[j],i)){
					analyse[i].formule[j][0]=express[i][0];
					analyse[i].formule[j][1]='-';
					analyse[i].formule[j][2]='>';
					analyse[i].formule[j][3]='@';
				}
			}			
}

void outTable(Table analyse[]){				//輸出預測分析表
	int i,j;
	printf("\n預測分析表:\n");
	for(j=0;j<LessNumber;j++)
		printf("\t%c",LessLetter[j]);
	printf("\n");
	for(i=0;i<5;i++){
		printf("%c\t",analyse[i].word);
		for(j=0;j<6;j++)
			printf("%s\t",analyse[i].formule[j]);
		printf("\n");
	}
}

bool judgeStack(char a){				//判斷字母a與符號棧頂元素是否相同
	if(signStack.elem[signStack.top]==a)
		return true;
	return false;
}

int settle(char bunch[],Table analyse[],char express[][15]){
	int i,j,t,s,r;
	int flag=0;
	for(i=0;i<location;i++)
		if(express[i][0]==signStack.elem[signStack.top]){
			j=i;
			break;
		}
	if(judgeStack(bunch[0])&&bunch[0]=='#')			//如果符號棧頂為'#'且輸入串也為'#'號時候結束,分析成功了。
		return 1;
	else if(judgeStack(bunch[0])){					//如果符號棧頂和輸入串第一位相同,則把符號棧的棧頂元素彈出,且輸入串第一位也刪除
		for(i=0;i<10;i++)
			bunch[i-1]=bunch[i];
		signStack.elem[signStack.top]='\0';
		signStack.top--;
		printf("%d\t%s\t%s\t\n",step++,signStack.elem,bunch);
	}
	
	else{
			
			for(t=0;t<LessNumber;t++){
				if(bunch[0]==LessLetter[t]){
					s=t;
					if(analyse[j].formule[s][3]=='@'){					//如果對應的產生式為X->@,則直接把棧頂元素彈出,輸入串不變
							signStack.elem[signStack.top]='\0';
							signStack.top--;
							flag=1;
							break;
						}
					else{
						for(r=15;r>=3;r--){						//找到符號棧頂和輸入串第一位對應的產生式,將產生式右部反序壓入到符號棧中
							if(analyse[j].formule[s][r]!='\0'){
								signStack.elem[signStack.top]=analyse[j].formule[s][r];
								signStack.top++;
							}
						}
					}
					if(flag==0)
						signStack.top--;
					break;
				}
			}
		printf("%d\t%s\t%s\t%s\n",step++,signStack.elem,bunch,analyse[j].formule[s]);
	}
	return 0;
	
}
	
void inputString(char bunch[],Table analyse[],char express[][15]){
	int i,j,k;
	printf("\n句子分析:\n");
	scanf("%s",bunch);
	printf("\n利用預測分析表進行預測分析的步驟如下:\n");
	signStack.top++;
	signStack.elem[signStack.top]='#';			//首先將'3'號壓入符號棧
	signStack.top++;
	signStack.elem[signStack.top]=express[0][0];	//將開始符號壓入棧頂
	printf("步驟\t符號棧\t輸入串\t所用產生式\n");
	printf("%d\t%s\t%s\t\n",step++,signStack.elem,bunch);	//找到開始符號和輸入串第一位對應的產生式,將產生式右部反序壓入到符號棧中
	for(i=0;i<LessNumber;i++){
		if(LessLetter[i]==bunch[0]){
			j=i;
			for(k=15;k>=3;k--)
				if(analyse[0].formule[j][k]!='\0'){
					signStack.elem[signStack.top]=analyse[0].formule[j][k];
					signStack.top++;
				}
		}
	}
	printf("%d\t%s\t%s\t%s\n",step++,signStack.elem,bunch,analyse[0].formule[j]);
	signStack.top--;
	while(signStack.elem[signStack.top]!='#')
		settle(bunch,analyse,express);
	printf("分析成功!\n");
	
}
	
	
int main(){
	char temp[10][15];
	char express[10][15];
	int number;        //記錄文法里面產生式的個數
	int i;
	char bunch[10];		//存放輸入串
	for(i=0;i<10;i++)
		bunch[i]='\0';
	Table analyse[5];		//存放預測分析表
	init(temp);
	init(express);
	init(FIRST);
	init(FOLLOW);
	InitTable(analyse);
	InitSeqStack();

	for(i=0;i<10;i++)
		Letter[i]='\0';
	printf("\n產生式個數:");
	scanf("%d",&number);
	input(temp,number);
	MakeLetter(temp,number);
	MakeLessLetter(temp,number);
	manage(temp,number,express);
	if(mark==1){
		printf("\n存在左遞歸!\n");
		printf("消除左遞歸后:\n");
		output(express,location);
	}
	for(i=0;i<location;i++)
		First(express[i],express,i,i);
	for(i=0;i<location;i++)
		Follow(express,express[i][0]);
	outFIRST(express);
	outFOLLOW(express);
	CreatTable(analyse,express);
	outTable(analyse);
	inputString(bunch,analyse,express);
	return 1;
}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
色综合久久久久综合体桃花网| 日韩理论片中文av| 久久超碰97中文字幕| 日韩欧美在线1卡| 国产在线日韩欧美| 欧美韩日一区二区三区四区| 99久久精品久久久久久清纯| 亚洲欧美日韩综合aⅴ视频| 在线精品视频免费观看| 亚洲r级在线视频| 欧美大片一区二区三区| 国产一区二区在线看| 国产精品久久三区| 国产精品一二三区| 制服丝袜激情欧洲亚洲| 日韩一区二区麻豆国产| 亚洲欧美日韩中文字幕一区二区三区| 中文字幕中文字幕一区二区| 一区二区三区久久久| 日韩黄色小视频| 国产成人精品免费看| 欧美视频中文一区二区三区在线观看| 日韩三级电影网址| 亚洲五码中文字幕| 美腿丝袜亚洲色图| 日韩欧美国产wwwww| 国产成人精品1024| 亚洲伦在线观看| 欧美tickling挠脚心丨vk| 国产精品一卡二| 亚洲国产一区二区三区| xvideos.蜜桃一区二区| aa级大片欧美| 免费高清成人在线| 国产精品国产馆在线真实露脸| 91国在线观看| 国产一区欧美二区| 亚洲成人av免费| 欧美激情综合在线| 欧美一区二区精品在线| av在线综合网| 久久99精品视频| 夜夜操天天操亚洲| 精品国产乱码91久久久久久网站| 成人av网站大全| 免费观看成人鲁鲁鲁鲁鲁视频| 国产精品美女久久久久久久网站| 欧美天堂一区二区三区| 成人av资源在线| 国产麻豆日韩欧美久久| 日韩综合一区二区| 亚洲曰韩产成在线| 国产精品久久久久一区二区三区| 欧美一区在线视频| 日本高清不卡在线观看| 国产精品亚洲成人| 六月婷婷色综合| 亚洲二区在线视频| 亚洲欧洲综合另类| 国产无一区二区| 欧美mv日韩mv国产网站| 欧美色网一区二区| 色一情一乱一乱一91av| 国产精品69久久久久水密桃| 日韩成人免费电影| 亚洲国产精品久久久久秋霞影院 | 久久国产尿小便嘘嘘| 亚洲男同性视频| 激情综合五月婷婷| 国产精品国产三级国产| 日韩欧美aaaaaa| 欧美在线观看一区| 国产成人av一区二区三区在线 | 中文字幕欧美区| 成人免费视频视频在线观看免费| 91免费国产在线观看| 亚洲色欲色欲www| 国产免费久久精品| 国产日产欧产精品推荐色| 精品国产乱码91久久久久久网站| 91精品一区二区三区在线观看| 91福利视频久久久久| 色综合一区二区| 色综合久久久久久久久久久| a级高清视频欧美日韩| 成人h动漫精品一区二区| 成人福利在线看| 不卡高清视频专区| 99久久国产免费看| 色偷偷88欧美精品久久久| 成人动漫一区二区三区| av一区二区不卡| 欧洲精品中文字幕| 欧美日本国产一区| 91精品婷婷国产综合久久性色| 欧美一级电影网站| 精品福利一区二区三区免费视频| 日韩精品一区二区三区中文不卡| 精品精品国产高清a毛片牛牛| 久久久久88色偷偷免费| 亚洲欧洲另类国产综合| 亚洲最大成人综合| 裸体健美xxxx欧美裸体表演| 狠狠色丁香九九婷婷综合五月| 国产在线不卡一区| 91在线云播放| 欧美精品丝袜久久久中文字幕| 日韩欧美在线123| 国产视频一区二区三区在线观看 | 久久99精品国产麻豆婷婷洗澡| 国产一区二区三区在线观看精品 | 欧美中文字幕一区| 91精品国产91久久久久久最新毛片| 精品久久国产97色综合| 国产精品乱码人人做人人爱| 亚洲乱码国产乱码精品精的特点| 亚洲国产成人av| 国产一区二区三区在线观看免费视频 | 日韩av中文字幕一区二区三区| 亚洲成人资源网| 国内精品嫩模私拍在线| 91精品91久久久中77777| 欧美日韩精品一区二区| 欧美白人最猛性xxxxx69交| 久久久影视传媒| 天天综合网 天天综合色| 国产精品一区二区久久不卡| 日韩区在线观看| 欧美成人猛片aaaaaaa| 亚洲欧洲精品一区二区三区| 日韩激情在线观看| 94-欧美-setu| 亚洲精品一区二区三区影院| 亚洲青青青在线视频| 麻豆精品国产传媒mv男同| 日本久久一区二区| 久久综合九色综合久久久精品综合| 亚洲蜜桃精久久久久久久| 久久99国产乱子伦精品免费| 色综合色综合色综合色综合色综合 | 亚洲www啪成人一区二区麻豆| 国产成人免费在线视频| 日韩欧美你懂的| 一个色综合av| 成人精品国产福利| 欧美电影免费观看完整版| 亚洲一二三四在线| 成人激情开心网| 久久久久亚洲蜜桃| 热久久久久久久| 欧美视频一区二区在线观看| 中文字幕日韩一区| 国产精品综合二区| 日韩精品一区二区三区中文精品 | 日韩中文字幕麻豆| 色播五月激情综合网| 国产精品久久久久影院| 国产在线视频一区二区三区| 欧美成人a在线| 蜜桃精品视频在线| 宅男在线国产精品| 日本怡春院一区二区| 欧美日韩一本到| 亚洲一二三四久久| 欧美视频一区在线| 亚洲18色成人| 欧美网站大全在线观看| 亚洲一区在线免费观看| 91久久精品日日躁夜夜躁欧美| 欧美经典三级视频一区二区三区| 国产伦精品一区二区三区视频青涩| 日韩精品一区二区三区在线播放| 免费在线观看一区二区三区| 在线综合视频播放| 美脚の诱脚舐め脚责91 | 夜夜精品视频一区二区| 亚洲精品一区二区三区四区高清| 国产乱一区二区| 国产精品一区在线观看你懂的| xf在线a精品一区二区视频网站| 成人av免费观看| 日本免费在线视频不卡一不卡二| 欧美va亚洲va香蕉在线| 97成人超碰视| 97精品久久久久中文字幕| 日本成人中文字幕| 九九九久久久精品| 国产精品夜夜嗨| 国产精品美女久久久久久久| 成人免费不卡视频| 亚洲欧美一区二区三区国产精品 | 久久亚洲春色中文字幕久久久| 国产精品一区二区久激情瑜伽| 欧美极品aⅴ影院| 色狠狠色噜噜噜综合网| 午夜精品一区二区三区三上悠亚| 欧美一区二区三区系列电影| 激情欧美一区二区| 亚洲国产成人自拍| 欧美视频一区在线|