SLR分析表构建方法详解

本文将详细解释以下代码构建SLR分析表的逻辑:

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_itemset.Count; i++)
    {
        SLRNode item = SLRobjNum[proitemset[Gy_itemset[i]].Container[0]];
        char left = item.Left[0];
        List<char> follow = GetFollow(left);
        foreach (char c in follow)
        {
            int CID = FindID(Echar, c);
            SLRAna[Gy_itemset[i]][CID] = new Table('r', Find_pro(item));
            
        }

    }

    for (int i = 0; i < Pindex; i++)
    {
        if (isFinalsymbol(dfa[i].symbol))//symbol为非终结符  添加状态N
        {
            int CID = FindID(Nchar, dfa[i].symbol);
            SLRAna[dfa[i].from][CID + Echar.Count] = new Table('N', dfa[i].to);
        }
        else //不是归约项目 添加状态S
        {
            int CID = FindID(Echar, dfa[i].symbol);
            SLRAna[dfa[i].from][CID] = new Table('S', dfa[i].to);
        }
    }
}

代码解析

  1. 定义SLRAnaly()方法: 该方法用于构建SLR分析表。

  2. 创建Table对象tnode: tnode代表一个空的表格项,用于初始化SLRAna数组。

  3. 创建二维数组SLRAna:

    • 行数:proitemset.Count,表示所有项目集的数量。
    • 列数:Echar.Count + Nchar.Count,表示所有终结符和非终结符的数量之和。
  4. 初始化SLRAna数组: 将SLRAna数组中的每个元素都初始化为tnode,表示每个状态对每个符号的初始动作都是错误。

  5. 创建Table对象tnode,并赋值:

    • tnode = new Table('A', 0); 表示创建接受状态,动作类型为'A',状态值为0。
    • SLRAna[1][FindID(Echar, '#')] = tnode; 表示将接受状态存放在项目集1,当遇到输入符号'#'时,执行接受操作。
  6. 构建归约项目:

    • 遍历Gy_itemset,该集合保存所有归约项目集的编号。
    • 获取每个项目集对应的项目item,以及item的左部符号left和其Follow集合follow
    • 遍历follow集合中的每个符号c
      • 获取cEchar中的索引CID
      • SLRAna数组中,将对应于Gy_itemset[i]CID的位置赋值为一个新的Table对象,该对象表示执行归约操作,动作类型为'r',状态值为Find_pro(item)(表示该项目对应的产生式编号)。
  7. 构建移进项目:

    • 遍历Pindex,该集合保存所有移进项目的信息。
    • 获取每个移进项目对应的dfa对象,dfa包含项目的信息,如symbol(项目中的符号)、from(状态编号)、to(下一状态编号)。
    • 判断dfa[i].symbol是否为终结符:
      • 如果是终结符,则执行移进操作,将SLRAna[dfa[i].from][CID]赋值为一个新的Table对象,动作类型为'S',状态值为dfa[i].to
      • 如果是非终结符,则执行状态转换,将SLRAna[dfa[i].from][CID + Echar.Count]赋值为一个新的Table对象,动作类型为'N',状态值为dfa[i].to
  8. 完成SLR分析表的构建: 以上步骤完成了SLR分析表所有项目的构建。

概念解释

  • SLR分析表: 一种用于语法分析的表格,每个表格项代表一种状态对一种符号的操作(移进、归约、接受或错误)。
  • 项目集: 包含所有处于特定状态下的产生式,每个产生式中点的位置不同,代表不同的状态。
  • Follow集合: 一个非终结符的Follow集合包含所有可能出现在该非终结符之后的终结符。
  • DFA: 确定有限状态自动机,用于识别语言中的所有合法字符串。
  • 移进操作: 将输入符号移入栈中,并转换到下一状态。
  • 归约操作: 根据产生式将栈顶的一系列符号替换为产生式的左部符号,并转换到下一状态。
  • 接受状态: 表示输入字符串被成功解析,语法分析结束。

总结

代码通过遍历项目集、Follow集合、DFA中的数据,逐步构建SLR分析表,最终将每个状态对每个符号的操作都记录在表格中,用于指导语法分析过程。


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

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