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

📄 frmmain.cs

📁 这是一个完整的文法分析器
💻 CS
📖 第 1 页 / 共 4 页
字号:
			listboxProducts.Items.Add(textboxInput.Text);
		}

		#endregion

		#region 加载符合集合

		private void btnLoadSymbols_Click(object sender, System.EventArgs e)
		{
			textboxNotEndall.ReadOnly=true;
			textboxEndall.ReadOnly=true;

			SymbolSet.getInstance().EndallSet.Clear();
			SymbolSet.getInstance().NotEndallSet.Clear();

			ofiledlg.ShowDialog();

			if (File.Exists(ofiledlg.FileName))
			{
				try 
				{
					using (StreamReader sr = new StreamReader(ofiledlg.FileName)) 
					{
						String strTaskItem;
						if(sr.ReadLine() !="NotEndall") return;
						textboxNotEndall.Text="";
						textboxEndall.Text="";
						bool notend=true;
						while ((strTaskItem = sr.ReadLine()) != null) 
						{
							if(strTaskItem=="Endall")
								notend=false;
							else if (notend && strTaskItem!="")
							{
								textboxNotEndall.AppendText(strTaskItem + "\r\n" );
								SymbolSet.getInstance().NotEndallSet.Add(strTaskItem);
							}
							else if (strTaskItem!="")
							{
								textboxEndall.AppendText(strTaskItem + "\r\n");
								SymbolSet.getInstance().EndallSet.Add(strTaskItem);
							}
						}


						sr.Close();
					}
				}
				catch (Exception ee) 
				{
					Console.WriteLine("The file could not be read:");
					Console.WriteLine(ee.Message);
				}
			}
		}


		#endregion 
		
		#region 编辑符号集
		
		private void btnEditSymbols_Click(object sender, System.EventArgs e)
		{
			textboxNotEndall.ReadOnly=false;
			textboxEndall.ReadOnly=false;
		}

		#endregion
		
		#region 初始化符合集
		
		private void btnOKSymbols_Click(object sender, System.EventArgs e)
		{
			textboxNotEndall.ReadOnly=true;
			textboxEndall.ReadOnly=true;

			SymbolSet.getInstance().EndallSet.Clear();
			SymbolSet.getInstance().NotEndallSet.Clear();
			Console.WriteLine("NotEndall");
			for(int i=0; i<textboxNotEndall.Lines.Length ; i++ )
			{

				if (textboxNotEndall.Lines[i]!="")
				{
					SymbolSet.getInstance().NotEndallSet.Add(textboxNotEndall.Lines[i]);
					Console.WriteLine(textboxNotEndall.Lines[i]);
				
				}
			}
			Console.WriteLine("Endall");
			for(int i=0; i<textboxEndall.Lines.Length ; i++ )
			{
				if (textboxEndall.Lines[i]!="")
				{
					SymbolSet.getInstance().EndallSet.Add(textboxEndall.Lines[i]);
					Console.WriteLine(textboxEndall.Lines[i]);
				}
			}
		}


		#endregion

		#region 保存符合集

		private void btnSaveSymbols_Click(object sender, System.EventArgs e)
		{
			sfiledlg.Filter="(*.txt)|*.txt|*.*|*.*";
			sfiledlg.ShowDialog();
			if(sfiledlg.FileName!="")
			{
				using (StreamWriter sw = new StreamWriter(sfiledlg.FileName)) 
				{
					sw.WriteLine("NotEndall");
					sw.WriteLine(textboxNotEndall.Text);
					sw.WriteLine("Endall");
					sw.WriteLine(textboxEndall.Text);
					
					sw.Close();
				}//using
			}
		}


		#endregion

		#region 辅助输入“→”

		private void btnTuichu_Click(object sender, System.EventArgs e)
		{
			textboxInput.AppendText("→");
		}

		#endregion

		#region 删除选中的表达式

		private void btnDeleltProduct_Click(object sender, System.EventArgs e)
		{
			listboxProducts.Items.RemoveAt(listboxProducts.SelectedIndex);
		}

		#endregion

		#region 加载表达式列表
		private void btnLoadProducts_Click(object sender, System.EventArgs e)
		{
			ofiledlg.ShowDialog();
			if (File.Exists(ofiledlg.FileName))
			{
				try 
				{
					using (StreamReader sr = new StreamReader(ofiledlg.FileName)) 
					{
						String strTaskItem;
						if(sr.ReadLine() !="Products") return;
						listboxProducts.Items.Clear();
						while ((strTaskItem = sr.ReadLine()) != null) 
						{
							
							if(strTaskItem.IndexOf("→")>0)
							{
								listboxProducts.Items.Add(strTaskItem);
								Console.WriteLine(strTaskItem);
							}
							else
							{
								listboxProducts.Items.Add(strTaskItem.Substring(0,1) + "→" + strTaskItem.Substring(1));
								Console.WriteLine(strTaskItem.Substring(0,1) + "→" + strTaskItem.Substring(1));
							}

						}
						sr.Close();
					}
				}
				catch (Exception ee) 
				{
					Console.WriteLine("The file could not be read:");
					Console.WriteLine(ee.Message);
				}
			}
		}

		#endregion

		#region 保存表达式列表

		private void btnSaveProducts_Click(object sender, System.EventArgs e)
		{
			sfiledlg.Filter="(*.txt)|*.txt|*.*|*.*";
			sfiledlg.ShowDialog();
			if(sfiledlg.FileName!="")
			{
				using (StreamWriter sw = new StreamWriter(sfiledlg.FileName)) 
				{
					sw.WriteLine("Products");
					for(int i=0 ; i<listboxProducts.Items.Count ; i++)
					{
						sw.WriteLine(listboxProducts.Items[i].ToString());
					}//for
					sw.Close();
			
				}

				


			}
		}


		#endregion

		#region 检测按钮 开始计算

		private void btnCheckString_Click(object sender, System.EventArgs e)
		{
			//构造产生式集
			CreatProductsSet();
			//计算FIRST集
			ArrayList ArrayFirst=FirstSet();
			outFirst(ArrayFirst);
			//计算FOLLOW集,需要传入FIRST集
			ArrayList ArrayFollow=FollowSet(ArrayFirst);
			outFollow(ArrayFollow);
			//计算SELECT集
			ArrayList ArraySellect=this.SelectSet(ArrayFirst,ArrayFollow);
			outSellect(ArraySellect);
			//构建预测分析表
			Hashtable HashAnalysis=this.BuildAnalysis(ArraySellect);
			outAnalysis(HashAnalysis);

			//输出结果
			OutResult(ArrayFirst,ArrayFollow,ArraySellect,HashAnalysis);

			Console.WriteLine(IsLL1(ArraySellect));
			//Console.WriteLine(this.CheckEmptySymbol("L")+ "\t阿斯蒂芬");
		}

		#endregion

		#region 计算前的准备工作

		#region 构造产生式集 统计使用到的终结符和非终结符

		private void CreatProductsSet()
		{
			LeftItem.Clear();
			emptyList.Clear();
			//用于记录出现的非终结符和终结符
			NotEndSet.Clear();
			EndSet.Clear();
		
			string strLeftItem="";
			ArrayList arylistRight= new ArrayList();
			if (listboxProducts.Items.Count<2) 
			{
				return;		
			}
			for(int i=0 ; i < listboxProducts.Items.Count ; i++)
			{
				//首先扫描记录能够推导出空串的非终结符
				if(listboxProducts.Items[i].ToString().Substring(2,1)=="$")
				{
					emptyList.Add(listboxProducts.Items[i].ToString().Substring(0,1));
				}

				if(strLeftItem.Length==0)
				{
					strLeftItem=getProductLeft(i);
					arylistRight.Add(getProductRight(i));
				}
				else if (strLeftItem==getProductLeft(i))
				{
					arylistRight.Add(getProductRight(i));
				}
				else
				{
					Product product=new Product(strLeftItem,arylistRight);
					LeftItem.Add(product);

					strLeftItem="";
					arylistRight=new ArrayList();
					//
					strLeftItem=getProductLeft(i);
					arylistRight.Add(getProductRight(i));
					//

					Console.WriteLine(product.ToString() + i);
				}
				//防止丢失最后一个表达式
				if( i== listboxProducts.Items.Count-1)
				{
					Product product=new Product(strLeftItem,arylistRight);
					LeftItem.Add(product);

					Console.WriteLine(product.ToString() + i);
				}

				//统计出现的终结符&非终结符
				string strSymbols=this.listboxProducts.Items[i].ToString().Replace("→","");

				for(int j=0 ; j<strSymbols.Length ; j++ )
				{
					//依次取出每一个字符然后统计
					string strSymbolsChar=strSymbols.Substring(j,1);
					if(SymbolSet.getInstance().IsInNotEndSet(strSymbolsChar) && !Tools.IsInList(strSymbolsChar,NotEndSet))
						this.NotEndSet.Add(strSymbolsChar);
					else if (SymbolSet.getInstance().IsInEndSet(strSymbolsChar) && !Tools.IsInList(strSymbolsChar,EndSet))
						this.EndSet.Add(strSymbolsChar);
				}

			}
			//最后终结符集还要加入"#"符号用于构建预测分析表
			this.EndSet.Add("#");

			//继续检测能够推导出空串的
			for(int i=0 ; i < LeftItem.Count ; i++)
			{
				string strFirstChar=((Product)LeftItem[i]).LeftItem;
				if( CheckEmptySymbol(strFirstChar) &&  !Tools.IsInList(strFirstChar,emptyList))
					emptyList.Add(strFirstChar);
			}
		}

		#endregion
		
		#region 返回列表中第i个表达式的左部

		public string getProductLeft(int index)
		{
			if (listboxProducts.Items.Count<=index) return "";
			else
				return listboxProducts.Items[index].ToString().Substring(0,1);
 
		}

		#endregion

		#region 返回列表中第i个表达式的右部
		public string getProductRight(int index)
		{
			if (listboxProducts.Items.Count<=index) return "";
			else
				return listboxProducts.Items[index].ToString().Substring(2);
 
		}
		#endregion

		#endregion

		#region 主要步骤
		
		#region 得到FIRST集
		/// <summary>
		/// 得到FIRST集
		/// </summary>
		/// <returns>ArrayList</returns>
		public ArrayList FirstSet()
		{
			ArrayList [] lstFirst = new ArrayList[LeftItem.Count];
			ArrayList lstItems = new ArrayList();

			Queue queueFirst=new Queue();

			for(int i=0 ; i< LeftItem.Count ; i++ )
			{
				lstFirst[i]=new ArrayList();
				Product product=(Product)LeftItem[i];
				//分成四步求FIRST集式 SELECT集 

				//1.如果 X 属于VT 则FIREST(X)={X}
				if(SymbolSet.getInstance().IsInEndSet(product.LeftItem))
				{
					lstFirst[i].Add(product.LeftItem);
				}	
				else 
				{
					lstFirst[i]=new ArrayList();
					//以此检测每一个右部
					for(int j=0 ; j<product.RightItems.Count ; j++ )
					{
						//2.如果 X 属于VN 且有产生式 X->a...,a属于VT,则 a 属于 FIREST(X)
						string strFirstLetter=product.StringRightItemAt(j).Substring(0,1);
						if(SymbolSet.getInstance().IsInEndSet(strFirstLetter))
						{	
							if(!Tools.IsInList(strFirstLetter,lstFirst[i]))
								lstFirst[i].Add(strFirstLetter);
							//Console.Write(strFirstLetter + " x ");
						}
						//3.如果 X 推出 $ ,则 $ 属于 FIRST(X)
						if(Tools.IsInList(product.LeftItem,emptyList))
						{
							if(!Tools.IsInList("$",lstFirst[i]))
							{
								lstFirst[i].Add("$");
								//if(i==1)Console.WriteLine("bbbbbbbbb");
								//Console.Write("$ 0 ");
							}
						}
							
						//4.如果产生式的右部的每一个字符都是非终结符集
						if(product.CheckRightItemAt(j))
						{
							string strRightTemp=product.StringRightItemAt(j);
							if(CheckEmptySymbol(strRightTemp.Substring(0,1)))
							{
								for(int l=0 ; l<strRightTemp.Length ; l++ )
								{
									bool bNext=true;
									if(CheckEmptySymbol(strRightTemp.Substring(l,1)) && bNext)
									{
										string strQueueElement="";
										if(l==strRightTemp.Length-1)
										{
											strQueueElement=product.LeftItem + product.StringRightItemAt(j).Substring(l,1);
											//Console
										}
										else
											strQueueElement=product.LeftItem + product.StringRightItemAt(j).Substring(l,1) + "$";

										if(!Tools.IsInQueue(strQueueElement,queueFirst))
										{
											queueFirst.Enqueue(strQueueElement);
											Console.WriteLine(strQueueElement + "\txp");
										}
									}
									else
									{
										bNext=false;
										string strQueueElement=product.LeftItem + product.StringRightItemAt(j).Substring(l,1);
										if(!Tools.IsInQueue(strQueueElement,queueFirst))
										{
											queueFirst.Enqueue(strQueueElement);
											Console.WriteLine(strQueueElement + "\txp");
										}
									}
								}
							}
							else
							{
								string strQueueElement=product.LeftItem + product.StringRightItemAt(j).Substring(0,1);
								if(!Tools.IsInQueue(strQueueElement,queueFirst))queueFirst.Enqueue(strQueueElement);
								Console.WriteLine(strQueueElement+ "\txp");
							}
						}
						else
						{
							//假如产生式的右部并非都是非终结符
							//那么取出第一个字符,假如是终结符,那么在上面的第2步里就已经计算过了,所以不用再计算
							//假如是非终结符就假如到待取队列
							if(SymbolSet.getInstance().IsInNotEndSet(product.StringRightItemAt(j).Substring(0,1)))
							{
								string strQueueElement=product.LeftItem + product.StringRightItemAt(j).Substring(0,1);
								if(!Tools.IsInQueue(strQueueElement,queueFirst))queueFirst.Enqueue(strQueueElement);
								Console.WriteLine(strQueueElement + "\txp");
							}
							
						}
							
					}//end for j
					
				}//end if  IsInEndSet(X)
			}//end for i
			lstItems=FinishFirst(lstFirst,queueFirst);
			return lstItems;
		}

		#endregion

⌨️ 快捷键说明

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