//获取LR0分析表
public Table[][] GET_ANA()
{
    if (SLRAna == null)
    {
        SLRAnaly();
    }
    return SLRAna;
}

//构造分析表
public void SLRAnaly()
{
    //获取Follow集
    GetFollow();

    //初始化分析表
    SLRAna = new Table[proitemset.Count][];
    for (int i = 0; i < proitemset.Count; i++)
    {
        SLRAna[i] = new Table[Echar.Count + 1];
        for (int j = 0; j < Echar.Count + 1; j++)
        {
            SLRAna[i][j] = new Table();
        }
    }

    //填充移进和归约项
    for (int i = 0; i < proitemset.Count; i++)
    {
        foreach (int index in proitemset[i].Container)
        {
            SLRNode node = SLRobjNum[index];
            if (node.Right.IndexOf('.') < node.Right.Length - 1) //移进项
            {
                char symbol = node.Right[node.Right.IndexOf('.') + 1];
                int j = Echar.IndexOf(symbol);
                if (j == -1)
                {
                    j = Echar.Count;
                }
                SLRAna[i][j] = new Table('S', dfa[Pindex++].to);
            }
            else //归约项
            {
                foreach (char symbol in Follow(node.Left[0]))
                {
                    int j = Echar.IndexOf(symbol);
                    if (j == -1)
                    {
                        j = Echar.Count;
                    }
                    if (!SLRAna[i][j].error)
                    {
                        Console.WriteLine('冲突:项目集' + i + '在' + symbol + '上有移进和归约冲突');
                        Success = false;
                        return;
                    }
                    SLRAna[i][j] = new Table('R', index);
                }
            }
        }
    }

    //填充接受项
    int acceptIndex = proitemset.Count - 1;
    SLRAna[acceptIndex][Echar.Count] = new Table('A', 0);
}


//获取非终结符的Follow集
public void GetFollow()
{
    //初始化Follow集
    foreach (char c in Nchar)
    {
        follow[c] = new HashSet<char>();
    }
    follow['S\''] = new HashSet<char> { '#' };

    //迭代计算Follow集
    bool flag = true;
    while (flag)
    {
        flag = false;
        foreach (SLRNode node in SLRproNum)
        {
            string right = node.Right;
            for (int i = 0; i < right.Length; i++)
            {
                if (isFinalsymbol(right[i]))
                {
                    continue;
                }
                char A = right[i];
                string beta = right.Substring(i + 1);
                HashSet<char> betaFirst = First(beta);
                int oldCount = follow[A].Count;
                if (betaFirst.Contains('#'))
                {
                    follow[A].UnionWith(follow[node.Left[0]]);
                }
                betaFirst.Remove('#');
                follow[A].UnionWith(betaFirst);
                int newCount = follow[A].Count;
                if (newCount > oldCount)
                {
                    flag = true;
                }
            }
        }
    }
}

//获取字符串的First集
public HashSet<char> First(string str)
{
    HashSet<char> first = new HashSet<char>();
    if (str.Length == 0)
    {
        first.Add('#');
        return first;
    }
    if (isFinalsymbol(str[0]))
    {
        first.Add(str[0]);
        return first;
    }
    foreach (SLRNode node in SLRproNum)
    {
        if (node.Left[0] == str[0])
        {
            string beta = str.Substring(1);
            HashSet<char> betaFirst = First(beta);
            int oldCount = first.Count;
            if (betaFirst.Contains('#'))
            {
                first.UnionWith(betaFirst);
                first.Remove('#');
                first.UnionWith(Follow(node.Left[0]));
            }
            else
            {
                first.UnionWith(betaFirst);
            }
            int newCount = first.Count;
            if (newCount > oldCount)
            {
                break;
            }
        }
    }
    return first;
}

//获取非终结符的Follow集
public HashSet<char> Follow(char nonTerminal)
{
    return follow[nonTerminal];
}
SLR(1)分析器的构建:从代码实现到示例解析

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

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