C# 实现语法分析器:LL(1) 预测分析法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
public class analyse_sentence
{
string text;
Select select;
Stack analyse;
Stack input;
public List<string> result_analys;
public List<string> result_input;
public List<string> result_parse;
public analyse_sentence(string text, Select select)
{
this.text = text;
this.select = select;
this.analyse = new Stack();
input = new Stack();
result_analys = new List<string>();
result_input = new List<string>();
result_parse = new List<string>();
analyseresult();
}
void analyseresult()
{
var selects = select.getselects();
analyse.Push('#');
analyse.Push(selects.First().Key[0]);
input.Push('#');
for (int i= text.Length-1; i>=0; i--)
input.push(text[i]);
result_analys.Add(analyse.getString());
result_input.Add(input.getString());
while (true)
{
//如果分析栈栈顶元素为终结符
if (IsTerminal(analyse.peek()))
{
//当两个栈都只剩下#时,说明匹配成功
if(analyse.peek() == input.peek() && analyse.length()==1 && input.length()==1)
{
result_parse.Add("成功");
return;
}
if(analyse.peek() == input.peek())
{
result_parse.Add("'" + analyse.peek()+"'");
analyse.pop();
input.pop();
result_analys.Add(analyse.getString());
result_input.Add(input.getString());
continue;
}
else
{
result_parse.Add("失败");
return;
}
}
int flag = 0;
string nofinal = analyse.peek().ToString();
string final = input.peek().ToString();
foreach(var parse in selects[nofinal])
{
if(parse.Value.Contains(final))
{
result_parse.Add(nofinal+"->" + parse.Key);
analyse.pop();
//当推出的产生式不为空时,对分析栈进行添加
if (!parse.Key.Equals("#"))
{
addanalyse(parse.Key);
}
result_analys.Add(analyse.getString());
result_input.Add(input.getString());
flag = 1; break;
}
}
//说明该非终结符中没有可推导出该终结符的产生式
if (flag == 0)
{
result_parse.Add("失败");
return;
}
}
}
void addanalyse(String t)
{
for(int i=t.Length-1; i>=0; i--)
{
analyse.push(t[i]);
}
}
static bool IsTerminal(char symbol)
{
return !char.IsUpper(symbol);
}
}
public class Select
{
public Dictionary<string, List<KeyValuePair<string, List<string>>>> selects;
public Select()
{
selects = new Dictionary<string, List<KeyValuePair<string, List<string>>>>();
}
public Dictionary<string, List<KeyValuePair<string, List<string>>>> getselects()
{
return selects;
}
}
// Stack 扩展方法,用于获取栈中元素的字符串表示
public static class StackExtensions
{
public static string getString(this Stack<char> stack)
{
return string.Join("", stack.Reverse().ToArray());
}
public static int length(this Stack<char> stack)
{
return stack.Count;
}
}
// ... 其余代码 ...
private void button7_Click(object sender, EventArgs e)
{
string text = textBox1.Text;
// 初始化分析栈和输入栈
analyseStack = new Stack<char>();
inputStack = new Stack<char>();
analyseStack.Push('#');
inputStack.Push('#');
for (int i = text.Length - 1; i >= 0; i--)
{
inputStack.Push(text[i]);
}
// 初始化分析结果列表
resultAnalyse = new List<string>();
resultInput = new List<string>();
resultParse = new List<string>();
// 将开始符号加入分析栈
analyseStack.Push(nonterminals[0][0]);
analyze();
// 在界面第二行之后展示步骤、分析串、剩余输入串、推导所用产生式或匹配
listView4.Columns.Clear();
listView4.Items.Clear();
listView4.View = View.Details;
listView4.Columns.Add("步骤", 60, HorizontalAlignment.Center);
listView4.Columns.Add("分析串", 60, HorizontalAlignment.Center);
listView4.Columns.Add("剩余输入串", 80, HorizontalAlignment.Center);
listView4.Columns.Add("推导所用产生式或匹配", 150, HorizontalAlignment.Center);
button8.Enabled = true;
button9.Enabled = true;
}
private void analyze()
{
while (true)
{
// 如果分析栈为空或者输入栈为空,则分析结束
if (analyseStack.Count == 0 || inputStack.Count == 0)
{
break;
}
// 获取分析栈的栈顶元素和输入栈的栈顶元素
char topAnalyse = analyseStack.Peek();
char topInput = inputStack.Peek();
// 如果分析栈的栈顶元素和输入栈的栈顶元素相同,则进行匹配
if (topAnalyse == topInput)
{
// 将匹配的元素从分析栈和输入栈中弹出
analyseStack.Pop();
inputStack.Pop();
// 在分析结果列表中添加匹配信息
resultAnalyse.Add(analyseStack.ToString());
resultInput.Add(inputStack.ToString());
resultParse.Add("'" + topAnalyse + "'" + " 匹配");
}
else
{
// 如果分析栈的栈顶元素为终结符,则出错
if (IsTerminal(topAnalyse))
{
resultParse.Add("出错");
break;
}
else
{
// 获取分析表中的产生式
string production = table[topAnalyse.ToString()][topInput.ToString()];
// 如果分析表中没有产生式,则出错
if (production == null)
{
resultParse.Add("出错");
break;
}
else
{
// 将产生式从分析栈中弹出
analyseStack.Pop();
// 如果产生式不是空串,则将产生式中的符号逆序压入分析栈中
if (production != "#")
{
for (int i = production.Length - 1; i >= 0; i--)
{
analyseStack.Push(production[i]);
}
}
// 在分析结果列表中添加产生式信息
resultAnalyse.Add(analyseStack.ToString());
resultInput.Add(inputStack.ToString());
resultParse.Add(topAnalyse + " -> " + production);
}
}
}
}
// 如果分析栈和输入栈都为空,则分析成功
if (analyseStack.Count == 0 && inputStack.Count == 0)
{
resultParse.Add("成功");
}
}
private int step = 0;
private void button8_Click(object sender, EventArgs e)
{
if (step < resultAnalyse.Count)
{
ListViewItem item = new ListViewItem((step + 1).ToString());
item.SubItems.Add(resultAnalyse[step]);
item.SubItems.Add(resultInput[step]);
item.SubItems.Add(resultParse[step]);
listView4.Items.Add(item);
step++;
}
}
private void button9_Click(object sender, EventArgs e)
{
listView4.Items.Clear();
for (int i = 0; i < resultAnalyse.Count; i++)
{
ListViewItem item = new ListViewItem((i + 1).ToString());
item.SubItems.Add(resultAnalyse[i]);
item.SubItems.Add(resultInput[i]);
item.SubItems.Add(resultParse[i]);
listView4.Items.Add(item);
}
}
原文地址: https://www.cveoy.top/t/topic/oBOY 著作权归作者所有。请勿转载和采集!