至上而下LL(1)分析算法-FIRST集C#实现-词法分析器-编译原理

LL(1)的特点

  1. 表驱动
  2. 线性。
  3. 会有冲突。

可以用这个部分来学习分析表的知识。分析表会告诉分析栈一些信息。而分析表是根据语法自动生成的。
读入语法,生成了这个表。

其实就是之前的算法,每次压入时,压入的是正确的表达式

这个就是分析表的样子假设我要分析的是我自己写的一个语法,如下:

A=B

       |空

B =C C

       |C

C= D E F

D=G 

       |空

G= a a

       |a

E=H

       |空

H=b b

       |b

F=c c

       |c

第一件事,先构造FIRST集
FIRST(N)表示从非终结符N开始推到得出的句子开头的所有可能终结符集合。
那么对于N=a…a是终结符
FIRST(N) 并={a}
对于N=M,M是非终结符
FIRST(N)并FIRST(M)

课程来自https://www.bilibili.com/video/BV17W41187gL?p=49
5.1.3

直接在unity里面写了一个:

    public List<string> tokens;//当前给出的词法内容
    public string S_token;//起始token
    public List<string> N_token;//非终结符
    public List<string> T_token;//终结符
    public Dictionary<string, List<string>> generator_dict;//产生式表
    public Dictionary<string, List<string>> FIRST;//FIRST集
    public string empty_token = "%";
    // Start is called before the first frame update
    void Start()
    {
        generator_dict = new Dictionary<string, List<string>>();
        //建立产生式表A的
        List<string> tempA = new List<string>();
        tempA.Add("B");
        tempA.Add(empty_token);
        generator_dict["A"] = tempA;        //建立产生式表B的
        List<string> tempB = new List<string>();
        tempB.Add("CC");
        tempB.Add("C");
        generator_dict["B"] = tempB;        //建立产生式表C的
        List<string> tempC = new List<string>();
        tempC.Add("DEF");
        generator_dict["C"] = tempC;        //建立产生式表D的
        List<string> tempD = new List<string>();
        tempD.Add("G");
        tempD.Add(empty_token);
        generator_dict["D"] = tempD;        //建立产生式表G的
        List<string> tempG = new List<string>();
        tempG.Add("aa");
        tempG.Add("a");
        generator_dict["G"] = tempG;        //建立产生式表E的
        List<string> tempE = new List<string>();
        tempE.Add("H");
        tempE.Add(empty_token);
        generator_dict["E"] = tempE;        //建立产生式表H的
        List<string> tempH = new List<string>();
        tempH.Add("bb");
        tempH.Add("b");
        generator_dict["H"] = tempH;        //建立产生式表F的
        List<string> tempF = new List<string>();
        tempF.Add("cc");
        tempF.Add("c");
        generator_dict["F"] = tempF;        //开始符
        S_token = "A";
        //非终结符
        N_token = new List<string>();
        N_token.Add("A");
        N_token.Add("B");
        N_token.Add("C");
        N_token.Add("D");
        N_token.Add("E");
        N_token.Add("F");
        N_token.Add("G");
        N_token.Add("H");
        //终结符
        T_token = new List<string>();
        T_token.Add("a");
        T_token.Add("b");
        T_token.Add("c");
        Create_First_Set();
    }    // Update is called once per frame    public void Create_First_Set()
    {
        FIRST = new Dictionary<string, List<string>>();
        foreach (string N in N_token)//轮询所有非终结符
        {
            FIRST[N] = new List<string>();//初始化成空集
        }
        bool still_changing = true;        while (still_changing)
        {
            //克隆了一份
            Dictionary<string, List<string>> NEWFIRST = new Dictionary<string, List<string>>();
            foreach (KeyValuePair<string, List<string>> kvp in FIRST)
            {
                List<string> templist = new List<string>();
                foreach (string a in kvp.Value)
                {
                    templist.Add(a);
                }
                NEWFIRST[kvp.Key] = templist;
            }            foreach (string N in N_token)//轮询所有非终结符
            {
                foreach (string EveryString in generator_dict[N])//对于所有非终结符的产生式。
                {
                    Debug.Log(EveryString);
                    char[] c_List = EveryString.ToCharArray();
                    foreach (char C in c_List)
                    {
                        if (N_token.Contains(C.ToString()))
                        {
                            //如果是非终结符,并集(处理了一遍)
                            FIRST[N]=FIRST[N].Union(FIRST[C.ToString()]).ToList();
                        }
                        else if (T_token.Contains(C.ToString()))
                        {
                            //如果是终结符直接加入。
                            List<string> newt = new List<string>();
                            newt.Add(C.ToString());
                            FIRST[N] = FIRST[N].Union(newt).ToList();
                        }
                    }
                }
                Debug.Log("下一个");
            }
            //判断是否变化了
            bool dictionariesEqual = Equal_dict(NEWFIRST,FIRST);
            still_changing = !dictionariesEqual;        }
        //这里应该产生了一个集了。
        Debug.Log(FIRST);
    }
制造出来的FIRST集是
A=abc
B=abc
C=abc
D=a
E=b
F=c
G=a
H=b
和文法符合!
接下来就是要制造Follow集来包容空集的情况,后面一篇文章更新。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值