编译原理实验辅助教学系统

目录

一.系统介绍

二.运行结果展示

三.源代码 


一.系统介绍

        本系统是基于C#开发的一个编译原理实验辅助教学系统,包含了词法分析器设计、自动机系统、NFA_DFA_MFA转换、LL(1)分析、LR(0)分析、SLR(1)分析等主要功能的实现。

二.运行结果展示

 

三.源代码 

namespace work_1
{
    public partial class Form1 : Form
    {
        static List<string> keys = new List<string>() { "int","float","double","char","struct","if","else","for","while","do","return",
                                                        "break","continue","auto","short","long","union","enum","typedef","const","unsigned",
                                                        "signed","extern","register","static","void","switch","case","goto","continue","break",
                                                        "sizeof","default"};
        static List<string> arithmetics = new List<string>() { "+","-","*","/","++","+="};
        static List<string> relations = new List<string>() { "<", "<=", "=", "==", ">", ">=", "!=","&","|","&&","||" };
        static List<char> borders = new List<char>() { ',',';','{','}','(',')','[',']' };
        //static List<string> labels = new List<string>();
        static List<string> consts = new List<string>();

        
  
        public Form1()
        {
            InitializeComponent();
        }

        private void toolStripMenuItem1_Click(object sender, EventArgs e)
        {

        }

        private void panel1_Paint(object sender, PaintEventArgs e)
        {

        }

        private void menuStrip2_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {

        }

        private void richTextBox2_TextChanged(object sender, EventArgs e)
        {
            richTextBox2.ReadOnly = true;
        }


        //打开按钮响应
        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            DialogResult dr = openFileDialog1.ShowDialog();
            //获取所打开文件的文件名
            string filename = openFileDialog1.FileName;
            if (dr == System.Windows.Forms.DialogResult.OK && !string.IsNullOrEmpty(filename))
            {
                StreamReader sr = new StreamReader(filename);
                richTextBox1.Text = sr.ReadToEnd();
                sr.Close();
            }
        }

        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {
            
        }


        //打开菜单响应
        private void 打开ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            DialogResult dr = openFileDialog1.ShowDialog();
            //获取所打开文件的文件名
            string filename = openFileDialog1.FileName;
            if (dr == System.Windows.Forms.DialogResult.OK && !string.IsNullOrEmpty(filename))
            {
                StreamReader sr = new StreamReader(filename);
                richTextBox1.Text = sr.ReadToEnd();
                sr.Close();
            }
        }

        保存按钮响应
        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog1 = new SaveFileDialog();
            DialogResult dr = saveFileDialog1.ShowDialog();
            string filename = saveFileDialog1.FileName;
            if (dr == System.Windows.Forms.DialogResult.OK && !string.IsNullOrEmpty(filename))
            {
                StreamWriter sw = new StreamWriter(filename, true, System.Text.Encoding.UTF8);
                sw.Write(richTextBox1.Text);
                sw.Close();
            }
        }

        private void 保存ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog1 = new SaveFileDialog();
            DialogResult dr = saveFileDialog1.ShowDialog();
            string filename = saveFileDialog1.FileName;
            if (dr == System.Windows.Forms.DialogResult.OK && !string.IsNullOrEmpty(filename))
            {
                StreamWriter sw = new StreamWriter(filename, true, System.Text.Encoding.UTF8);
                sw.Write(richTextBox1.Text);
                sw.Close();
            }
        }

        //退出按钮响应
        private void toolStripButton3_Click(object sender, EventArgs e)
        {
            System.Environment.Exit(0);
        }

        //退出菜单响应
        private void 退出ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            System.Environment.Exit(0);
        }

        //允许编辑
        private void toolStripButton4_Click(object sender, EventArgs e)
        {
            //richTextBox1.ReadOnly=false;
            richTextBox1.Enabled = true;
            richTextBox2.Enabled = true;
            richTextBox3.Enabled = true;
        }

        //退出编辑(只读)
        private void toolStripButton5_Click(object sender, EventArgs e)
        {
            richTextBox1.Enabled=false;
            richTextBox2.Enabled = false;
            richTextBox3.Enabled = false;
        }

        private void toolStripButton6_Click(object sender, EventArgs e)
        {
            richTextBox3.Text = null;
            int a = 89;
            int b = 90;
            int num = 0;
            richTextBox2.Text = string.Format("标识符整数码为{0};常量整数码为{1}\n", a,b);
            richTextBox2.AppendText("______________________________________________________\n");
            richTextBox2.AppendText("行号\t单词\t类型\t是否合法\t单词码\n");
            richTextBox2.AppendText("______________________________________________________\n");

            string[] str = richTextBox1.Text.Split('\n');
            //richTextBox2.AppendText(#"{Word}\t关键字\t合法\n");
            //逐行分析
            for (int i = 0; i < str.Length; i++)
            {
                char[] chars = str[i].ToCharArray();
                List<char> word = new List<char>();//临时保存分解出来的变量,关键字,字符等
                for (int j = 0; j < chars.Length; )
                {
                    char ch = chars[j];  //ch=i
                    while (ch <= 32 && ch > 0)//跳过不可见字符(空格)
                    {
                        if (j < chars.Length - 1)
                        {
                            ch = chars[++j];
                        }
                        else
                        {
                            break;
                        }
                    }
                    if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z')//若以字母开头,判断是关键字还是变量
                    {
                        while (true)
                        {
                            word.Add(ch);//保存下来
                            if (j < chars.Length - 1)//是否达到字符数组末尾
                            {
                                ch = chars[++j];
                            }
                            else
                            {
                                string Word = new string(word.ToArray());
                                //判断是关键字还是变量
                                if (keys.Contains(Word))//关键字
                                {
                                    //richTextBox2.Text = string.Format("标识符整数码为{0};常量整数码为{1}\n", a,b);
                                    richTextBox2.AppendText(String.Format("{0}\t", i + 1));
                                    richTextBox2.AppendText($"{Word}\t保留字\t合法\t\t2\n");
                                }
                                else
                                {
                                    /*
                                    if (!labels.Contains(Word))
                                    {
                                        labels.Add(Word);

                                    }*/
                                    richTextBox2.AppendText(String.Format("{0}\t", i + 1));
                                    richTextBox2.AppendText($"{Word}\t标识符\t合法\t\t89\n");
                                }
                                word.Clear();
                                j++;
                                break;
                            }
                            if (!(ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch >= '0' && ch <= '9'))//当出现非字母或数字的字符,即到达变量或关键字的结尾
                            {
                                string Word = new string(word.ToArray());
                                if (keys.Contains(Word))
                                {
                                    richTextBox2.AppendText(String.Format("{0}\t", i + 1));
                                    richTextBox2.AppendText($"{Word}\t保留字\t合法\t\t2\n");
                                }
                                else
                                {
                                    /*
                                    if (!labels.Contains(Word))
                                    {
                                        labels.Add(Word);
                                    }*/
                                    richTextBox2.AppendText(String.Format("{0}\t", i + 1));
                                    richTextBox2.AppendText($"{Word}\t标识符\t合法\t\t89\n");
                                }
                                word.Clear();
                                break;
                            }
                        }
                    }
                    else if (ch >= '0' && ch <= '9')//遇到数字开头
                    {
                        int flag = 0;
                        List<char> numbers = new List<char>();
                        while (true)
                        {
                            numbers.Add(ch);
                            ch = chars[++j];
                            if (!(ch >= 'a' && ch <= 'z'||ch>='A'&&ch<='Z'|| ch >= '0' && ch <= '9' || ch == '.'))
                            {
                                break;
                            }
                            
                        }

                        //分析numbers
                        for(int k = 0; k < numbers.Count; k++)
                        {
                            if (numbers[k] >= 'a' && numbers[k] <= 'z' || numbers[k] >= 'A' && numbers[k] <= 'Z')
                            {
                                string numbers_Word = new string(numbers.ToArray());
                                richTextBox2.AppendText(String.Format("{0}\t", i + 1));
                                //richTextBox2.AppendText(#"{numbers_Word}\t变量\t非法\n
                                
                                richTextBox2.AppendText($"{numbers_Word}\t标识符\t非法\t\t-1\t<-(错误行)\n");
                                richTextBox3.AppendText(String.Format("{0}行\t", i + 1));
                                richTextBox3.AppendText($"{numbers_Word}\t\t标识符命名错误\n");
                                num++;
                                numbers.Clear();
                                flag = 1;
                                break;
                            }
                        }
                        if (flag == 0)
                        {
                            string numbers_Word = new string(numbers.ToArray());
                            richTextBox2.AppendText(String.Format("{0}\t", i + 1));
                            richTextBox2.AppendText($"{numbers_Word}\t常量\t合法\t\t90\n");
                            numbers.Clear();
                        }
                    }
                    else if (ch == '+' || ch == '-' || ch == '*' || ch == '/')//遇到运算符号
                    {
                        string Word;
                        word.Add(ch);
                        ch = chars[++j];
                        if (chars[j - 1] == '-' && ch >= '0' && ch <= 9)//是负数还是-运算符
                        {
                            while (true)
                            {
                                word.Add(ch);
                                ch = chars[++j];
                                if (!(ch >= '0' && ch <= '9'))
                                {
                                    Word = new string(word.ToArray());
                                    if (!consts.Contains(Word))
                                    {
                                        consts.Add(Word);
                                    }
                                    richTextBox2.AppendText(String.Format("{0}\t", i + 1));
                                    richTextBox2.AppendText($"{Word}\t常量\t合法\t\t90\n");
                                    word.Clear();
                                    break;
                                }
                            }
                        }
                        else if (ch == '+' || ch == '-' || ch == '*' || ch == '/')//判断是否是++、--等运算符
                        {
                            word.Add(ch);
                            ch = chars[++j];
                        }
                        Word = new string(word.ToArray());
                        word.Clear();
                        if (arithmetics.Contains(Word))
                        {
                            richTextBox2.AppendText(String.Format("{0}\t", i + 1));
                            richTextBox2.AppendText($"{Word}\t运算符\t合法\t\t60\n");
                        }
                    }
                    else if (ch == '>' || ch == '<' || ch == '=' || ch == '!')//判断是否是关系运算符
                    {
                        word.Add(ch);
                        ch = chars[++j];
                        if (ch == '=')
                        {
                            word.Add(ch);
                            ch = chars[++j];
                        }
                        string Word = new string(word.ToArray());
                        word.Clear();
                        if (relations.Contains(Word))
                        {
                            richTextBox2.AppendText(String.Format("{0}\t", i + 1));
                            richTextBox2.AppendText($"{Word}\t运算符\t合法\t\t40\n");
                        }
                    }
                    else if (borders.Contains(ch))//是否是边界符
                    {
                        //richTextBox2.AppendText("*******************\n");
                        word.Add(ch);
                        if (j < chars.Length - 1)
                        {
                            ch = chars[++j];
                        }
                        else
                        {
                            j++;
                        }
                        string Word = new string(word.ToArray());
                        word.Clear();
                        richTextBox2.AppendText(String.Format("{0}\t", i + 1));
                        richTextBox2.AppendText($"{Word}\t界符\t合法\t\t64\n");
                    }
                    else
                    {
                        //richTextBox2.AppendText("*******************\n");
                        j++;
                    }

                }
            }
            richTextBox3.AppendText("____________________________________________\n");
            richTextBox3.AppendText(String.Format("{0} errors", num));
            //richTextBox3.Text = String.Format("{0} errors", num);

        }

        private void richTextBox3_TextChanged(object sender, EventArgs e)
        {
            //richTextBox3.ReadOnly = true;
        }

        private void 允许编辑ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //richTextBox1.ReadOnly = false;
        }

        private void 退出编辑ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            richTextBox1.ReadOnly = true;
        }

        private void 词法分析ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            toolStripButton6_Click(sender, e);
        }

        private void 自动机系统ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //new Form2().Show();
        }

        private void nFADFAMFAToolStripMenuItem_Click(object sender, EventArgs e)
        {
            new Form2().Show();
        }

        private void lL1分析ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            new Form3().Show();
        }

        private void lR0分析ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            new Form4().Show();
        }

        private void sLR1ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            new SLR_1().Show();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
    }
}
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;
using System.Text.RegularExpressions;
using System.Collections;

namespace work_1
{
    public partial class Form2 : Form
    {


        public Form2()
        {
            InitializeComponent();
            button4.Enabled = false;
            button7.Enabled = false;
            button9.Enabled = false;
        }

        string nfa;
        string dfa;
        string re;//正规式

        private void toolStripContainer1_TopToolStripPanel_Click(object sender, EventArgs e)
        {

        }

        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void label5_Click(object sender, EventArgs e)
        {

        }

        public bool rep(char x, string s)//判断是否重复
        {
            int i = 0;
            if (s.Length == 0)
            {
                return true;
            }
            while (i < s.Length)
            {
                if (s[i] == x)
                    return false;
                i++;
            }
            return true;
        }

        string s3 = "";
        public int countap(string s)//统计字母个数
        {
            int i = 0;
            while (i < s.Length)
            {
                if (s[i] <= 'z' && s[i] >= 'a')
                {
                    if (rep(s[i], s3))
                        s3 = s3 + s[i];
                }
                i++;
            }
            return s3.Length;
        }

        private void button1_Click(object sender, EventArgs e)
        {

            //MessageBox.Show("正确的输入");
            /*
             * 
            Regex r = new Regex("[\\(|\\)|\\*|\\||[a-z]|\\d#949]+");
            string a = textBox1.Text;
            bool t = r.IsMatch(a);
            if (t == false)
            {
                MessageBox.Show("表达式错误", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else
            {
                MessageBox.Show("正确", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
             */

            string Regular;//正规式
            int i, count = 0;//count用来标记(和)
            Regular = textBox1.Text;//用户输入的内容为正规式
            countap(Regular);//统计字母个数
            if (Regular == "")//如果输入为空白
            {
                MessageBox.Show("请输入一个正规式!");
                return;
            }


            if (Regular[0] == '|' || Regular[0] == '*' || Regular[Regular.Length - 1] == '|' || Regular[Regular.Length - 1] == '(')//不能以|、*开头,也不能以|、(结尾
            {
                // MessageBox.Show("错误的输入!");
                MessageBox.Show("表达式错误", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            for (i = 0; i < Regular.Length; i++)//做循环判断
            {
                if ((Regular[i] >= 'a' && Regular[i] <= 'z') || (Regular[i] >= 'A' && Regular[i] <= 'Z') || Regular[i] == '*' || Regular[i] == '|' || Regular[i] == '(' || Regular[i] == ')')
                //当前为大写(小写)字母或者*、|、(、)
                {
                    switch (Regular[i])
                    {
                        case '('://
                            if ((i + 1) < Regular.Length)
                            {
                                if (Regular[i + 1] == '*' || Regular[i + 1] == '|')//()内开头也不可以是闭包 
                                {
                                    //MessageBox.Show("正规式格式错误!\n (" + Regular[i + 1] + " 不符合要求");
                                    MessageBox.Show("表达式错误", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                    return;
                                }
                                if (Regular[i + 1] == ')')
                                {
                                    //MessageBox.Show("正规式格式错误!\n () 不符合要求");
                                    MessageBox.Show("表达式错误", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                    return;
                                }
                            }
                            count++;
                            break;
                        case '|'://
                            if ((i + 1) < Regular.Length)
                            {
                                if (Regular[i + 1] == '*' || Regular[i + 1] == '|' || Regular[i + 1] == ')')
                                {
                                    //MessageBox.Show("正规式格式错误!\n |" + Regular[i + 1] + " 不符合要求");
                                    MessageBox.Show("表达式错误", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                    return;
                                }
                            }
                            break;
                        case '*':
                            if ((i + 1) < Regular.Length)
                            {
                                if (Regular[i + 1] == '*')
                                {
                                    //MessageBox.Show("正规式格式错误!\n **不符合要求");
                                    MessageBox.Show("表达式错误", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                    return;
                                }
                            }
                            break;
                        case ')':
                            count--;
                            break;
                    }
                }
                else
                {
                    //MessageBox.Show("正规式格式错误!\n" + Regular[i] + "不符合要求!");
                    MessageBox.Show("表达式错误", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                if (count < 0)//只要出现)数量大于(时,一定是错误情况
                {
                    //MessageBox.Show("正规式格式错误!\n括号不匹配!");
                    MessageBox.Show("表达式错误", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
            }
            if (count != 0)//最终循环结束时,count=0才是括号匹配
            {
                //MessageBox.Show("正规式格式错误!\n括号不匹配!");
                MessageBox.Show("表达式错误", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            //CreateNFA.Enabled = true;
            button4.Enabled = true;
            button7.Enabled = true;
            button9.Enabled = true;
            //MessageBox.Show("表达式正确!");
            MessageBox.Show("表达式正确", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);


        }


        private String addConnect(String s)
        { // 为表达式加上连接符
            Stack stack = new Stack();
            char[] chr = s.ToCharArray();
            int point = 0;
            
            while (point != chr.Length)
            {

                //Regex r = new Regex("[\\(|\\)|\\*|\\||[a-z]]+");
                Regex r = new Regex("[(|)|*|||[a-z]]+");   //正则表达式,用来验证正规式
                Regex r1 = new Regex("[a-z]");


                // 对*[a-z]的情况在中间加上连接符后入栈
                if (chr[point] == '*' && point != chr.Length - 1&& r1.IsMatch(chr[point + 1] + ""))
                {
                    stack.push(chr[point]);
                    stack.push('.');
                }
                // 对)(、*(、[a-z](的情况在中间加上连接符后入栈
                else if (chr[point] == '(' && point != 0 && chr[point - 1] != '|')
                {
                    stack.push('.');
                    stack.push('(');
                }
                //[a-z][a-z] 或 )[a-z]
                else if (point != 0 && r1.IsMatch(chr[point] + "")&& (r1.IsMatch(chr[point - 1] + "") || chr[point - 1] == ')'))
                {
                    stack.push('.');
                    stack.push(chr[point]);
                }
                else
                {
                    stack.push(chr[point]);
                }
                point++;
            }
            return stack.getString(); //stack:(a*|b)*
        }

        private String change(String s)
        { // 生成后缀表达式
            char[] chr = s.ToCharArray();
            int point = 0;
            Stack stack = new Stack();
            String str = "";

            while (point != chr.Length)
            {
                switch (chr[point])
                {
                    case '(':
                        stack.push(chr[point]);
                        point++;
                        break;
                    case ')':   //在栈内匹配(,匹配成功则(出栈
                        while (stack.peek() != '(' && !stack.isEmpty())
                        {
                            str += stack.pop();
                        }
                        if (!stack.isEmpty() && stack.peek() == '(')
                            stack.pop();
                        point++;
                        break;
                    case '*':
                        str += chr[point];
                        point++;
                        break;
                    case '|':
                    case '.':
                        while (!stack.isEmpty() && stack.peek() != '('
                        && stack.peek() != ')'
                        && !compare(chr[point], stack.peek()))
                        {
                            str += stack.pop();
                        }
                        stack.push(chr[point]);
                        point++;
                        break;
                    default:  //[a-z]
                        str += chr[point];
                        point++;
                        break;
                }
            }
            while (!stack.isEmpty())
            {
                if (stack.peek() == ')' || stack.peek() == ')')
                    return "";
                else
                    str += stack.pop();
            }
            return str;  //str="a*b*

        }

        private bool compare(char a, char b)
        { //比较操作符的优先级
            if (a == b)
                return false;
            if (a == '*')
                return true;
            if (a == '.')
            {
                if (b == '*')
                    return false;
                else
                    return true;
            }
            return false;
        }

        private bool check(String str)
        { // 对后缀表达式做消除运算
            Stack stack = new Stack();
            Stack result = new Stack();
            char[] chr = str.ToCharArray();
            Regex r1 = new Regex("[a-z]");
            for (int i = chr.Length - 1; i >= 0; i--)
                stack.push(chr[i]);
            while (!stack.isEmpty())
            {
                switch (stack.peek())
                {
                    case '*':
                        if (!r1.IsMatch(result.peek() + ""))
                            return false;
                        stack.pop();
                        break;
                    case '.':
                    case '|':
                        if (result.length() < 2 || !r1.IsMatch(result.pop() + "")
                                || !r1.IsMatch(result.peek() + ""))
                            return false;
                        stack.pop();
                        break;
                    default:
                        result.push(stack.peek());
                        stack.pop();
                        break;
                }
            }
            return result.length() == 1 && r1.IsMatch(result.peek() + "");

        }

        int x = 1;
        Stack<int[]> list = new Stack<int[]>();
        Stack<string[]> res = new Stack<string[]>();
        Stack<string[]> res_T = new Stack<string[]>();

        private int getFacoter()
        {
            int s = x;
            x++;
            return s;
        }

        public int[] getElement(Stack<int[]> stack, int position)
        {
            int[] result = stack.Pop();
            if (stack.Count == position)
            {
                return result;
            }
            else
            {
                int[] element = getElement(stack, position);
                stack.Push(element);
                return element;
            }
        }

        public int[] getfactor()
        {
            return getElement(list, 0);
        }

        public Stack<String[]> getlist()
        {
            return res;
        }

        public void ToNFA(String str)
        {
            // TODO Auto-generated constructor stub
            char[] chr = str.ToCharArray();
            for (int i = 0; i < chr.Length; i++)
            {
                char ch = chr[i];
                int[] a = new int[2];
                int[] b = new int[2];
                int[] c = new int[2];
                switch (ch)
                {
                    case '.':
                        String[] st = new String[3];
                        // 取出list中上面的两个关系
                        a = list.Peek();
                        Console.WriteLine(a);
                        list.Pop();
                        b = list.Peek();
                        Console.WriteLine(b);
                        list.Pop();
                        // 创建新的关系
                        c = new int[2];
                        c[0] = b[0];
                        c[1] = a[1];
                        // 将上面的两个关系替换成新的关系
                        list.Push(c);
                        // 添加新的NFA项
                        st[0] = b[1] + "";
                        st[1] = "#";
                        st[2] = a[0] + "";
                        res.Push(st);
                        break;
                    case '|':
                        c[0] = getFacoter();
                        c[1] = getFacoter();
                        a = list.Peek();
                        list.Pop();
                        b = list.Peek();
                        list.Pop();
                        list.Push(c);
                        String[] st1 = new String[3];
                        String[] st2 = new String[3];
                        String[] st3 = new String[3];
                        String[] st4 = new String[3];
                        st1[0] = c[0] + "";
                        st1[1] = "#";
                        st1[2] = a[0] + "";
                        res.Push(st1);
                        st2[0] = c[0] + "";
                        st2[1] = "#";
                        st2[2] = b[0] + "";
                        res.Push(st2);
                        st3[0] = a[1] + "";
                        st3[1] = "#";
                        st3[2] = c[1] + "";
                        res.Push(st3);
                        st4[0] = b[1] + "";
                        st4[1] = "#";
                        st4[2] = c[1] + "";
                        res.Push(st4);
                        break;
                    case '*':
                        String[] st5 = new String[3];
                        String[] st6 = new String[3];
                        String[] st7 = new String[3];
                        String[] st8 = new String[3];
                        c[0] = getFacoter();
                        c[1] = getFacoter();
                        a = list.Peek();
                        list.Pop();
                        list.Push(c);
                        st5[0] = c[0] + "";
                        st5[1] = "#";
                        st5[2] = c[1] + "";
                        res.Push(st5);
                        st6[0] = c[0] + "";
                        st6[1] = "#";
                        st6[2] = a[0] + "";
                        res.Push(st6);
                        st7[0] = a[1] + "";
                        st7[1] = "#";
                        st7[2] = a[0] + "";
                        res.Push(st7);
                        st8[0] = a[1] + "";
                        st8[1] = "#";
                        st8[2] = c[1] + "";
                        res.Push(st8);
                        break;
                    default:
                        String[] st9 = new String[3];
                        c[0] = getFacoter();
                        c[1] = getFacoter();
                        list.Push(c);
                        st9[0] = c[0] + "";
                        st9[1] = ch + "";
                        st9[2] = c[1] + "";
                        res.Push(st9);
                        break;
                }
            }
        }


        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void button2_Click(object sender, EventArgs e)
        {
            textBox1.Text = "";
            listView1.Items.Clear();
            listView2.Items.Clear();
            listView3.Items.Clear();
            textBox2.Text = "";
            textBox3.Text = "";
            textBox4.Text = "";
            textBox5.Text = "";
            textBox6.Text = "";
            textBox7.Text = "";
        }

        private void richTextBox1_TextChanged_1(object sender, EventArgs e)
        {

        }

        private void button3_Click(object sender, EventArgs e)
        {
            listView1.Items.Clear();
            StreamReader vStreamReader = new StreamReader(
    @"F:\dfa_read.txt", Encoding.Default);
            string vLine;
            while ((vLine = vStreamReader.ReadLine()) != null)
            {
                string[] vItems = vLine.Split(new char[] { (char)9, ' ' },
                    StringSplitOptions.RemoveEmptyEntries); // 文本的格式得规范用空格还是制表符分隔?这里可以根据情况调整
                if (vItems.Length <= 0) continue;
                ListViewItem vListViewItem = new ListViewItem();
                vListViewItem.Text = vItems[0];
                for (int i = 1; i < vItems.Length; i++)
                {
                    vListViewItem.SubItems.Add(vItems[i]);
                }
                listView1.Items.Add(vListViewItem);
            }
            vStreamReader.Close();
            button4.Enabled = true;
            button7.Enabled = true;
            button9.Enabled = true;
        }

        private void button6_Click(object sender, EventArgs e)
        {
            listView2.Items.Clear();
            StreamReader vStreamReader = new StreamReader(
    @"F:\todfa2.txt", Encoding.Default);
            string vLine;
            while ((vLine = vStreamReader.ReadLine()) != null)
            {
                string[] vItems = vLine.Split(new char[] { (char)9, ' ' },
                    StringSplitOptions.RemoveEmptyEntries); // 文本的格式得规范用空格还是制表符分隔?这里可以根据情况调整
                if (vItems.Length <= 0) continue;
                ListViewItem vListViewItem = new ListViewItem();
                vListViewItem.Text = vItems[0];
                for (int i = 1; i < vItems.Length; i++)
                {
                    vListViewItem.SubItems.Add(vItems[i]);
                }
                listView2.Items.Add(vListViewItem);
            }
            vStreamReader.Close();
            textBox4.Text = "1";
            textBox5.Text = "5";

            button4.Enabled = true;
            button7.Enabled = true;
            button9.Enabled = true;
        }

        private void button5_Click(object sender, EventArgs e)
        {
            using (var tw = new StreamWriter(@"F:\t2.txt"))
            {
                StringBuilder sb;
                

                if (listView1.Items.Count > 0)
                {
                 
                    // the actual data
                    foreach (ListViewItem lvi in listView1.Items)
                    {
                        sb = new StringBuilder();
                        
                        foreach (ListViewItem.ListViewSubItem listViewSubItem in lvi.SubItems)
                        {
                            sb.Append(string.Format("{0}\t", listViewSubItem.Text));
                        }
                        tw.WriteLine(sb.ToString());
                    }
                    tw.WriteLine();
                }
            }
            MessageBox.Show("保存成功", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void button8_Click(object sender, EventArgs e)
        {
            using (var tw = new StreamWriter(@"F:\dfa_save.txt"))
            {
                StringBuilder sb;


                if (listView1.Items.Count > 0)
                {

                    // the actual data
                    foreach (ListViewItem lvi in listView1.Items)
                    {
                        sb = new StringBuilder();

                        foreach (ListViewItem.ListViewSubItem listViewSubItem in lvi.SubItems)
                        {
                            sb.Append(string.Format("{0}\t", listViewSubItem.Text));
                        }
                        tw.WriteLine(sb.ToString());
                    }
                    tw.WriteLine();
                }
            }
            MessageBox.Show("保存成功", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void button4_Click(object sender, EventArgs e)
        {
            /*
            listView1.Items.Clear(); //清空数据

            List<string> ch1 = new List<string>();
            List<string> ch2 = new List<string>();

            string st = textBox1.Text;
            string ss = addConnect(st);
            string ss1 = change(ss);
            string ss2;
            if (check(ss1))
            {
                ss2 = ss1;
            }
            else
            {
                ss2 = "";
            }

            ToNFA(ss2);
            foreach (string[] ch in res)
            {
                String[] st_t = new String[3];
                st_t[0] = ch[0];
                st_t[1] = ch[1];
                st_t[2] = ch[2];
                res_T.Push(st_t);
            }

            int cnt1 = 0, cnt2 = 0;
            int flag = 0;
            string t=null;

            foreach (string[] ch in res_T)
            {
                
                ListViewItem item = new ListViewItem();
                item.Text = ch[0];

                //记录ch[0]以便判断初始状态集
                if (!ch1.Contains(ch[0]))
                {
                    ch1.Add(ch[0]);
                    cnt1++;
                }
                item.SubItems.Add(ch[1]);
                item.SubItems.Add(ch[2]);
                //记录ch[2]以便判断初始状态集
                if (!ch2.Contains(ch[2]))
                {
                    ch2.Add(ch[2]);
                    cnt2++;
                }
                listView1.Items.Add(item);
                
                flag++;
                t = ch[2];

            }

            int i, j, flag2 = 0;//flag2用来标记初始终态集
            for(i = 0; i < cnt1; i++)
            {
                for(j = 0; j < cnt2; j++)
                {
                    if (ch1[i] == ch2[j])
                    {
                        //ch1.Remove(ch1[i]);
                        //ch2.Remove(ch2[j]);
                        flag2 = 1;break;
                    }
                }
                if(flag2 == 0) //找到了初始集
                {
                    textBox2.AppendText(ch1[i]+" ");
                    //textBox2.Text = ch1.ToString();
                }
                flag2 = 0;
            }

            int flag3 = 0;
            for (i = 0; i < cnt2; i++)
            {
                for (j = 0; j < cnt1; j++)
                {
                    if (ch2[i] == ch1[j])
                    {
                        //ch1.Remove(ch1[i]);
                        //ch2.Remove(ch2[j]);
                        flag3 = 1; break;
                    }
                }
                if (flag3 == 0) //找到了终态
                {
                    textBox3.AppendText(ch2[i] + " ");
                    //textBox2.Text = ch1.ToString();
                }
                flag3 = 0;
            }

            */

            //textBox3.Text = t;

            if (textBox1.Text != "")
            {
                string str = textBox1.Text;
                NFA nFA = new NFA();
                nFA.SetStr(str);
                nFA.ExptoNFA();
                nfa = "开始符:" + nFA.start_state.ToString() + '\n' +
                    "终结符:" + nFA.end_state.ToString() + '\n' +
                    "符号集:";
                for (int i = 0; i < nFA.list_ch.Count; i++)
                {
                    nfa += nFA.list_ch[i].ToString() + ' ';
                }
                nfa += '\n';
                nfa += nFA.result;

                string[] ss = nFA.result.Split('\n');
                listView1.Items.Clear();
                // 在listViewNFA.Items中显示
                for (int i = 0; i < ss.Length; i++)
                {
                    string[] sss = ss[i].Split('\t', '\n');
                    ListViewItem list = new ListViewItem(sss[0]);
                    list.SubItems.Add(sss[1]);
                    list.SubItems.Add(sss[2]);
                    listView1.Items.Add(list);
                }
                // 输出开始状态集、终态集
                textBox2.Text = nFA.start_state.ToString();
                textBox3.Text = nFA.end_state.ToString();
                button7.Enabled = true;
            }
            else
            {
                //DialogResult dia = MessageBox.Show("正规式为空!", "提示");
                //button7.Enabled = false;
                //buttonMFA.Enabled = false;
            }
            listView2.Items.Clear();
            listView3.Items.Clear();

        }

        private void listView1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void listView1_SelectedIndexChanged_1(object sender, EventArgs e)
        {

        }

        private void textBox2_TextChanged(object sender, EventArgs e)
        {
            
        }

        private void button7_Click(object sender, EventArgs e)
        {
            if (nfa != "")
            {
                DFA dFA = new DFA(nfa);
                string str_dfa_result = dFA.NFAtoDFA();
                string[] str_dfa_splited = str_dfa_result.Split('\n');
                listView2.Items.Clear();
                for (int i = 0; i < str_dfa_splited.Length; i++)
                {
                    string[] every_base_state = str_dfa_splited[i].Split('\t', '\n');
                    ListViewItem list = new ListViewItem(every_base_state[0]);
                    list.SubItems.Add(every_base_state[1]);
                    list.SubItems.Add(every_base_state[2]);
                    listView2.Items.Add(list);
                }
                textBox4.Text = "0";
                textBox5.Text = dFA.end_state;
                dfa = "开始符:0;\n结束符:" + textBox5.Text + "\n" + "最大状态数:" + dFA.count + "\n" + "符号集:";
                for (int i = 0; i < dFA.to_list.Count; i++)
                {
                    dfa += dFA.to_list[i] + " ";
                }
                dfa += "\n" + str_dfa_result;
                //richTextBox1.Text = dfa;
                //buttonMFA.Enabled = true;
            }
            else
            {
                //DialogResult dia = MessageBox.Show("NFA为空!", "提示");
                //buttonMFA.Enabled = false;
            }
            listView3.Items.Clear();
        }

        private void textBox4_TextChanged(object sender, EventArgs e)
        {

        }

        private void button9_Click(object sender, EventArgs e)
        {
            if (dfa != "")
            {
                MFA Mfa = new MFA(dfa);
                Mfa.Needless();
                Mfa.Sameless();
                listView3.Items.Clear();
                for (int i = 0; i < Mfa.mfa_list.Count; i++)
                {
                    ListViewItem list = new ListViewItem(Mfa.mfa_list[i].start.ToString());
                    list.SubItems.Add(Mfa.mfa_list[i].to.ToString());
                    list.SubItems.Add(Mfa.mfa_list[i].end.ToString());
                    listView3.Items.Add(list);
                }
                textBox6.Text = Mfa.start.ToString();
                textBox7.Text = Mfa.num_end.ToString();
            }
            else
            {
                DialogResult dia = MessageBox.Show("DFA为空!", "提示");
            }
        }

        private void Form2_Load(object sender, EventArgs e)
        {

        }
    }
}



public class Stack
{

    private int maxSize;// 栈的大小
    private int top;
    private char[] arr;

    public Stack()
    {
        maxSize = 30;
        top = -1;
        arr = new char[maxSize];
    }

    public void push(char value)
    { // 压入数据

        arr[++top] = value;
    }

    public char pop()
    { // 弹出数据

        return arr[top--];
    }

    public char peek()
    { // 访问栈顶元素

        return arr[top];
    }

    public bool isFull()
    { // 栈是否满了

        return maxSize - 1 == top;
    }

    public bool isEmpty()
    { // 栈是否为空

        return top == -1;
    }

    public int length()
    { // 栈内元素个数
        return top + 1;
    }

    public String getString()
    {
        if (top == -1)
            return "";
        String s = "";
        int point = 0;
        while (point <= top)
        {
            s += arr[point];
            point++;
        }
        return s;
    }
}

public class NFA
{
    public struct FA
    {
        public int start;
        public char to;
        public int end;
    }
    public string str;
    public string result;
    public int start_state;         // 记录开始状态
    public int end_state;           // 记录结束状态

    // 构造函数
    public NFA(string str)
    {
        this.str = str;
    }

    public NFA()
    {
    }

    public void SetStr(string str)
    {
        this.str = str;
    }

    // 定义两个list作存储数组
    public List<FA> list_nfa = new List<FA>();
    public List<char> list_ch = new List<char>();


    public void ExptoNFA()      // 正规式转NFA
    {
        string exp_end = ExptoEnd();
        int state_num = 0;

        Stack<int> stack_startstate = new Stack<int>();
        Stack<int> stack_endstate = new Stack<int>();
        for (int i = 0; i < exp_end.Length; i++)
        {
            if (char.IsLetter(exp_end[i]))
            {
                FA nfa1 = new FA();
                nfa1.start = state_num;
                stack_startstate.Push(state_num);

                nfa1.to = exp_end[i];

                nfa1.end = state_num + 1;
                stack_endstate.Push(state_num + 1);
                state_num += 2;

                list_nfa.Add(nfa1);
                if (!list_ch.Contains(exp_end[i]))
                {
                    list_ch.Add(exp_end[i]);
                }
            }
            else
            {
                if (exp_end[i] == '.')
                {

                    FA nFA_temp = new FA();
                    int s1, s2, e1, e2;

                    s2 = stack_startstate.Pop();
                    s1 = stack_startstate.Pop();
                    e2 = stack_endstate.Pop();
                    e1 = stack_endstate.Pop();


                    nFA_temp.start = e1;
                    nFA_temp.to = '#';
                    nFA_temp.end = s2;
                    list_nfa.Add(nFA_temp);
                    stack_startstate.Push(s1);
                    stack_endstate.Push(e2);
                }
                else if (exp_end[i] == '*')
                {
                    int s1, e1;
                    s1 = stack_startstate.Pop();
                    e1 = stack_endstate.Pop();
                    FA nFA_temp = new FA();


                    nFA_temp.start = state_num;
                    nFA_temp.to = '#';
                    nFA_temp.end = s1;
                    list_nfa.Add(nFA_temp);

                    nFA_temp.start = e1;
                    nFA_temp.to = '#';
                    nFA_temp.end = state_num + 1;
                    list_nfa.Add(nFA_temp);


                    nFA_temp.start = state_num;
                    nFA_temp.to = '#';
                    nFA_temp.end = state_num + 1;
                    list_nfa.Add(nFA_temp);


                    nFA_temp.start = e1;
                    nFA_temp.to = '#';
                    nFA_temp.end = s1;
                    list_nfa.Add(nFA_temp);

                    stack_startstate.Push(state_num);
                    stack_endstate.Push(state_num + 1);
                    state_num += 2;

                }
                else if (exp_end[i] == '|')
                {
                    FA nFA_temp = new FA();
                    int s1, s2, e1, e2;
                    s2 = stack_startstate.Pop();
                    s1 = stack_startstate.Pop();
                    e2 = stack_endstate.Pop();
                    e1 = stack_endstate.Pop();


                    nFA_temp.start = state_num;
                    nFA_temp.to = '#';
                    nFA_temp.end = s1;
                    list_nfa.Add(nFA_temp);
                    nFA_temp.start = state_num;
                    nFA_temp.to = '#';
                    nFA_temp.end = s2;
                    list_nfa.Add(nFA_temp);


                    nFA_temp.start = e1;
                    nFA_temp.to = '#';
                    nFA_temp.end = state_num + 1;
                    list_nfa.Add(nFA_temp);
                    nFA_temp.start = e2;
                    nFA_temp.to = '#';
                    nFA_temp.end = state_num + 1;
                    list_nfa.Add(nFA_temp);

                    stack_startstate.Push(state_num);
                    stack_endstate.Push(state_num + 1);
                    state_num += 2;
                }
            }
            if (stack_startstate.Count == 1)
            {
                start_state = stack_startstate.Peek();
                end_state = stack_endstate.Peek();
            }
        }
        result = NFAtoString(list_nfa);
        list_ch.Sort();
    }//
    public string NFAtoString(List<FA> n)
    {
        string str = "";
        int i = 0;
        for (i = 0; i < n.Count - 1; i++)
        {
            str += n[i].start.ToString() + '\t' + n[i].to + '\t' + n[i].end.ToString() + '\n';
        }
        str += n[i].start.ToString() + '\t' + n[i].to + '\t' + n[i].end.ToString();
        return str;
    }

    // 表达式转后缀表达式
    public string ExptoEnd()
    {
        string str_temp = "";
        string str_result = "";
        int i = 0;
        for (i = 0; i < str.Length - 1; i++)
        {
            str_temp += str[i];
            if ((char.IsLetter(str[i]) && (char.IsLetter(str[i + 1]) || str[i + 1] == '('))
                || (str[i].Equals(')') && char.IsLetter(str[i + 1]))
                || (str[i].Equals(')') && str[i + 1].Equals('('))
                || (str[i].Equals('*') && (str[i + 1].Equals('(') || char.IsLetter(str[i + 1]))))
            {
                // 添加 .表示连接运算
                str_temp += '.';
            }
        }
        str_temp += str[str.Length - 1];

        Stack<char> op_youxianji_stack = new Stack<char>();        // 判断操作符优先级的栈
        i = 0;
        string sign = "(|.*)";      // 处理后的操作符
                                    //操作符优先级判断  ) > * > . > | > ( 
        while (i < str_temp.Length)
        {
            if (char.IsLetter(str_temp[i]))
            {
                str_result += str_temp[i];      // 字母直接加入
            }
            else
            {
                if (op_youxianji_stack.Count == 0)     // 栈空,操作符直接加入
                    op_youxianji_stack.Push(str_temp[i]);
                else
                {
                    if (str_temp[i] == '(')
                        op_youxianji_stack.Push('(');
                    else if (str_temp[i] == ')')
                    {
                        while (op_youxianji_stack.Peek() != '(')
                        {
                            str_result += op_youxianji_stack.Peek();
                            op_youxianji_stack.Pop();
                        }
                        op_youxianji_stack.Pop();
                    }
                    else if (sign.IndexOf(str_temp[i]) > sign.IndexOf(op_youxianji_stack.Peek()))
                    {
                        op_youxianji_stack.Push(str_temp[i]);
                    }
                    else
                    {
                        while (op_youxianji_stack.Count > 0 && sign.IndexOf(str_temp[i]) <= sign.IndexOf(op_youxianji_stack.Peek()))
                        {
                            str_result += op_youxianji_stack.Peek();
                            op_youxianji_stack.Pop();
                        }
                        op_youxianji_stack.Push(str_temp[i]);
                    }
                }
            }
            i++;
        }
        while (op_youxianji_stack.Count != 0)
        {
            str_result += op_youxianji_stack.Peek();
            op_youxianji_stack.Pop();
        }
        return str_result;
    }
}

public class DFA
{
    public struct FA
    {
        public int start;
        public char to;
        public int end;
    }
    public List<int> start = new List<int>();//开始状态集
    public List<int> end = new List<int>();//结束状态集
    public List<char> to_list = new List<char>();//符号集
    public int count = 0;//状态数
    List<FA> nfa = new List<FA>();

    public String end_state;

    public DFA(string str_nfa_rslt)    // 对前一部分的结果进行处理
    {

        string[] str1 = str_nfa_rslt.Split('\n');
        int i = 0;
        while (i < str1.Length)
        {
            if (i == 0)
            {
                string[] str_temp1 = str1[0].Split(':');
                string[] str_temp2 = str_temp1[1].Split(' ');
                for (int j = 0; j < str_temp2.Length; j++)
                {
                    start.Add(int.Parse(str_temp2[j]));
                }
            }
            else if (i == 1)
            {
                string[] str_temp3 = str1[1].Split(':');
                string[] str_temp4 = str_temp3[1].Split(' ');
                for (int j = 0; j < str_temp4.Length; j++)
                {
                    end.Add(int.Parse(str_temp4[j]));
                }
            }
            else if (i == 2)
            {
                string[] str_temp5 = str1[2].Split(':');
                string[] str_temp6 = str_temp5[1].Split(' ');
                for (int j = 0; j < str_temp6.Length - 1; j++)
                {
                    to_list.Add(char.Parse(str_temp6[j]));
                }
            }
            else
            {
                string[] str = str1[i].Split('\t', '\n', '\r');
                FA fa_temp = new FA();
                fa_temp.start = int.Parse(str[0]);
                fa_temp.to = str[1][0];
                fa_temp.end = int.Parse(str[2].ToString());
                nfa.Add(fa_temp);
            }
            i++;
        }
    }//NFA

    public String NFAtoDFA()
    {
        List<List<int>> closure_list = new List<List<int>>();
        List<FA> list_FA = new List<FA>();
        int index = 0;
        closure_list.Add(closure(start));
        while (index < closure_list.Count)
        {
            List<int> list_t = new List<int>();
            list_t = closure_list[index];
            for (int i = 0; i < to_list.Count; i++)
            {
                if (move(list_t, to_list[i]).Count != 0)
                {
                    List<int> res = new List<int>();
                    res = closure(move(list_t, to_list[i]));
                    int NO = locate(closure_list, res);
                    if (NO == -1)
                    {
                        closure_list.Add(res);
                        FA n = new FA();
                        n.start = index;
                        n.to = to_list[i];
                        n.end = closure_list.Count - 1;
                        list_FA.Add(n);
                    }
                    else
                    {
                        FA n = new FA();
                        n.start = index;
                        n.to = to_list[i];
                        n.end = NO;
                        list_FA.Add(n);
                    }
                }
            }
            index++;
        }
        count = StatuesNum(list_FA);
        end_state = end_with(closure_list, end);
        return NFAtoString(list_FA);

    }//NFAtoDFA

    public List<int> closure(List<int> list)
    {
        Queue<int> state_queue = new Queue<int>();
        List<int> closure_result_list = new List<int>();
        for (int i = 0; i < list.Count; i++)
        {
            state_queue.Enqueue(list[i]);
            closure_result_list.Add(list[i]);
        }
        while (state_queue.Count != 0)
        {
            int now_state = state_queue.Peek();
            state_queue.Dequeue();
            for (int i = 0; i < nfa.Count; i++)
            {
                if (nfa[i].start == now_state && nfa[i].to == '#' && find(closure_result_list, nfa[i].end) == -1)
                {
                    state_queue.Enqueue(nfa[i].end);
                    closure_result_list.Add(nfa[i].end);
                }
            }
        }
        closure_result_list.Sort();
        return closure_result_list;
    }
    public int find(List<int> list_t, int x)     // find函数
    {
        for (int i = 0; i < list_t.Count; i++)
        {
            if (list_t[i] == x)
                return 1;
        }
        return -1;
    }

    public List<int> move(List<int> state_list, char to)
    {
        List<int> move_result_list = new List<int>();
        for (int i = 0; i < state_list.Count; i++)
        {
            for (int j = 0; j < nfa.Count; j++)
            {
                if (state_list[i] == nfa[j].start && nfa[j].to == to)
                {
                    move_result_list.Add(nfa[j].end);
                }
            }
        }
        move_result_list.Sort();
        return move_result_list;
    }//move

    public int locate(List<List<int>> C, List<int> x)       // 查找x在C中的位置
    {
        for (int i = 0; i < C.Count; i++)
        {
            if (C[i].Count == x.Count)
            {
                int j;
                for (j = 0; j < x.Count; j++)
                {
                    if (C[i][j] != x[j])
                        break;
                }
                if (j >= x.Count)
                    return i;
            }
        }
        return -1;
    }

    public string NFAtoString(List<FA> n)       // 转换为固定格式的string
    {
        string str = "";
        int i = 0;
        for (i = 0; i < n.Count - 1; i++)
        {
            str += n[i].start.ToString() + '\t' + n[i].to + '\t' + n[i].end.ToString() + '\n';
        }
        str += n[i].start.ToString() + '\t' + n[i].to + '\t' + n[i].end.ToString();
        return str;
    }

    public String end_with(List<List<int>> C, List<int> end)
    {
        String result = "";
        for (int i = 0; i < C.Count; i++)
        {
            for (int j = 0; j < end.Count; j++)
            {
                if (C[i].Contains(end[j]))
                {
                    result += i.ToString() + ' ';
                    break;
                }
            }
        }
        return result;
    }
    public int StatuesNum(List<FA> n)
    {
        List<int> num_list = new List<int>();
        for (int i = 0; i < n.Count; i++)
        {
            if (!num_list.Contains(n[i].start))
            {
                num_list.Add(n[i].start);
            }
            if (!num_list.Contains(n[i].end))
            {
                num_list.Add(n[i].end);
            }
        }
        return num_list.Count;
    }
}

class MFA
{
    public struct FA
    {
        public int start;
        public char to;
        public int end;
    }
    string Origin;
    List<FA> dfa_list = new List<FA>();
    public List<FA> mfa_list = new List<FA>();
    public int start;//开始状态集
    List<int> end_list = new List<int>();//结束状态集
    public int num_end;
    int max_state_count;//最大状态数
    List<char> sign_list = new List<char>();//符号集
    public MFA(string str)
    {
        this.Origin = str;
        string[] str1 = str.Split('\n');
        for (int i = 0; i < str1.Length; i++)
        {
            if (i == 0)
            {
                string[] str2 = str1[0].Split(':');
                string[] str3 = str2[1].Split(';');
                start = int.Parse(str3[0]);
            }
            else if (i == 1)
            {
                string[] str2 = str1[1].Split(':');
                string[] str3 = str2[1].Split(' ');
                for (int j = 0; j < str3.Length - 1; j++)
                {
                    end_list.Add(int.Parse(str3[j]));
                }
            }
            else if (i == 2)
            {
                string[] str2 = str1[2].Split(':');
                max_state_count = int.Parse(str2[1]);
            }
            else if (i == 3)
            {
                string[] str2 = str1[3].Split(':');
                string[] str3 = str2[1].Split(' ');
                for (int j = 0; j < str3.Length - 1; j++)
                {
                    sign_list.Add(str3[j][0]);
                }
            }
            else
            {
                string[] str2 = str1[i].Split('\t', '\n');
                FA fa_temp = new FA();
                fa_temp.start = int.Parse(str2[0]);
                fa_temp.to = str2[1][0];
                fa_temp.end = int.Parse(str2[2]);
                dfa_list.Add(fa_temp);
            }
        }
        end_list.Sort();
        sign_list.Sort();
    }//MFA

    public void Needless()
    {
        int max_new = max_state_count;
        List<int> new_count_list = new List<int>();
        for (int i = 0; i < max_new; i++)
        {
            new_count_list.Add(0);
        }
        Stack<int> stack = new Stack<int>();
        stack.Push(0);
        new_count_list[0] = 1;
        while (stack.Count != 0)
        {
            int x = stack.Peek();
            stack.Pop();
            for (int i = 0; i < dfa_list.Count; i++)
            {
                if (dfa_list[i].start == x)
                {
                    if (new_count_list[dfa_list[i].end] == 0)
                    {
                        stack.Push(dfa_list[i].end);
                        new_count_list[dfa_list[i].end] = 1;
                    }
                }
            }
        }
        List<FA> dfa_new = new List<FA>();
        List<int> end_new = new List<int>();
        for (int i = 0; i < new_count_list.Count; i++)
        {
            if (new_count_list[i] == 1)
            {
                if (end_list.Contains(i))
                {
                    end_new.Add(i);
                }
                for (int j = 0; j < dfa_list.Count; j++)
                {
                    if (dfa_list[j].start == i)
                    {
                        dfa_new.Add(dfa_list[j]);
                    }

                }
            }
        }
        dfa_list.Clear();
        end_list.Clear();
        dfa_list = dfa_new;
        end_list = end_new;
    }

    public void Sameless()
    {
        List<List<int>> result = new List<List<int>>();
        List<int> e = new List<int>();
        for (int i = 0; i < dfa_list.Count; i++)
        {
            if (!end_list.Contains(dfa_list[i].start) && !e.Contains(dfa_list[i].start))
            {
                e.Add(dfa_list[i].start);
            }
        }
        e.Sort();
        if (e.Count != 0)
            result.Add(e);
        result.Add(end_list);
        int count = 0;
        while (count < result.Count)
        {
            List<int> E = new List<int>();
            E = result[count];
            if (count == result.Count - 1)//终结状态
            {
                num_end = findtype(result, E[0]);
            }
            List<int> L = new List<int>();
            for (int i = 0; i < sign_list.Count; i++)
            {
                int x = findtype(result, findlast(E[0], sign_list[i]));
                for (int j = 0; j < E.Count; j++)
                {
                    if (findlast(E[j], sign_list[i]) != -1 && findtype(result, findlast(E[j], sign_list[i])) != x && !L.Contains(E[j]))
                    {
                        L.Add(E[j]);
                    }
                }
            }
            if (L.Count == 0)
            {
                count++;
            }
            else
            {
                List<int> J = new List<int>();
                for (int x = 0; x < E.Count; x++)
                {
                    if (!L.Contains(E[x]))
                    {
                        J.Add(E[x]);
                    }
                }
                result.RemoveAt(count);
                result.Insert(count, J);
                result.Insert(count + 1, L);
            }
        }

        for (int i = 0; i < result.Count; i++)
        {
            for (int j = 0; j < dfa_list.Count; j++)
            {
                if (dfa_list[j].start == result[i][0])
                {
                    FA fa = new FA();
                    fa.start = findtype(result, dfa_list[j].start);
                    fa.to = dfa_list[j].to;
                    fa.end = findtype(result, dfa_list[j].end);
                    if (!mfa_list.Contains(fa))
                        mfa_list.Add(fa);
                }
            }
        }
    }

    public int findlast(int s, char a)
    {
        for (int i = 0; i < dfa_list.Count; i++)
        {
            if (dfa_list[i].start == s && dfa_list[i].to == a)
            {
                return dfa_list[i].end;
            }
        }
        return -1;
    }

    public int findtype(List<List<int>> result, int type)
    {
        for (int i = 0; i < result.Count; i++)
        {
            if (result[i].Contains(type))
                return i;
        }
        return -1;
    }

    public string FAtoString(List<FA> n)
    {
        string str = "";
        int i = 0;
        for (i = 0; i < n.Count - 1; i++)
        {
            str += n[i].start.ToString() + '\t' + n[i].to + '\t' + n[i].end.ToString() + '\n';
        }
        str += n[i].start.ToString() + '\t' + n[i].to + '\t' + n[i].end.ToString();
        return str;
    }//

    public string Test()
    {
        string res = "";
        for (int i = 0; i < sign_list.Count; i++)
        {
            res += sign_list[i] + " ";
        }
        return res;
    }
}

  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值