{ "title": "SLR 分析器 C# 代码实现", "description": "本文提供完整的 SLR 分析器 C# 代码实现,包含产生式定义、项目集构造、分析表生成和分析过程。", "keywords": "SLR 分析器, C#, 编译原理, 语法分析, 自动机, 形式语言", "content": "namespace WindowsFormsApp4 { class SLR { //产生式结点类 public class SLRproNode { public string Left; public string Right; public SLRproNode(string Left, string Right) { this.Left = Left; this.Right = Right; } } //项目集类 public class SLR_club { public List Container = new List(100); //记录项目在项目集合中的序号 }

    //DFA结点
    public struct DFA
    {
        public int from;
        public char symbol;
        public int to;
        public DFA(int from, char symbol, int to)
        {
            this.from = from;
            this.symbol = symbol;
            this.to = to;
        }
    }

    //分析表 结点
    public class Table
    {
        public bool error;//是否为ERROR
        public char type;//结点类型
        public int id;//数值
        public Table()
        {
            this.error = true;
        }
        public Table(char type, int id)
        {
            this.type = type;
            this.id = id;
            this.error = false;
        }
    }

   

    public DFA[] dfa = new DFA[100];
    public int Pindex = 0; //dfa数组指针
    public Table[][] SLRAna;//分析表
    public ANA_JUZI Jz;
    public bool Success = false;
    public List<SLRproNode> SLRproNum = new List<SLRproNode>(50);//产生式 列表
    public List<SLRproNode> SLRobjNum = new List<SLRproNode>(50);//项目 列表
    public List<SLR_club> pro_club = new List<SLR_club>(100);//项目集合
    public List<int> Gy_obj = new List<int>(50);//归约项目序号集合
    public List<int> Gy_club = new List<int>(50);//含有归约项目的集合的序号 的集合
    public List<char> Nchar = new List<char>(50);//非终结符集合
    public List<char> Echar = new List<char>(50);//终结符集合

    public string RETStr = "";
    public string RETStr_obclub = "";//输出返回
    public string RETStr_DFA = "";
    public string RETStr_ANA = "";




    //读取传递过来的文件信息str后,对str的或运算加以处理,变成多个产生式
    //返回处理过的信息
    //public void Start(string str)
    {
    }

  

    //求项目集
    public void Cre_club()
    {
        List<int> slr_club = new List<int>(100);//记录项目的序号
        slr_club.Add(0);
        slr_club = Closure(slr_club);//构造初始项目集 求闭包

        SLR_club SLR_C = new SLR_club();
        SLR_C.Container = slr_club;//集合----项目集序号的集合
        pro_club.Add(SLR_C);//集合的集合----存放项目集序号集合 的集合


        for (int i = 0; i < pro_club.Count; i++)//整体集合中 第i个项目集
        {
            pro_club[i].Container.Sort();//排序由小到大 后面用于判断是否存在的比较
            int[] flag = new int[pro_club[i].Container.Count];
            for (int fi = 0; fi < pro_club[i].Container.Count; fi++)//标志位,用来判断该序号是否已经构造
            {
                flag[fi] = 0;
            }

            for (int j = 0; j < pro_club[i].Container.Count; j++)//第i个项目集的第j个项目
            {
                if (flag[j] == 1)//如果已经访问过 就不再构造 找下一个项目
                    continue;
                int index = pro_club[i].Container[j];
                for (int pi = 0; pi < SLRobjNum[index].Right.Length - 1; pi++)//length-1是避免匹配到.在最后的规约项目
                {
                    if (SLRobjNum[index].Right[pi] == '.')
                    {

                        List<int> slr2_club = new List<int>(100);//记录项目的序号
                        char symbol = SLRobjNum[index].Right[pi + 1];//记录.a转移状态a.的符号a
                        slr2_club.Add((index + 1));//如果遇到.a形式的项目序号为index 那么项目a.的序号为index+1
                        for (int m1 = j + 1; m1 < pro_club[i].Container.Count; m1++)
                        {//在第i个项目集中找到了可以移动的.:.a  重新遍历第i个项目集j项目之后的 找到同样可以移动a的项目集
                            int index2 = pro_club[i].Container[m1];
                            for (int m2 = 0; m2 < SLRobjNum[index2].Right.Length - 1; m2++)
                            {
                                if (SLRobjNum[index2].Right[m2] == '.' && SLRobjNum[index2].Right[m2 + 1] == symbol)
                                {
                                    flag[m1] = 1;//标记位置为1 已经访问 之后不再访问
                                    slr2_club.Add(index2 + 1);
                                }
                            }
                        }
                        slr2_club = Closure(slr2_club);//求闭包
                        int value = isexist(slr2_club);
                        if (value == -1)//-1表示不存在相同的
                        {
                            for (int m3 = 0; m3 < Gy_obj.Count; m3++)
                            {
                                if (isnexist(slr2_club, Gy_obj[m3]))
                                {
                                    Gy_club.Add(pro_club.Count);
                                }
                            }
                            SLR_club SLR_C2 = new SLR_club();
                            dfa[Pindex++] = new DFA(i, symbol, pro_club.Count);//count不用加1  本身从0开始
                            SLR_C2.Container = slr2_club;
                            pro_club.Add(SLR_C2);
                        }
                        else
                        {
                            dfa[Pindex++] = new DFA(i, symbol, value);
                        }
                        break;
                    }
                }
            }//end-forj
        }//end-fori

    }//end-Cre_club

    //构造ACTION和GOTO表
    public void Cre_table()
    {
        SLRAna = new Table[pro_club.Count][];
        for (int i = 0; i < pro_club.Count; i++)
        {
            SLRAna[i] = new Table[Echar.Count + Nchar.Count + 1];
            for (int j = 0; j < Echar.Count + Nchar.Count + 1; j++)
            {
                SLRAna[i][j] = new Table();
            }
        }

        for (int i = 0; i < pro_club.Count; i++)
        {
            for (int j = 0; j < pro_club[i].Container.Count; j++)
            {
                int index = pro_club[i].Container[j];
                for (int k = 0; k < Echar.Count; k++)//Echar为终结符集合
                {
                    char ch = Echar[k];
                    if (SLRobjNum[index].Right.Contains('.'))
                    {
                        if (SLRobjNum[index].Right.IndexOf('.') == SLRobjNum[index].Right.Length - 1)//最后一个字符是'.',表示可以规约
                        {
                            for (int m = 0; m < Gy_obj.Count; m++)
                            {
                                if (Gy_obj[m] == index)
                                {
                                    SLRAna[i][k] = new Table('r', m);
                                }
                            }
                        }
                        else
                        {
                            int to = Find_to(index, ch);
                            if (to != -1)
                            {
                                SLRAna[i][k] = new Table('s', to);
                            }
                        }
                    }
                }
                for (int k = 0; k < Nchar.Count; k++)//Nchar为非终结符集合
                {
                    char ch = Nchar[k];
                    if (SLRobjNum[index].Right.Contains('.'))
                    {
                        if (SLRobjNum[index].Right.IndexOf('.') == SLRobjNum[index].Right.Length - 1)//最后一个字符是'.',表示可以规约
                        {
                            for (int m = 0; m < Gy_obj.Count; m++)
                            {
                                if (Gy_obj[m] == index)
                                {
                                    SLRAna[i][Echar.Count + k] = new Table('r', m);
                                }
                            }
                        }
                        else
                        {
                            int to = Find_to(index, ch);
                            if (to != -1)
                            {
                                SLRAna[i][Echar.Count + k] = new Table('g', to);
                            }
                        }
                    }
                }
                if (SLRobjNum[index].Right.Contains('.'))
                {
                    if (SLRobjNum[index].Right.IndexOf('.') == SLRobjNum[index].Right.Length - 1)//最后一个字符是'.',表示可以规约
                    {
                        SLRAna[i][Echar.Count + Nchar.Count] = new Table('a', 0);
                    }
                }
            }
        }
    }

    //SLR分析器
    public void SLR_Analysis(string input)
    {
        Stack<int> stateStack = new Stack<int>();
        Stack<char> symbolStack = new Stack<char>();
        stateStack.Push(0);//初始状态
        symbolStack.Push('#');//初始符号
        int index = 0;
        while (index < input.Length)
        {
            int state = stateStack.Peek();
            char symbol = input[index];
            int col = -1;
            if (Echar.Contains(symbol))
            {
                col = Echar.IndexOf(symbol);
            }
            else if (Nchar.Contains(symbol))
            {
                col = Nchar.IndexOf(symbol) + Echar.Count;
            }
            if (SLRAna[state][col].error)
            {
                Success = false;
                break;
            }
            else if (SLRAna[state][col].type == 's')
            {
                stateStack.Push(SLRAna[state][col].id);
                symbolStack.Push(symbol);
                index++;
            }
            else if (SLRAna[state][col].type == 'r')
            {
                int num = SLRAna[state][col].id;
                SLRproNode node = SLRproNum[num];
                for (int i = 0; i < node.Right.Length; i++)
                {
                    stateStack.Pop();
                    symbolStack.Pop();
                }
                int newState = stateStack.Peek();
                symbolStack.Push(node.Left[0]);
                int col2 = -1;
                if (Nchar.Contains(node.Left[0]))
                {
                    col2 = Nchar.IndexOf(node.Left[0]) + Echar.Count;
                }
                stateStack.Push(SLRAna[newState][col2].id);
SLR 分析器 C# 代码实现

原文地址: https://www.cveoy.top/t/topic/f0lp 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录