private void Analyse(string text, Dictionary<string, List<string>> selects)
{
    // 初始化分析器
    analyse = new Stack<char>();
    input = new Stack<char>();
    result_analys = new List<string>();
    result_input = new List<string>();
    result_parse = new List<string>();

    // 检查 selects 是否为空
    if (selects.Count == 0)
    {
        throw new ArgumentException("selects 不能为空");
    }

    // 构造输入栈
    input.Push('#');
    for (int i = text.Length - 1; i >= 0; i--)
    {
        input.Push(text[i]);
    }

    // 初始化分析栈
    analyse.Push('#');
    analyse.Push(selects.First().Key[0]);

    // 记录分析栈和输入栈的初始状态
    result_analys.Add(GetStackString(analyse));
    result_input.Add(GetStackString(input));

    while (true)
    {
        // 如果分析栈栈顶元素为终结符
        if (IsTerminal(analyse.Peek()))
        {
            // 当两个栈都只剩下#时,说明匹配成功
            if (analyse.Peek() == input.Peek() && analyse.Count == 1 && input.Count == 1)
            {
                result_parse.Add("成功");
                return;
            }
            if (analyse.Peek() == input.Peek())
            {
                result_parse.Add(''' + analyse.Peek() + ''' + "匹配");
                analyse.Pop();
                input.Pop();
                result_analys.Add(GetStackString(analyse));
                result_input.Add(GetStackString(input));
                continue;
            }
            else
            {
                result_parse.Add("失败");
                return;
            }
        }

        // 非终结符
        string nonterminal = analyse.Peek().ToString();
        // 当前输入字符
        string current = input.Peek().ToString();

        // 检查预测分析表中是否存在非终结符
        if (!table.ContainsKey(nonterminal))
        {
            throw new ArgumentException("预测分析表中不存在非终结符: " + nonterminal);
        }

        // 检查预测分析表中是否存在产生式
        if (!table[nonterminal].ContainsKey(current))
        {
            throw new ArgumentException("预测分析表中不存在产生式: " + nonterminal + " -> " + current);
        }

        // 根据预测分析表查找产生式
        string production = table[nonterminal][current];
        result_parse.Add(nonterminal + "->" + production);
        analyse.Pop();

        // 当推出的产生式不为空时,对分析栈进行添加
        if (!production.Equals("#"))
        {
            for (int i = production.Length - 1; i >= 0; i--)
            {
                analyse.Push(production[i]);
            }
        }

        result_analys.Add(GetStackString(analyse));
        result_input.Add(GetStackString(input));
    }
}

private string GetStackString(Stack<char> stack)
{
    if (stack == null || stack.Count == 0)
    {
        return "";
    }
    else
    {
        return new string(stack.ToArray());
    }
}

改进点:

  1. 添加了对 selects 的空值检查,避免 selects.First() 抛出异常。
  2. 使用 GetStackString() 方法获取栈的字符串表示,避免直接调用 getString() 方法,避免空栈异常。
  3. 添加了对 table 中非终结符和产生式的存在性检查,避免索引器访问异常。
  4. 将双引号替换为单引号,并对代码格式进行了调整,使其更易于阅读。

优化建议:

  1. 考虑使用泛型栈和列表,提高代码的通用性和可读性。
  2. 可以使用更具描述性的变量名,提高代码的可读性。
  3. 可以使用单元测试对代码进行测试,确保代码的正确性和稳定性。
C# 预测分析算法实现 - 异常处理与优化

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

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