class Select
{
    LL1Item LL1Item;
    First first;
    Follow follow;
    Dictionary<string, Dictionary<string, List<string>>> selects;

    public Select(LL1Item LL1Item, First first, Follow follow)
    {
        this.LL1Item = LL1Item;
        this.first = first;
        this.follow = follow;
        selects = new Dictionary<string, Dictionary<string, List<string>>>();
        GetSelect();
    }

    public void GetSelect()
    {
        var production = LL1Item.getproduction();
        foreach (var nofinal in LL1Item.nofinal)
        {
            selects.Add(nofinal, new Dictionary<string, List<string>>());
            //对非终结符的每个产生式获取select值
            foreach (var f in production[nofinal])
            {
                selects[nofinal].Add(f, new List<string>());
                for (int i = 0; i < f.Length; i++)
                {
                    //如果该产生式第一个字符为终结符
                    if (IsTerminal(f[i]))
                    {
                        if (f[i].Equals('#'))
                        {
                            foreach (var fol in follow.getfollows()[nofinal])
                                selects[nofinal][f].Add(fol);
                        }
                        else if (!selects[nofinal][f].Contains(f[i].ToString()))
                            selects[nofinal][f].Add(f[i].ToString());
                        break;
                    }
                    //如果该产生式第一个字符为非终结符
                    else
                    {
                        int flag = 0;
                        foreach (var fir in first.getfirsts()[f[i].ToString()])
                        {
                            if (fir.Equals('#'))
                                flag = 1;
                            else
                            {
                                if (!selects[nofinal][f].Contains(fir))
                                    selects[nofinal][f].Add(fir);
                            }
                        }
                        if (flag == 0) break;
                    }
                    if (i == f.Length - 1)
                    {
                        foreach (var fol in follow.getfollows()[nofinal])
                            if (!selects[nofinal][f].Contains(fol))
                                selects[nofinal][f].Add(fol);
                    }
                }
            }
        }
    }
    static bool IsTerminal(char symbol)
    {
        return !char.IsUpper(symbol);
    }

    public Dictionary<string, Dictionary<string, List<string>>> getselects()
    {
        return selects;
    }
}

// 不使用 LL1Item 的 GetSelect 函数实现
private Dictionary<string, List<string>> GetSelect(Dictionary<string, List<string>> production1, Dictionary<string, List<string>> firsts1, Dictionary<string, List<string>> follows1)
{
    // 初始化 SELECT 集
    Dictionary<string, List<string>> selects1 = new Dictionary<string, List<string>>();
    foreach (var item in production1)
        selects1.Add(item.Key, new List<string>());

    // 遍历每个产生式,计算对应的 SELECT 集
    foreach (var nonterm in production1.Keys)
    {
        foreach (var prod in production1[nonterm])
        {
            List<string> select = new List<string>();
            bool flag = true;
            // 对于产生式中的每个符号,计算其 FIRST 集
            foreach (var s in prod)
            {
                if (IsTerminal(s))
                {
                    select.Add(s.ToString());
                    flag = false;
                    break;
                }
                else
                {
                    GetFirst(s.ToString(), production1, firsts1);
                    foreach (var f in firsts1[s.ToString()])
                    {
                        if (!f.Equals('#') && !select.Contains(f))
                            select.Add(f);
                    }
                    if (!IsReachEmpty(s.ToString(), production1))
                    {
                        flag = false;
                        break;
                    }
                }
            }
            // 如果产生式中所有符号的 FIRST 集都包含空串,则将 FOLLOW 集加入 SELECT 集中
            if (flag)
            {
                GetFollow(nonterm, production1, firsts1, follows1);
                foreach (var f in follows1[nonterm])
                {
                    if (!select.Contains(f))
                        select.Add(f);
                }
            }
            selects1[nonterm].Add(string.Join("", select.ToArray()));
        }
    }
    return selects1;
}

// 补充 GetFirst 和 IsReachEmpty 函数实现,以及 GetFollow 函数
// ...
C#实现LL(1)文法分析器:SELECT集计算函数

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

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