SLR分析表生成算法实现

public void SLRAnaly()
{
    SLRAna = new Table[proitemset.Count][];
    for (int i = 0; i < proitemset.Count; i++)
    {
        SLRAna[i] = new Table[Echar.Count + Nchar.Count];
        for (int j = 0; j < Echar.Count + Nchar.Count; j++)
        {
            SLRAna[i][j] = new Table();
        }
    }

    //遍历每个状态
    for (int i = 0; i < proitemset.Count; i++)
    {
        //遍历每个终结符
        for (int j = 0; j < Echar.Count; j++)
        {
            bool flag = false;
            int index = -1;
            //遍历移进项
            for (int k = 0; k < proitemset[i].Container.Count; k++)
            {
                int itemIndex = proitemset[i].Container[k];
                if (SLRobjNum[itemIndex].Right.Contains('.') && SLRobjNum[itemIndex].Right.IndexOf('.') < SLRobjNum[itemIndex].Right.Length - 1 && SLRobjNum[itemIndex].Right[SLRobjNum[itemIndex].Right.IndexOf('.') + 1] == Echar[j])
                {
                    flag = true;
                    index = k;
                    break;
                }
            }
            if (flag)
            {
                SLRAna[i][j] = new Table('S', proitemset[Move(proitemset[i], Echar[j])][index + 1]);
            }
            else
            {
                SLRAna[i][j] = new Table();
            }
        }

        //遍历每个非终结符
        for (int j = 0; j < Nchar.Count; j++)
        {
            int index = -1;
            //遍历移进项
            for (int k = 0; k < proitemset[i].Container.Count; k++)
            {
                int itemIndex = proitemset[i].Container[k];
                if (SLRobjNum[itemIndex].Right.Contains('.') && SLRobjNum[itemIndex].Right.IndexOf('.') < SLRobjNum[itemIndex].Right.Length - 1 && SLRobjNum[itemIndex].Right[SLRobjNum[itemIndex].Right.IndexOf('.') + 1] == Nchar[j])
                {
                    index = k;
                    break;
                }
            }
            if (index != -1)
            {
                SLRAna[i][Echar.Count + j] = new Table('S', proitemset[Move(proitemset[i], Nchar[j])][index + 1]);
            }
            else
            {
                SLRAna[i][Echar.Count + j] = new Table();
            }
        }

        //遍历归约项
        for (int j = 0; j < Gy_obj.Count; j++)
        {
            int itemIndex = Gy_obj[j];
            if (proitemset[i].Container.Contains(itemIndex))
            {
                foreach (char c in Follow(SLRobjNum[itemIndex].Left))
                {
                    if (SLRAna[i][GetIndex(c)].error)
                    {
                        SLRAna[i][GetIndex(c)] = new Table('r', itemIndex);
                    }
                    else
                    {
                        Console.WriteLine("Conflict: state " + i + " " + c + " " + SLRAna[i][GetIndex(c)].type + SLRAna[i][GetIndex(c)].id + " r" + itemIndex);
                    }
                }
            }
        }
    }

    //处理接受状态
    int acceptState = -1;
    for (int i = 0; i < proitemset.Count; i++)
    {
        if (proitemset[i].Container.Contains(0))
        {
            acceptState = i;
            break;
        }
    }
    SLRAna[acceptState][GetIndex('#')] = new Table('A', 0);
}

//获取符号在分析表中的索引
private int GetIndex(char c)
{
    if (isFinalsymbol(c))
    {
        return Echar.IndexOf(c);
    }
    else
    {
        return Echar.Count + Nchar.IndexOf(c);
    }
}

//求FOLLOW集
private List<char> Follow(string symbol)
{
    List<char> followSet = new List<char>();
    if (symbol == "S'")
    {
        followSet.Add('#');
    }
    foreach (SLRNode node in SLRproNum)
    {
        int index = node.Right.IndexOf(symbol);
        if (index != -1 && index < node.Right.Length - 1)
        {
            List<char> firstSet = First(node.Right.Substring(index + 1));
            if (firstSet.Contains('#'))
            {
                followSet.AddRange(Follow(node.Left));
                followSet.Remove('#');
            }
            followSet.AddRange(firstSet);
        }
    }
    return followSet;
}

//求FIRST集
private List<char> First(string str)
{
    List<char> firstSet = new List<char>();
    if (str == "#" )
    {
        firstSet.Add('#');
        return firstSet;
    }
    if (isFinalsymbol(str[0]))
    {
        firstSet.Add(str[0]);
        return firstSet;
    }
    foreach (SLRNode node in SLRproNum)
    {
        if (node.Left == str[0].ToString())
        {
            List<char> tempSet = First(node.Right);
            firstSet.AddRange(tempSet);
            if (tempSet.Contains('#'))
            {
                firstSet.Remove('#');
                firstSet.AddRange(First(str.Substring(1)));
            }
            return firstSet;
        }
    }
    return firstSet;
}

private List<int> Move(SLRitemsets itemset, char symbol)
{
    List<int> moveSet = new List<int>();
    foreach (int index in itemset.Container)
    {
        int dotIndex = SLRobjNum[index].Right.IndexOf('.');
        if (dotIndex != -1 && dotIndex < SLRobjNum[index].Right.Length - 1 && SLRobjNum[index].Right[dotIndex + 1] == symbol)
        {
            moveSet.Add(index + 1);
        }
    }
    return Closure(moveSet);
}

代码说明:

  • 该代码实现了SLR分析表生成算法,其中SLRAna是一个二维数组,用于存储分析表。
  • 代码首先遍历每个状态和每个符号,根据当前状态和符号,确定相应的动作(移进、归约或接受)。
  • 在处理移进动作时,需要调用Move函数来计算新的状态,并使用proitemset[Move(proitemset[i], Nchar[j])][index + 1]来获取新的状态对应的项目集中的项目索引。
  • 在处理归约动作时,需要计算当前状态对应符号的FOLLOW集,并根据FOLLOW集中的符号进行相应的归约。
  • 最后,处理接受状态,将接受状态对应的符号设置为'A',表示接受。

注意事项:

  • 代码中需要根据具体情况调整相关变量和函数的定义和实现。
  • 代码中的注释部分解释了代码的逻辑和算法步骤,方便读者理解代码的功能。
  • 代码中使用了泛型List类型,方便存储和操作数据。
  • 代码中使用了string类型来表示符号,并使用IndexOf函数来查找符号在字符串中的位置。
  • 代码中使用了Contains函数来判断一个集合是否包含某个元素。

代码示例:

// 示例代码,演示SLR分析表生成算法的使用
// 假设已经定义了proitemset、Echar、Nchar、SLRobjNum、Gy_obj、SLRproNum等变量和函数
// 调用SLRAnaly函数生成SLR分析表
SLRAnaly();

// 打印分析表
for (int i = 0; i < SLRAna.Length; i++)
{
    for (int j = 0; j < SLRAna[i].Length; j++)
    {
        Console.Write(SLRAna[i][j].ToString() + " ");
    }
    Console.WriteLine();
}

总结:

本文介绍了SLR分析表生成算法的实现,并提供了相应的代码示例,详细解释了算法的流程和关键步骤。该代码可以作为学习和参考,用于理解SLR分析表生成算法的原理和实现方法。

SLR分析表生成算法实现

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

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