📄 frmmain.cs
字号:
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 + -