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

📄 ll_1.cpp

📁 LL_1文法分析 个人感觉不怎么好用 大家一起来看看
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// ***************************************************************
//  LL_1.CPP  version:  1.0   谢伟纯 05软件工程 date: 05/22/2008
//  -------------------------------------------------------------
//  程序名:LL(1) 语法分析程序 
//  -------------------------------------------------------------
//  Copyright (C) 2008 - All Rights Reserved
// ***************************************************************
// 说明:本程序可对用户输入的合法(无多余规则,无递归产生式)文法,
// 进行是否为LL(1)文法判断,并生成相应的文法预测分析表。在分析表产
// 生后,用户可输入要分析的字符串,进行分析。
// ***************************************************************

#include <iostream>
#include <string>
#include <conio.h> 
#include <stdio.h>
using namespace std;

//////////////////////////////////////////////////////////////////////////
//全局变量字典{

int i = 0, j = 0, t = 0, n = 0, m = 0, x = 0, y = 0;  //下标或临时变量
int len = 0;  //字符串长度
int isENum = 0;  //能推出e的终结符数量
bool isE = false; //标记是否能推出e
bool isUpdate = false;  //标记是否更新过结果集
bool isSame = false;  //标记是否有相同SELECT结果集
char strTemp[100] = "\0";  //临时字符串 或 要分析的字符串
char cTemp = '\0';  //临时字符

int grammarNum = 0;  //文法数量
char (*grammar)[32];  //文法  grammar[grammarNum][32]
char noEndSign[30];  //非终结符
char endSign[100];  //终结符
char (*grammarTemp)[32];  //临时文法  grammarTemp[grammarNum][32]
char (*isDerivation_e)[2];  //标记非终结符是否推出e数组  isDerivation_e[strlen(noEndSign)][2]
char (*frist)[100];  //每个文法符号的FRIST集  frist[strlen(noEndSign) + strlen(endSign)][100]
char (*bringFrist)[2][100];  //产生式的FRIST集  bringFrist[grammarNum][2][100]
char (*fllow)[100];  //非终结符的FLLOW集  fllow[strlen(noEndSign)][100]
char (*select)[2][100];  //select集  select[grammarNum][2][100]

char construeArray[100];  //分析栈
char bringStr[100];  //推导所用的产生式或匹配字符串
char stepNum[10];  //步聚数
char construeTop = '\0';  //栈顶字符
char strTempTop = '\0';  //剩余输入串头字符

//全局变量字典}
//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////
//输入文法
void InputGrammar()
{
	//初始数据
	do 
	{
		n = 0;  //标记成功赋值的变量数
		fflush(stdin);  //清空输入缓存区
		cout<<"请输入文法数量(1<=n<=20):";
		n = scanf("%d", &grammarNum);
	} while(!n || grammarNum < 1 || grammarNum > 20);
	
 	grammar = new char[grammarNum][32];

	//输入文法字符串
	cout<<"\n"<<"文法输入规则如下:\n\na、大写英文字母表示非终结符。\
		\nb、e表示空产生式。 \
		\nc、除大写字母、#、'、| 外的单字符表示终结符。\
		\nd、不能出现递归文法。(如 S->S或S->A, A->S;)\
		\ne、不能出现多余文法规则。(如 S->A,A不是非终结符;程序不检测)\
		\nf、文法产生式长度不超过10个字符。(程序不检测)"<<"\n"<<endl;
	
	for (i = 0; i < grammarNum; ++i)
	{
		cout<<i+1<<" ";
		
		//输入文法左部
		strTemp[0] = getch();
		if ( strTemp[0] >= 'A' && strTemp[0] <= 'Z')
		{
			grammar[i][0] = strTemp[0];
			cout<<grammar[i][0]<<"->";
		}
		else
		{
			cout<<"请输入非终结符!"<<endl;
			--i;
			continue;
		}
		
		//输入文法右部
		cin>>strTemp;
		for (j = 0; j < strlen(strTemp); ++j)
		{
			grammar[i][j+1] = strTemp[j];
		}
		grammar[i][++j] = '\0';
		
		//检测文法合法性
		len = strlen(grammar[i]);
		for (j = 1; j < len; ++j)
		{
			//是否为空串
			if (j == 1 && grammar[i][j] == 'e' && grammar[i][j+1] == '\0')
			{
				continue;
			}
			
			if(grammar[i][j] == '#' || grammar[i][j] == '|' || grammar[i][j] == 'e' || grammar[i][j] == '\'')
			{
				cout<<"产生式含有非法字符,请重新输入:"<<endl;
				--i;
				break;
			}
		}
		
		//检测递归产生式
		for(j=1; j<len; ++j)
		{
			if (grammar[i][0] != grammar[i][j])
			{
				break;
			}
		}
		if (j == len)
		{
			cout<<"文法存在递归产生式,请重新输入:"<<endl;
			--i;
		}
	}
	cout<<'\n'<<endl;
	
	//显示文法
	cout<<"你输入的文法是:"<<'\n'<<endl;
	for (i = 0; i < grammarNum; ++i)
	{
		cout<<i+1<<" "<<grammar[i][0]<<"->";
		for (j = 1; j < strlen(grammar[i]); ++j)
		{
			cout<<grammar[i][j];
		}
		cout<<endl;
	}
	cout<<endl;
}

//////////////////////////////////////////////////////////////////////////
//获取,显示终结符和非终结符
void Count_noEndSign_endSign()
{
	//初始数据
	strcpy(noEndSign, "\0");
	strcpy(endSign, "\0");
	
	for (i = 0; i < grammarNum ; ++i)
	{
		//非终结符判断
		if (!strchr(noEndSign, grammar[i][0]))
		{
			len = strlen(noEndSign);
			noEndSign[len] = grammar[i][0];
			noEndSign[len+1] = '\0';
		}
		
		//终结符判断
		for (j = 1, m = 0; j < strlen(grammar[i]); ++j)
		{
			if (!strchr(endSign, grammar[i][j]) && (grammar[i][j] < 'A' || grammar[i][j] > 'Z') && grammar[i][j] != 'e')
			{
				len = strlen(endSign);
				endSign[len] = grammar[i][j];
				endSign[len+1] = '\0';
			}
		}
	}
	
	//显示终结符和非终结符
	n = 0;
	cout<<"非终结符是:";
	while (noEndSign[n] != '\0')
	{
		cout<<noEndSign[n++]<<" ";
	}
	cout<<endl;
	n = 0;
	cout<<"终结符是:";
	while (endSign[n] != '\0')
	{
		cout<<endSign[n++]<<" ";
	}
	cout<<'\n'<<endl;
}

//////////////////////////////////////////////////////////////////////////
//求出能推出e的非终结符
void Count_isDerivation_e()
{
	//初始数据
	grammarTemp = new char[grammarNum][32];
	for (i = 0; i < grammarNum; ++i)
	{
	   strcpy(grammarTemp[i], grammar[i]);
	}

	isDerivation_e = new char[strlen(noEndSign)][2];

	//1、初始标记数组,全部设为'2'('0'表示不能推出e,'1'表示能推出e,'2'表示未定)
	for (i = 0; i < len; ++i)
	{
		isDerivation_e[i][0] = noEndSign[i];
		isDerivation_e[i][1] = '2';
	}
	
	//2、扫描文法中的产生式
	for (i = 0; i < grammarNum; ++i)
	{
		//是否推出e的非终结符
		if (grammarTemp[i][1] == 'e')
		{
			for (j = 0; j < strlen(noEndSign); ++j)
			{
				if (isDerivation_e[j][0] == grammarTemp[i][0])
				{
					isDerivation_e[j][1] = '1';
				}
			}
			continue;
		}

		//是否含有终结符
		len = strlen(grammarTemp[i]);
		for (j = 1; j < len; ++j)
		{
			if (strchr(endSign, grammarTemp[i][j]))
			{
				grammarTemp[i][0] = '\0';
				break;
			}
		}
	}

	//标记不能推出e的非终结符
	for (i=0; i<strlen(noEndSign); ++i)
	{
		for (j=0; j<grammarNum; ++j)
		{
			if (isDerivation_e[i][0] == grammarTemp[j][0])
			{
				break;
			}
		}
		if (j == grammarNum)
		{
			isDerivation_e[i][1] = '0';
		}
	}

	//3、扫描产生式右部的每一符号
	//是
	do 
	{
		isUpdate = false;  //标记此次操作是否有更新过数据

		for (i=0; i<grammarNum; ++i)
		{
			for (j=1; j<strlen(grammarTemp[i]); ++j)
			{
				if (strchr(noEndSign, grammarTemp[i][j]))
				{
					for (t=0; t<strlen(noEndSign); ++t)
					{
						if (isDerivation_e[t][0] == grammarTemp[i][j] && isDerivation_e[t][1] == '1')
						{
							grammarTemp[i][j] = 32;
						}
					}
				}
			}
		}
		for (i=0; i<strlen(noEndSign); ++i)
		{
			for (j=0; j<grammarNum; ++j)
			{
				if (isDerivation_e[i][0] == grammarTemp[j][0])
				{
					for (t=1; t<strlen(grammarTemp[j]); ++t)
					{
						if (grammarTemp[j][t] != 32)
						{
							break;
						}
					}
					if (t == strlen(grammarTemp[j]))
					{
						isDerivation_e[i][1] = '1';
						isUpdate = true;
						//删除该非终结符在左部的所有产生式
						for (n=0; n<grammarNum; ++n)
						{
							if (grammarTemp[j][0] == grammarTemp[n][0] && j!= n)
							{
								grammarTemp[n][0] = '\0';
							}
						}
						grammarTemp[j][0] = '\0';
					}
				}
			}
		}
		
		//否
		for (i=0; i<grammarNum; ++i)
		{
			for (j=1; j<strlen(grammarTemp[i]); ++j)
			{
				if (strchr(noEndSign, grammarTemp[i][j]))
				{
					for (t=0; t<strlen(noEndSign); ++t)
					{
						if (isDerivation_e[t][0] == grammarTemp[i][j] && isDerivation_e[t][1] == '0')
						{
							grammarTemp[i][0] = '\0';
						}
					}
				}
			}
		}
		for (i=0; i<strlen(noEndSign); ++i)
		{
			if (isDerivation_e[i][1] != '2')
			{
				continue;
			}
			for (j=0; j<grammarNum; ++j)
			{
				if (isDerivation_e[i][0] ==grammarTemp[j][0])
				{
					break;
				}
			}
			if (j == grammarNum)
			{
				isDerivation_e[i][1] = '0';
				isUpdate = true;
			}
		}
		
	} while(isUpdate);

	//显示结果
	cout<<"非终结符能否推导出e的表"<<endl;
	cout<<"------------------------------------------------------------------"<<endl;
	for (i=0; i<strlen(noEndSign); ++i)
	{
		cout<<"  "<<isDerivation_e[i][0]<<" ";
	}
	cout<<"\n"<<endl;
	for (i=0; i<strlen(noEndSign); ++i)
	{
		switch(isDerivation_e[i][1])
		{
		case '0':
			cout<<" 否 ";
			break;
		case '1':
			cout<<" 是 ";
			break;
		default:
		    break;
		}
	}
	cout<<"\n"<<"------------------------------------------------------------------"<<endl;
	cout<<endl;
}

//////////////////////////////////////////////////////////////////////////
//计算FRIST集
void Count_Frist()
{
	//初始数据
	len = strlen(noEndSign) + strlen(endSign);
	frist = new char[len][100];  

	n = 0;
	for (i=0; i<strlen(noEndSign); ++i)
	{
		frist[n][0] = noEndSign[i];
		frist[n++][1] = '\0';
	}
	for (i=0; i<strlen(endSign); ++i)
	{
		frist[n][0] = endSign[i];
		frist[n++][1] = '\0';
	}

	//计算每个符号的FRIST集
	
	//1、属于终结符情况
	for (i=0; i<len; ++i)
	{
		if (strchr(endSign, frist[i][0]))
		{
			frist[i][1] = frist[i][0];
			frist[i][2] = '\0';
		}
	}

	//2、属于非终结符,产生式首字符为终结符
	for (i=0; i<strlen(noEndSign); ++i)  //遍历非终结符的FRIST集frist[i][0]
	{
		for (j=0; j<grammarNum; ++j)  //遍历文法grammar[j][0]
		{
			if (frist[i][0] == grammar[j][0] && strchr(endSign, grammar[j][1]))
			{
				len = strlen(frist[i]);
				frist[i][len] = grammar[j][1];
				frist[i][len+1] = '\0';
			} 
		}
	}

	//3、能推出e的非终结符
	for (i=0; i<strlen(noEndSign); ++i)  //遍历非终结符的FRIST集frist[i][0]
	{
		for (j=0; j<strlen(noEndSign); ++j)  //遍历能否推出e情况表
		{
			if (frist[i][0] == isDerivation_e[j][0] && isDerivation_e[j][1] == '1' && !strchr(frist[i], 'e'))
			{
				len = strlen(frist[i]);
				frist[i][len] = 'e';
				frist[i][len+1] = '\0';
				break;
			}
		}
	}
	
	//4、5、产生中的非终结符能推出e的情况处理
	do 
	{
		isE = true;
		isENum = 0;
		isUpdate = false;
	
		for (i=0; i<strlen(noEndSign); ++i)  //遍历frist[i]
		{
			for (j=0; j<grammarNum; ++j)  //遍历grammar[j]
			{
				if (frist[i][0] == grammar[j][0])
				{
					for (t=1; t<strlen(grammar[j]); ++t)  //遍历grammar[j][t]
					{
						//是否为非终结符
						if (strchr(endSign, grammar[j][t]))
						{
							break;
						}
	
						//判断是否能推出e
						for (n=0; n<strlen(noEndSign); ++n)  //遍历isDerivation_e[n]
						{
							if (grammar[j][t] == isDerivation_e[n][0])
							{
								if (isDerivation_e[n][1] == '1')
								{
									++isENum;
									break;
								}
								else
								{
									isE = false;
									break;
								}
							}
						}
	
						if (isE == 0)
						{
							isE = true;
							break;
						}
					}  
	
					//判断产生式中字符的推出e数量,并处理
					len = strlen(grammar[j]);
	
					//前部分能推出e
					if (isENum != len -1)
					{
						for (t=1; t<=isENum+1; ++t)  //遍历grammar[j][t]
						{
							for (n=0; n<strlen(noEndSign); ++n)  //遍历frist[n]
							{
								if (grammar[j][t] == frist[n][0])
								{
									for (m=1; m<strlen(frist[n]); ++m)  //遍历frist[n][m]
									{
										if (t != isENum+1)
										{
											if (!strchr(frist[i], frist[n][m]) && frist[n][m] != 'e')
											{
												x = strlen(frist[i]);
												frist[i][x] = frist[n][m];
												frist[i][x+1] = '\0';
	
												isUpdate = true;
											}
										}
										else
										{
											if (!strchr(frist[i], frist[n][m]))
											{
												x = strlen(frist[i]);
												frist[i][x] = frist[n][m];
												frist[i][x+1] = '\0';
	
												isUpdate = true;
											}
										}							
									}
								}
							}
						}
					}
	
					//全部都能推出e
					if (isENum == len - 1)
					{
						for (t=1; t<=isENum+1; ++t)  //遍历grammar[j][t]
						{
							for (n=0; n<strlen(noEndSign); ++n)  //遍历frist[n]
							{
								if (grammar[j][t] == frist[n][0])
								{
									for (m=1; m<strlen(frist[n]); ++m)  //遍历frist[n][m]
									{
										if (!strchr(frist[i], frist[n][m]))
										{
											x = strlen(frist[i]);
											frist[i][x] = frist[n][m];
											frist[i][x+1] = '\0';
	
											isUpdate = true;
										}
									}
								}
							}
						}
	
						//并e
						if (!strchr(frist[i], 'e'))
						{
							x = strlen(frist[i]);
							frist[i][x] = frist[n][m];
							frist[i][x+1] = '\0';
							
							isUpdate = true;
						}
					}
				}
	
				isENum = 0;
				}
		}
	} while(isUpdate);
		
	//求字符串FRIST集

	//初始数组
	bringFrist = new char[grammarNum][2][100];
	
	for (i=0; i<grammarNum; ++i)
	{
		bringFrist[i][0][0] = '\0';
		for (j=1; j<strlen(grammar[i]); ++j)
		{
			len = strlen(bringFrist[i][0]);
			bringFrist[i][0][len] = grammar[i][j];
			bringFrist[i][0][len+1] = '\0';
		}
	}

	for (i=0; i<grammarNum; ++i)
	{
		strcpy(bringFrist[i][1], "\0");
	}

	//产生式首字符能否推出e情况处理
	for (i=0; i<grammarNum; ++i)
	{
		isENum = 0;
		len = strlen(noEndSign);
		for (j=0; j<len; ++j)
		{
			if (bringFrist[i][0][0] == isDerivation_e[j][0] && isDerivation_e[j][1] == '1')
			{
				isENum = 1;
				break;
			}
		}
		if (1 == isENum)
		{
			for (j=1; j<strlen(bringFrist[i][0]); ++j)  //遍历产生式字符
			{
				for (t=0; t<strlen(noEndSign); ++t)  //判断是否能推出e
				{
					if (bringFrist[i][0][j] == isDerivation_e[t][0] && isDerivation_e[t][1] == '1')
					{
						++isENum;
					}
				}
				if (t == strlen(noEndSign))
				{
					break;
				}
			}

			//产生式全部字符能推出e
			if (isENum == strlen(bringFrist[i][0]))
			{
				for (j=0; j<strlen(bringFrist[i][0]); ++j)  //遍历产生式
				{
					for (t=0; t<strlen(noEndSign); ++t)  //遍历FRIST集
					{
						if (bringFrist[i][0][j] == frist[t][0])  //是否为非终结符的FRIST集
						{
							for (m=1; m<strlen(frist[t]); ++m)  //遍历FRIST集
							{
								if (!strchr(bringFrist[i][1], frist[t][m]))
								{
									len = strlen(bringFrist[i][1]);

⌨️ 快捷键说明

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