以下是使用SLR文法构造分析表的代码,主要是在LRAnaly()函数中进行修改:

public void SLRAnaly() { Table tnode = new Table();

SLRAna = new Table[proitemset.Count][];
for (int i = 0; i < proitemset.Count; i++)
    SLRAna[i] = new Table[Echar.Count + Nchar.Count];

for (int i = 0; i < proitemset.Count; i++)//初始化 赋予ERROR属性
    for (int j = 0; j < Echar.Count + Nchar.Count; j++)//为终结符加r状态 
        SLRAna[i][j] = tnode;

tnode = new Table('A', 0);
SLRAna[1][FindID(Echar, '#')] = tnode;//项目集1必定是接受项目   构建[1][#]:acc的情况 先直接赋值好 dfa里没有

for (int i = 0; i < Gy_obj.Count; i++)//归约项目
{
    int proNum = Find_pro(LRobjNum[Gy_obj[i]]);
    List<char> follow = Follow(LRproNum[proNum].left);
    for (int j = 0; j < follow.Count; j++)
    {
        int CID = FindID(Echar, follow[j]);
        tnode = new Table('r', proNum);
        SLRAna[Gy_itemset[i]][CID] = tnode;
    }
}
for (int i = 0; i < proitemset.Count; i++)
{
    for (int j = 0; j < Echar.Count; j++)
    {
        List<int> Goto = GOTO(i, Echar[j]);
        if (Goto.Count > 0)
        {
            if (Gy_itemset.Contains(i) && Goto.Count > 1)//移进-归约冲突
            {
                int proNum = Find_pro(LRobjNum[proitemset[Goto[0]].Container[0]]);
                List<char> follow = Follow(LRproNum[proNum].left);
                if (follow.Contains(Echar[j]))//如果follow集中包含当前终结符
                {
                    tnode = new Table('r', proNum);
                    SLRAna[i][j] = tnode;
                }
                else
                {
                    tnode = new Table('E', -1);
                    SLRAna[i][j] = tnode;
                }
            }
            else if (Gy_itemset.Contains(i) && Goto.Count == 1)//归约-归约冲突
            {
                int proNum1 = Find_pro(LRobjNum[proitemset[i].Container[0]]);
                int proNum2 = Find_pro(LRobjNum[proitemset[Goto[0]].Container[0]]);
                if (proNum1 > proNum2)
                {
                    tnode = new Table('r', proNum1);
                    SLRAna[i][j] = tnode;
                }
                else
                {
                    tnode = new Table('r', proNum2);
                    SLRAna[i][j] = tnode;
                }
            }
            else
            {
                tnode = new Table('s', Goto[0]);
                SLRAna[i][j] = tnode;
            }
        }
    }
    for (int j = 0; j < Nchar.Count; j++)
    {
        List<int> Goto = GOTO(i, Nchar[j]);
        if (Goto.Count > 0)
        {
            tnode = new Table('N', Goto[0]);
            SLRAna[i][j + Echar.Count] = tnode;
        }
    }
}

}

其中,Follow()函数用于求某个非终结符的Follow集,GOTO()函数用于求某个项目集在某个符号下的Goto集合。

完整代码如下:

public class Table { public char type; public int id; public bool error; public Table(char t, int i) { type = t; id = i; error = false; } public Table() { error = true; } }

public class SLRNode { public int left; public string right; public int dot; public SLRNode(int l, string r, int d) { left = l; right = r; dot = d; } }

public class SLRitemsets { public List Container; public List Symbol; public SLRitemsets(List c, List s) { Container = c; Symbol = s; } }

public class Analyze { public DFA[] dfa = new DFA[100]; public int Pindex = 0; //dfa数组指针 public Table[][] SLRAna;//分析表 public Analyze Jz; public bool Success = false; public List SLRproNum = new List(50);//产生式 列表 public List SLRobjNum = new List(50);//项目 列表 public List proitemset = new List(100);//项目集合 public List Gy_obj = new List(50);//归约项目序号集合 public List Gy_itemset = new List(50);//含有归约项目的集合的序号 的集合 public List Nchar = new List(50);//非终结符集合 public List Echar = new List(50);//终结符集合

public string RStr = "";
public string RStr_obitemset = "";//输出返回
public string RStr_DFA = "";
public string RStr_ANA = "";

public void SLRAnaly()
{
    Table tnode = new Table();

    SLRAna = new Table[proitemset.Count][];
    for (int i = 0; i < proitemset.Count; i++)
        SLRAna[i] = new Table[Echar.Count + Nchar.Count];

    for (int i = 0; i < proitemset.Count; i++)//初始化 赋予ERROR属性
        for (int j = 0; j < Echar.Count + Nchar.Count; j++)//为终结符加r状态 
            SLRAna[i][j] = tnode;

    tnode = new Table('A', 0);
    SLRAna[1][FindID(Echar, '#')] = tnode;//项目集1必定是接受项目   构建[1][#]:acc的情况 先直接赋值好 dfa里没有

    for (int i = 0; i < Gy_obj.Count; i++)//归约项目
    {
        int proNum = Find_pro(LRobjNum[Gy_obj[i]]);
        List<char> follow = Follow(LRproNum[proNum].left);
        for (int j = 0; j < follow.Count; j++)
        {
            int CID = FindID(Echar, follow[j]);
            tnode = new Table('r', proNum);
            SLRAna[Gy_itemset[i]][CID] = tnode;
        }
    }
    for (int i = 0; i < proitemset.Count; i++)
    {
        for (int j = 0; j < Echar.Count; j++)
        {
            List<int> Goto = GOTO(i, Echar[j]);
            if (Goto.Count > 0)
            {
                if (Gy_itemset.Contains(i) && Goto.Count > 1)//移进-归约冲突
                {
                    int proNum = Find_pro(LRobjNum[proitemset[Goto[0]].Container[0]]);
                    List<char> follow = Follow(LRproNum[proNum].left);
                    if (follow.Contains(Echar[j]))//如果follow集中包含当前终结符
                    {
                        tnode = new Table('r', proNum);
                        SLRAna[i][j] = tnode;
                    }
                    else
                    {
                        tnode = new Table('E', -1);
                        SLRAna[i][j] = tnode;
                    }
                }
                else if (Gy_itemset.Contains(i) && Goto.Count == 1)//归约-归约冲突
                {
                    int proNum1 = Find_pro(LRobjNum[proitemset[i].Container[0]]);
                    int proNum2 = Find_pro(LRobjNum[proitemset[Goto[0]].Container[0]]);
                    if (proNum1 > proNum2)
                    {
                        tnode = new Table('r', proNum1);
                        SLRAna[i][j] = tnode;
                    }
                    else
                    {
                        tnode = new Table('r', proNum2);
                        SLRAna[i][j] = tnode;
                    }
                }
                else
                {
                    tnode = new Table('s', Goto[0]);
                    SLRAna[i][j] = tnode;
                }
            }
        }
        for (int j = 0; j < Nchar.Count; j++)
        {
            List<int> Goto = GOTO(i, Nchar[j]);
            if (Goto.Count > 0)
            {
                tnode = new Table('N', Goto[0]);
                SLRAna[i][j + Echar.Count] = tnode;
            }
        }
    }
}

public List<int> GOTO(int itemset, char symbol)
{
    List<int> Goto = new List<int>();
    for (int i = 0; i < proitemset[itemset].Container.Count; i++)
    {
        int index = proitemset[itemset].Container[i];
        if (SLRobjNum[index].dot < SLRobjNum[index].right.Length && SLRobjNum[index].right[SLRobjNum[index].dot] == symbol)
        {
            SLRNode node = new SLRNode(SLRobjNum[index].left, SLRobjNum[index].right, SLRobjNum[index].dot + 1);
            int num = Find_itemset(node);
            if (!Goto.Contains(num))
                Goto.Add(num);
        }
    }
    return Goto;
}

public List<char> Follow(int left)
{
    List<char> follow = new List<char>();
    if (left == 0)//S'
        follow.Add('#');
    for (int i = 0; i < SLRproNum.Count; i++)
    {
        for (int j = 0; j < SLRproNum[i].right.Length; j++)
        {
            if (SLRproNum[i].left == left)
            {
                if (j == SLRproNum[i].right.Length - 1)//A->αB
                {
                    if (SLRproNum[i].left != left)//避免无限递归
                    {
                        List<char> f = Follow(SLRproNum[i].left);
                        for (int k = 0; k < f.Count; k++)
                        {
                            if (!follow.Contains(f[k]))
                                follow.Add(f[k]);
                        }
                    }
                }
                else//A->αBβ
                {
                    if (isNonterminal(SLRproNum[i].right[j + 1]))//B->γD
                    {
                        List<char> first = First(SLRproNum[i].right[j + 1]);
                        for (int k = 0; k < first.Count; k++)
                        {
                            if (first[k] != 'ε' && !follo
public DFA dfa = new DFA100; public int Pindex = 0; dfa数组指针 public Table SLRAna;分析表 public Analyze Jz; public bool Success = false; public ListSLRNode SLRproNum = ne

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

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