c# 编译原理Lr0实现(可视化表格)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsLR0Table
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
table.Hide();
}
public struct production
{
public string left;
public string right;
};
public struct action
{
public string left;
public string right;
public string value;
};
public struct item
{
public production[] pp;
public int number;
public int n;
};
string strings;
item[] items = new item[30];
production[] p = new production[20];
production[] allp = new production[20];
action[] act = new action[100];
int inputn;
int itemNum;
char[] tableNum = new char[10];
char[] vn = new char[10];
char[] vt = new char[10];
int vtnum;
int vnnum;
int numNumber;
int rightNumber = 0;
int actNumber = 0;
int sNumber = 0;
void chop(production[] p, int i)
{
int j;
for (j = 0; j < strings.Length; j++)
if (strings[j] == '>')
{
p[i].left = strings.Substring(0, j - 1);
p[i].right = strings.Substring(j + 1, strings.Length - j - 1);
//cout<<"chop"<<endl;
// rtb_get.Text += "\n"+p[i].left +" "+ p[i].right ;
}
}
public void getp()//S->AB,A->Bcd,B->cab,end
{
//rtb_show.Text += "getp\n";
string[] str = rtb_show.Text.Split(',');
for (int i = 0; i < 10; i++)
{
strings = str[i];
if (strings == "end")
{
inputn = i;
break;
}
chop(p, i+1);
}
}
public void addExpendGrame(production[] p)
{
p[0].left = "S'";
p[0].right = p[1].left;
}
public void addpoint(production[] p)
{
//
for(int i=0;i<inputn+1;i++)
{
p[i].right = '.' + p[i].right;
allp[i] = p[i];
}
for(int i=0;i<inputn+1;i++)
{
rtb_show.Text += allp[i].left + "->" + allp[i].right + "\n";
}
}
public int findpoint(string str)
{
for(int i=0;i<str.Length;i++)
{
if(str[i]=='.')
{
return i;
}
}
return -1;
}
private void button3_Click(object sender, EventArgs e)
{
getp();
addExpendGrame(p);
// rtb_show.Text += "\n" + "添加拓广文法完毕";
//rtb_show.Text += "/n" + p[0].left + p[0].right;
addpoint(p);
items[0].pp = new production[20];
creatI0();
// proCloses(items,0);
rtb_show.Text += items[0].number+"\n";
// rtb_show.Text += "\n" + "添加点完毕";
for (int i = 0; i < items[0].number; i++)
{
rtb_show.Text += "\n" +items[0].pp[i].left +items[0].pp[i].right;
}
rtb_show.Text+="\n"+items[0].number;
getVn();
getvt();
getNum();
for(int i=0;i<numNumber;i++)
{
rtb_show.Text += tableNum[i] + "\n";
}
for(int i=0;i<itemNum+1;i++)
{
actionGo(items, i);
}
//proCloses(items, 1);
for(int i=0;i<itemNum;i++)
{
rtb_show.Text += "item" + i + " ";
for(int j=0;j<items[i].number;j++)
{
rtb_show.Text += "\npro " + j + ":"+items[i].pp[j].left+"->"+items[i].pp[j].right;
}
}
for(int i=0;i<actNumber;i++)
{
rtb_show.Text += "\n act" + i + ":(" + act[i].left + "," + act[i].right + ")=" + act[i].value;
}
sNumber = itemNum;
tableInit();
table.Show();
}
public void actionGo(item[] itemsget,int n)
{
int newppnum = 0;
char cup = '1';
for (int v = 0; v < numNumber; v++)//按字符表寻找就可以同时找出相同的条件字符的产生式
{
for (int i = 0; i < itemsget[n].number; i++)
{
int point = findpoint(itemsget[n].pp[i].right);
if (point < itemsget[n].pp[i].right.Length - 1)//如果数组位置不是末尾
{
if (itemsget[n].pp[i].right[point + 1] == tableNum[v])//点后为某字符
{
if (cup != tableNum[v])//根据所求字符是否为同一类决定是否为新项目集
{
if (cup != '1')
proCloses(items, itemNum);//将上一个项目集求闭包,现在的话,上一个项目集应该是完全的,且itemnum未改变
cup = tableNum[v];
itemNum++;//关于某一字符的项目集求得,项目集数量加1
items[itemNum].pp = new production[20];//初始化新项
items[itemNum].number = 0;//初始化项目产生式个数
items[itemNum].n = itemNum;//赋值给项目序号,表行为输出要用来表示。
newppnum = 0;//新项目集的新产生式号
}
items[itemNum].pp[newppnum] = itemsget[n].pp[i];//先给item【n】,再移点
items[itemNum].pp[newppnum].right = itemsget[n].pp[i].right.Substring(0, point) + itemsget[n].pp[i].right.Substring(point + 1, 1) + "." + itemsget[n].pp[i].right.Substring(point + 2);
items[itemNum].number++;
newppnum++;//当前项目集的产生式数目加1
// if (itemsget[n].pp[i].right[point + 1] >= 'a' && itemsget[n].pp[i].right[point + 1] <= 'z')
// {
act[actNumber].left = "s" + itemsget[n].n;//接受项目的
act[actNumber].right = itemsget[n].pp[i].right[point + 1].ToString();//点后一位
act[actNumber].value = "s" + itemNum;
actNumber++;
rtb_show.Text += "\n act go \n";
rtb_show.Text += "所找字符:" + tableNum[v] + " items" + itemNum + "的产生式" + newppnum + ":" + items[itemNum].pp[newppnum - 1].left + "->" + items[itemNum].pp[newppnum - 1].right;
// }
}
}
}
}
for (int i = 0; i < itemsget[n].number; i++)
{
int point = findpoint(itemsget[n].pp[i].right);
if (point == itemsget[n].pp[i].right.Length - 1)
{
//rtb_show.Text += "\n"+vtnum+" "+inputn;
for (int k = 0; k < inputn+1; k++)
{
//rtb_show.Text += "\n" + itemsget[n].pp[i].right.Substring(0, findpoint(itemsget[n].pp[i].right))+"=" + p[k].right;
//产生式集中找出对应的产生式来归约,由于p【】中是加了.的所以加上再比较是否相等
if(p[k].left == itemsget[n].pp[i].left && p[k].right == ("."+itemsget[n].pp[i].right.Substring(0, findpoint(itemsget[n].pp[i].right))))
//if (allp[k].left == itemsget[n].pp[i].left && allp[k].right == itemsget[n].pp[i].right)
{
//rtb_show.Text += "\ni acturelly in else"+i+","+k;
//rtb_show.Text += "\n" + itemsget[n].pp[i].right.Substring(0, findpoint(itemsget[n].pp[i].right))+"=" + p[k].right;
if (itemsget[n].pp[i].left == "S'")
{
act[actNumber].left = "s" + itemsget[n].n;
act[actNumber].right = vt[4].ToString();
act[actNumber].value = "acc";
actNumber++;
}
else
{
for (int h = 0; h < vtnum; h++)
{
act[actNumber].left = "s" + itemsget[n].n;
act[actNumber].right = vt[h].ToString();
act[actNumber].value = "r" + k;
actNumber++;
rtb_show.Text += "\ni acturelly do it to r some state";
}
}
}
}
}
}
}
public void proCloses(item[] itemsget,int n)
{
// rtb_show.Text += "\nthis is closes\n";
int itemnumber = itemsget[n].number;
for(int i=0;i<itemnumber;i++)
{
int point = findpoint(itemsget[n].pp[i].right);//得到当前项某产生式的右部点的数组位置
if(point< itemsget[n].pp[i].right.Length-1)//如果数组位置不是末尾
{
if(itemsget[n].pp[i].right[point+1]<='Z'&&itemsget[n].pp[i].right[point+1]>='A')//寻找此产生式点后一位对应的是否为当前非终结符
{
for (int k=0;k<inputn+1;k++)//如果是非终结符,遍历项目集0的产生式
{
if(allp[k].left.Length<=1&&allp[k].left[0]== itemsget[n].pp[i].right[point + 1])//项目集0的某产生式的左部与点后一位相等
{
//rtb_show.Text += "i do search form 0 where left is"+itemsget.pp[i].right[point+1]+"\n";
rtb_show.Text += "which is find is" + allp[k].left + "->" + allp[k].right + "\n";
itemsget[n].pp[itemsget[n].number] = allp[k];//将此产生式加入到当前项目集
rtb_show.Text += itemsget[n].pp[itemsget[n].number].left+"->"+ itemsget[n].pp[itemsget[n].number ].right + "\n";
itemsget[n].number=itemsget[n].number+1;//加入产生式的个数+1
rtb_show.Text += itemsget[n].number + "\n";
}
}
}
}
}
//itemsget.number = 10;
}
public void creatI0()
{
for(int i=0;i<allp.Length;i++)
{
if(allp[i].left=="S'")
{
items[0].pp[0] = allp[i];
items[0].number = 1;
items[0].n = 0;
}
}
proCloses(items,0);
itemNum = 0;//反正是记录一个标记,具体含义看后面操作
}
public void getvt()
{
numNumber = 0;
bool flag;
for (int i = 0; i < inputn+1; i++)//S->Abcd,A->c,end
{
for (int j = 0; j < p[i].right.Length; j++)
{
if (p[i].right[j] >= 'a' && p[i].right[j] <= 'z')
{
flag = true;
for (int k = 0; k < numNumber - 1; k++)
{
if (vt[k] == p[i].right[j])
flag = false;
}
if (flag)
{
vt[numNumber++] = p[i].right[j];
}
}
}
}
vt[numNumber++] = '#';
vtnum = numNumber;
}
public void getVn()
{
numNumber = 0;
for (int i = 0; i < inputn; i++)
{
vn[numNumber++] = p[i].left[0];
}
vnnum = numNumber;
}
public void getNum()//获取元素建表首行a b c d e f A B C S
{
numNumber = 0;
bool flag ;
for(int i=0;i<inputn+1;i++)//S->Abcd,A->c,end
{
for(int j=0;j<p[i].right.Length;j++)
{
if (p[i].right[j]>='a'&&p[i].right[j]<='z')
{
flag = true;
for (int k = 0; k < numNumber - 1; k++)
{
if (tableNum[k] == p[i].right[j])
flag = false;
}
if (flag)
{
tableNum[numNumber++] = p[i].right[j];
}
}
}
}
tableNum[numNumber++] = '#';
for (int i = 0; i < inputn+1; i++)
{
if(p[i].left.Length<=1)
tableNum[numNumber++] = p[i].left[0];
}
}
public void getSi()
{
int bigNumber=0;
for(int i=0;i<inputn;i++)
{
for (int j = 0; j < p[i].right.Length; j++)
{
if(p[i].right[j]>'A'&&p[i].right[j]<'Z')
{
bigNumber++;
}
}
}
}
public void getAction()
{
int actnNumber = 0;
int a;
for (int i = 0; i < numNumber; i++)
{
if(p[i].left=="S")
{
for (int rightNumber = 0; rightNumber < p[i].right.Length; rightNumber++)
{
act[actnNumber].left = "s" + actnNumber;
act[actnNumber].right = p[i].right[rightNumber].ToString();
a = actnNumber + 1;
act[actnNumber].value = "s" + a;
actnNumber++;
}
}
}
}
public void getActiontest()
{
//rightNumber = 0;
actNumber = 0;
sNumber = 0;
int a;
for(int i=0;i< inputn;i++)
{
if (p[i].left == "S")
{
for (int j = 0; j < p[i].right.Length; j++)
if (p[i].right[j] >= 'a' && p[i].right[j] <= 'z')
{
act[actNumber].left = "s" + sNumber;
a = sNumber + 1;
act[actNumber].value = "s" + a;
act[actNumber].right = p[i].right[j].ToString();
actNumber++;
sNumber++;
}
else
bigNum(p, i, j);
}
}
act[actNumber].left = "s" + sNumber;
act[actNumber].right = "#";
act[actNumber].value = "acc";
actNumber++;
}
public void bigNum(production[] p, int i,int j)
{
for (int k = 0; k < inputn; k++)
{
if (p[k].left == p[i].right[j].ToString())//A->b A->Ab
{
int returnNumber = sNumber;
int a;
for (int n = 0; n < p[k].right.Length; n++)
{
if (p[k].right[n] >= 'a' && p[k].right[n] <= 'z')
{
act[actNumber].right = p[k].right[n].ToString();
act[actNumber].left = "s" + sNumber;
a = sNumber + 1;
act[actNumber].value = "s" + a;
actNumber++;
sNumber++;
}
else bigNum(p,k,n);
}
int actionNum = numNumber;
for(int m=0;m<actionNum; m++)//ri
{
act[actNumber].left = "s" + sNumber;
act[actNumber].value = "r" + returnNumber;
act[actNumber].right = tableNum[m].ToString();
actNumber++;
if(tableNum[m]=='#')
{
actionNum = 1;//结束
}
}
act[actNumber].left = "s" + returnNumber;
//act[actNumber].right = p[i].right[rightNumber].ToString();
act[actNumber].right = p[i].right[j].ToString();
a = sNumber + 1;
act[actNumber].value = "s" + a;
sNumber++;
actNumber++;
}
}
}
private void button2_Click(object sender, EventArgs e)
{
rtb_show.Clear();
//rtb_show.Text += "S->aAbd,A->c,end,\n";//
rtb_show.Text += "S->aAbE,A->c,E->d,end,\n";
//table.Dock = DockStyle.Top;//靠顶部自适应大小
table.Controls.Clear();//清空表
}
public void tableInit()
{
table.ColumnCount = numNumber + 1; //列
table.RowCount = sNumber + 3;
table.Height = table.RowCount * 40; //table的整体高度,每行40
//table.Height = table.RowCount * 44;
for (int i = 0; i < table.ColumnCount; i++)
{
table.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, table.Width * 0.2f)); //利用百分比计算,0.2f表示占用本行长度的20%
}
Label label0 = new Label();//首空白
label0.Text = " ";
label0.Width = 200;
label0.Height = 40;
label0.Font = new Font("隶书", 13, FontStyle.Bold);
label0.TextAlign = ContentAlignment.MiddleCenter;
table.Controls.Add(label0, 0, 0);
for (int j = 0; j < numNumber; j++)//列
{
Label label1 = new Label();
label1.Text = tableNum[j].ToString();
label1.Width = 200;
label1.Height = 40;
label1.Font = new Font("隶书", 13, FontStyle.Bold);
label1.TextAlign = ContentAlignment.MiddleCenter;
table.Controls.Add(label1, j + 1, 0);
}
for (int j = 0; j < sNumber+1; j++)//行
{
table.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 40));
Label label1 = new Label();
label1.Text += "s" + j;
label1.Width = 200;
label1.Height = 40;
label1.Font = new Font("隶书", 13, FontStyle.Bold);
label1.TextAlign = ContentAlignment.MiddleCenter;
table.Controls.Add(label1, 0, j + 1);
}
for (int i = 0; i < sNumber + 1; i++)
{
for (int j = 0; j < actNumber; j++)
{
//rtb_show.Text += "left time \n";
if (act[j].left == "s" + i)
{
// rtb_show.Text += "s left find " + act[j].left + "\n";
for (int k = 0; k < numNumber; k++)
{
//rtb_show.Text += "right time \n";
if (act[j].right == tableNum[k].ToString())
{
newLable(act[j].value, k + 1, i + 1);
rtb_show.Text += "site " + j + 1 + "," + k + 1 + "value"+act[j].value+"\n";
}
}
}
}
}
}
public void newLable(string tet,int x_site,int y_site)
{
Label label1 = new Label();
label1.Text += tet;
label1.Width = 200;
label1.Height = 40;
label1.Font = new Font("隶书", 13, FontStyle.Bold);
label1.TextAlign = ContentAlignment.MiddleCenter;
table.Controls.Add(label1, x_site, y_site);
}
private void tableLayoutPanel1_Paint(object sender, PaintEventArgs e)
{
}
}
}