using System;
using System.Collections.Generic;
using System.Linq;

// ... 其他代码 ...

public List<int> Closure(List<int> I)
{
    bool flag = true;
    while (flag)
    {
        flag = false;
        for (int index = 0; index < I.Count; index++)
        {
            for (int i = 0; i < SLRobjNum[I[index]].Right.Length - 1; i++)
            {
                if (SLRobjNum[I[index]].Right[i] == '.' && !isFinalsymbol(SLRobjNum[I[index]].Right[i + 1]))
                {
                    char A = SLRobjNum[I[index]].Right[i + 1];
                    HashSet<char> followA = new HashSet<char>();
                    if (i + 2 < SLRobjNum[I[index]].Right.Length)
                    {
                        followA = First(SLRobjNum[I[index]].Right.Substring(i + 2));
                    }
                    else if (follow.ContainsKey(SLRobjNum[I[index]].Left[0]))
                    {
                        followA = follow[SLRobjNum[I[index]].Left[0]];
                    }
                    for (int j = 0; j < SLRobjNum.Count; j++)
                    {
                        if (isnexist(I, j))
                            continue;
                        if (SLRobjNum[j].Left == A.ToString() && SLRobjNum[j].Right[0] == '.')
                        {
                            foreach (char c in followA)
                            {
                                if (SLRobjNum[j].Follow.Add(c))
                                    flag = true;
                            }
                            if (!I.Contains(j))
                                I.Add(j);
                        }
                    }
                }
            }
        }
    }
    return I;
}

public int Goto(List<int> I, char X)
{
    List<int> J = new List<int>();
    for (int i = 0; i < I.Count; i++)
    {
        int index = I[i];
        if (SLRobjNum[index].Right.Contains('.'))
        {
            int dotIndex = SLRobjNum[index].Right.IndexOf('.');
            if (dotIndex + 1 < SLRobjNum[index].Right.Length && SLRobjNum[index].Right[dotIndex + 1] == X)
            {
                string tmp = SLRobjNum[index].Right.Remove(dotIndex, 1);
                tmp = tmp.Insert(dotIndex + 1, '.');
                SLRNode node = new SLRNode(SLRobjNum[index].Left, tmp);
                // 将Follow集传递给新的项目
                node.Follow = SLRobjNum[index].Follow;
                if (!SLRobjNum.Any(n => n.Left == node.Left && n.Right == node.Right && n.Follow.SetEquals(node.Follow)))
                {
                    SLRobjNum.Add(node);
                    J.Add(SLRobjNum.Count - 1);
                }
            }
        }
    }
    return isnexist(J) ? -1 : isnexist(J) ? -1 : proitemset.Count;
}

public Table[][] GET_ANA()
{
    SLRAnaly();
    RStr_ANA += '\r\nSLR(1)分析表:\r\n    ';
    int i;
    for (i = 0; i < Echar.Count; i++)
    {
        RStr_ANA += Echar[i].ToString() + '     ';
    }
    for (i = 0; i < Nchar.Count; i++)
    {
        RStr_ANA += Nchar[i].ToString() + '     ';
    }
    RStr_ANA += '\r\n';
    for (i = 0; i < proitemset.Count; i++)
    {
        RStr_ANA += i.ToString() + '  ';
        for (int j = 0; j < Echar.Count + Nchar.Count; j++)
        {
            if (SLRAna[i][j].error)
            {
                RStr_ANA += '  ' + '    ';
            }
            else if (i == 1 && j == Echar.Count - 1)
            {
                RStr_ANA += 'AC' + '    ';
            }
            else if (SLRAna[i][j].type != 'N')
            {
                RStr_ANA += SLRAna[i][j].type.ToString() + SLRAna[i][j].id.ToString() + '    ';
            }
            else
                RStr_ANA += SLRAna[i][j].id.ToString() + '    ';
        }
        RStr_ANA += '\r\n';
    }

    return SLRAna;
}

// ... 其他代码 ...

代码解释:

  1. SLRNode类修改:SLRNode类添加一个HashSet<char> Follow字段,用于存储每个项目的Follow集。
  2. Closure函数修改:
    • 在原有逻辑的基础上,使用Follow集判断是否需要将新的项目加入到闭包中。
    • 当遇到.A形式的项目时,获取A的Follow集followA
    • 遍历所有以A开头的项目,如果该项目的Follow集中包含followA中的任何一个字符,则将该项目加入到闭包中,并将flag设置为true,表示需要继续进行闭包运算。
  3. Goto函数修改:
    • 在创建新的项目时,将原项目的Follow集传递给新的项目。
    • 在将新的项目加入到项目集之前,检查该项目是否已经存在于项目集中。
  4. GET_ANA函数修改:
    • 将函数名修改为GET_ANA,并修改输出的分析表类型为SLR(1)分析表。

注意:

  • 上述代码中省略了部分函数的实现,例如isFinalsymbolFirstisnexistSLRAnaly等函数。你需要根据自己的实际情况进行实现。
  • 在实际应用中,还需要根据具体的SLR(1)文法进行相应的调整。

希望以上代码和解释能够帮助你理解如何将LR(0)分析器代码转换为SLR(1)分析器代码。

LR(0)分析器到SLR(1)分析器的转换:C#代码示例

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

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