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)

        {

            

        }

 

       

    }

}

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值