C# 预测分析算法实现 - 异常处理与优化
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());
}
}
改进点:
- 添加了对
selects的空值检查,避免selects.First()抛出异常。 - 使用
GetStackString()方法获取栈的字符串表示,避免直接调用getString()方法,避免空栈异常。 - 添加了对
table中非终结符和产生式的存在性检查,避免索引器访问异常。 - 将双引号替换为单引号,并对代码格式进行了调整,使其更易于阅读。
优化建议:
- 考虑使用泛型栈和列表,提高代码的通用性和可读性。
- 可以使用更具描述性的变量名,提高代码的可读性。
- 可以使用单元测试对代码进行测试,确保代码的正确性和稳定性。
原文地址: https://www.cveoy.top/t/topic/oykM 著作权归作者所有。请勿转载和采集!