{ //产生式结点类 public class SLRNode { public string Left; public string Right; public SLRNode(string Left, string Right) { this.Left = Left; this.Right = Right; } } //项目集类 public class SLRitemsets { public List Container = new List(100); //记录项目在项目集合中的序号 }

//DFA结点
public struct DFA
{
    public int from;
    public char symbol;
    public int to;
    public DFA(int from, char symbol, int to)
    {
        this.from = from;
        this.symbol = symbol;
        this.to = to;
    }
}

//分析表 结点
public class Table
{
    public bool error;//是否为ERROR
    public char type;//结点类型
    public int id;//数值
    public Table()
    {
        this.error = true;
    }
    public Table(char type, int id)
    {
        this.type = type;
        this.id = id;
        this.error = false;
    }
}

public DFA[] dfa = new DFA[100];
public int Pindex = 0; //dfa数组指针
public Table[][] SLRAna;//分析表

public bool Success = false;
public List<SLRNode> SLRproNum = new List<SLRNode>(50);//产生式 列表
public List<SLRNode> SLRobjNum = new List<SLRNode>(50);//项目 列表
public List<SLRitemsets> proitemset = new List<SLRitemsets>(100);//项目集合
public List<int> Gy_obj = new List<int>(50);//归约项目序号集合
public List<int> Gy_itemset = new List<int>(50);//含有归约项目的集合的序号 的集合
public List<char> Nchar = new List<char>(50);//非终结符集合
public List<char> Echar = new List<char>(50);//终结符集合
public string RStr_obitemset = ""; // 项目集构建过程中的输出信息


public void Buildprod(string str)
{

    SLRNode Lr;
    int i = 0;
    string left = "";
    string right = "";
    left += 'S';
    left += ''';
    right += str[0];
    Lr = new SLRNode(left, right);//拓广文法开始
    SLRproNum.Add(Lr);
    while (i < str.Length)
    {
        left = right = "";//还原
        int j = i;
        while (i < str.Length && str[i] != '\r' && str[i] != '\n')//换行符‘\r\n’
        {
            if (str[i] == ' ')
            {
                i++;
                continue;
            }
            if (str[i] == '|')                 //  遇到'|'可构造一条产生式
            {
                Lr = new SLRNode(left, right);
                SLRproNum.Add(Lr);
                right = "";                    //产生式左边相同 右边重新积累
                i++;                           //跳过'|'
                continue;
            }
            if ((i - j) == 0)
            {
                if (!exist(Nchar, str[i]))//如果非终结符集合中不存在str[i],加入Nchar  产生式左边 只有非终结符 不必判断终结符
                    Nchar.Add(str[i]);
                left += str[i++];
            }
            else if (i - j <= 2)
                i++;
            else
            {
                if (isFinalsymbol(str[i]) && !exist(Nchar, str[i]))//如果非终结符集合中不存在str[i],加入Nchar  isfinalsymbol 非终结符返回T 终结符返回F
                    Nchar.Add(str[i]);
                else if (!isFinalsymbol(str[i]) && !exist(Echar, str[i]))//产生式右边 需要判断终结符
                    Echar.Add(str[i]);
                right += str[i++];
            }


        }//while

        i++;//跳过换行符
        if (left != "" && right != "")
        {
            Lr = new SLRNode(left, right);//构造每一行最后一个产生式,不存在'|'时就是该行产生式本身
            SLRproNum.Add(Lr);
        }
    }//while
    Echar.Add('#');

    //构造项目 对产生式集合LRproNum中的所有产生式都循环插'.'
    SLRNode Lobj;
    for (i = 0; i < SLRproNum.Count; i++)
    {
        left = "";
        right = "";
        for (int j = 0; j <= SLRproNum[i].Right.Length; j++)//j可以等于length  项目共length+1个
        {
            left = SLRproNum[i].Left;
            right = CreObj(SLRproNum[i].Right, j);//在第j个位置插入'.'
            if (j == SLRproNum[i].Right.Length && SLRobjNum.Count != 1)
            {
                //在产生式最后的位置插入. 即为归约项目   项目集中1号位置为接受项目
                Gy_obj.Add(SLRobjNum.Count);//归约项目在项目集中的序号 不用+1 本身就是从0开始的
            }
            Lobj = new SLRNode(left, right);
            SLRobjNum.Add(Lobj);
            left = "";//还原
            right = "";
        }
    }
    Creteitemsets();//项目集
    RStr_obitemset += "\r\n项目集构建:\r\n";
    for (int j = 0; j < proitemset.Count; j++)
    {
        RStr_obitemset += 'I' + j.ToString() + ':' + "\r\n";
        for (i = 0; i < proitemset[j].Container.Count; i++)
        {
            RStr_obitemset += SLRobjNum[proitemset[j].Container[i]].Left.ToString() + "->" + SLRobjNum[proitemset[j].Container[i]].Right.ToString() + "\r\n";
        }
    }
    //return RStr_obitemset;



}


public Table[][] GET_ANA()
{
    // 构造分析表 SLRAna
    SLRAna = new Table[proitemset.Count][]; // 行数为项目集数量
    for (int i = 0; i < proitemset.Count; i++)
    {
        SLRAna[i] = new Table[Echar.Count + 1]; // 列数为终结符集合 + 1 (为了处理 # 符号)
        for (int j = 0; j < Echar.Count + 1; j++)
        {
            SLRAna[i][j] = new Table(); // 初始化为错误
        }
    }

    // 处理所有项目集
    for (int i = 0; i < proitemset.Count; i++)
    {
        // 1. 处理移进动作
        for (int j = 0; j < Echar.Count; j++)
        {
            int nextState = getNextState(i, Echar[j]); // 获取下一个状态
            if (nextState != -1)
            {
                SLRAna[i][j] = new Table('s', nextState); // 标记为移进动作
            }
        }

        // 2. 处理归约动作
        for (int j = 0; j < Gy_obj.Count; j++)
        {
            if (exist(proitemset[i].Container, Gy_obj[j])) // 如果该项目集中存在归约项目
            {
                int prodNum = getProdNum(Gy_obj[j]); // 获取产生式编号
                SLRAna[i][Echar.Count] = new Table('r', prodNum); // 标记为归约动作
            }
        }
    }

    // 处理接受状态
    SLRAna[0][Echar.Count] = new Table('a', -1); // 接受状态

    return SLRAna;
}


// 求项目集
public void Creteitemsets()
{
    List<int> I0 = new List<int>(100);
    I0.Add(0); // 拓广文法的第一个项目
    proitemset.Add(new SLRitemsets());
    proitemset[0].Container = Closure(I0);
    int index = 1;
    while (index < proitemset.Count)
    {
        // 对当前项目集中每个项目
        for (int i = 0; i < proitemset[index - 1].Container.Count; i++)
        {
            for (int j = 0; j < Echar.Count; j++)
            {
                List<int> temp = new List<int>(100);
                temp = Go(proitemset[index - 1].Container, Echar[j]);
                if (temp.Count > 0 && !exist(proitemset, temp))
                {
                    proitemset.Add(new SLRitemsets());
                    proitemset[index].Container = Closure(temp);
                    index++; // 加入新的项目集
                }
            }
        }
        index++;
    }

}




//构造闭包
public List<int> Closure(List<int> I)
{
    for (int index = 0; index < I.Count; index++)//遍历该集合中的所有序号 初始序号就是拓广文法的0 下面的ADD步骤中会扩大他的内容
        for (int i = 0; i < SLRobjNum[I[index]].Right.Length - 1; i++)//遍历第index序号项目右侧字符串 找到.A结构
        {
            if (SLRobjNum[I[index]].Right[i] == '.' && isFinalsymbol(SLRobjNum[I[index]].Right[i + 1]))
            {
                for (int j = 0; j < SLRobjNum.Count; j++)//遍历所有项目,找到以A开头的.a
                {
                    if (isnexist(I, j))
                        continue;
                    if (SLRobjNum[j].Left == SLRobjNum[I[index]].Right[i + 1].ToString() && SLRobjNum[j].Right[0] == '.')
                        I.Add(j);//ADD:在项目集(序号集合)中加入新成员
                }
            }
        }
    return I;

}

// 获取下一个状态
public int getNextState(int itemsetIndex, char symbol)
{
    List<int> temp = Go(proitemset[itemsetIndex].Container, symbol);
    if (temp.Count == 0)
        return -1;
    for (int i = 0; i < proitemset.Count; i++)
    {
        if (areListEqual(temp, proitemset[i].Container))
            return i;
    }
    return -1;
}

// 判断两个列表是否相等
public bool areListEqual(List<int> list1, List<int> list2)
{
    if (list1.Count != list2.Count)
        return false;
    for (int i = 0; i < list1.Count; i++)
    {
        if (list1[i] != list2[i])
            return false;
    }
    return true;
}

// 获取产生式编号
public int getProdNum(int itemIndex)
{
    for (int i = 0; i < SLRobjNum.Count; i++)
    {
        if (i == itemIndex)
            return i / (SLRproNum[0].Right.Length + 1);
    }
    return -1;
}

// 判断列表中是否包含某个元素
public bool exist(List<int> list, int value)
{
    for (int i = 0; i < list.Count; i++)
    {
        if (list[i] == value)
            return true;
    }
    return false;
}

// 判断列表中是否包含某个元素
public bool exist(List<SLRitemsets> list, List<int> value)
{
    for (int i = 0; i < list.Count; i++)
    {
        if (areListEqual(list[i].Container, value))
            return true;
    }
    return false;
}

// 判断列表中是否不存在某个元素
public bool isnexist(List<int> list, int value)
{
    return !exist(list, value);
}

// 判断字符是否是终结符
public bool isFinalsymbol(char c)
{
    return !exist(Nchar, c);
}

// 在字符串中插入'.'
public string CreObj(string str, int index)
{
    if (index == str.Length)
        return str + ".";
    else
        return str.Substring(0, index) + "." + str.Substring(index);
}

// 计算Go函数
public List<int> Go(List<int> I, char symbol)
{
    List<int> result = new List<int>(100);
    for (int i = 0; i < I.Count; i++)
    {
        if (SLRobjNum[I[i]].Right[0] == '.' && SLRobjNum[I[i]].Right.Length > 1 && SLRobjNum[I[i]].Right[1] == symbol)
        {
            result.Add(I[i] + 1);
        }
    }
    return result;
}

}


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

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