C# LL(1) 文法分析器:实现语法分析功能
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
namespace byyljxfzxt
{
public partial class Form4 : Form
{
public Form4()
{
InitializeComponent();
}
//--------------------预处理
Dictionary<string, List<string>> production;
Dictionary<string, List<string>> firsts;
Dictionary<string, List<string>> follows;
Dictionary<string, List<string>> selects;
Dictionary<string, Dictionary<string, string>> table;
List<string> terminals;
List<string> nonterminals;
Stack<char> analyse; // 分析栈
Stack<char> input; // 输入栈
List<string> result_analys; // 分析栈的每一步变化
List<string> result_input; // 输入栈的每一步变化
List<string> result_parse; // 每一步分析的结果,包括推导所用产生式或匹配
private int step = 0;
private void button4_Click(object sender, EventArgs e)
{
string text = richTextBox1.Text;
production = new Dictionary<string, List<string>>();
string[] pro = text.Split('\n');
foreach (string s in pro)
{
if (s == "") continue;
Regex.Replace(s, " ", "");
string[] ga = Regex.Split(s, "->");
if (ga.Length != 2) return;
if (ga[0].Length == 0 || ga[1].Length == 0)
return;
if (ga[0].Length != 1 || !char.IsUpper(ga[0][0])) return;
string[] ga2 = Regex.Split(ga[1], "\|");
if (!production.ContainsKey(ga[0]))
production.Add(ga[0], new List<string>());
foreach (string s1 in ga2)
production[ga[0]].Add(s1);
}
firsts = new Dictionary<string, List<string>>();
foreach (var item in production.Keys)
GetFirst(item, production, firsts);
follows = new Dictionary<string, List<string>>();
foreach (var item in production.Keys)
GetFollow(item, production, firsts, follows);
if (JudgeLL1(production, firsts, follows))
{
MessageBox.Show("该文法是LL(1)文法\n");
}
else
{
MessageBox.Show("该文法不是LL(1)文法,存在左递归或者存在FIRST集合有交集的情况!\n");
}
button1.Enabled = true;
button2.Enabled = true;
button6.Enabled = true;
button7.Enabled = true;
}
private void button7_Click(object sender, EventArgs e)
{
// 判断输入是否为空
if (string.IsNullOrWhiteSpace(textBox1.Text))
{
MessageBox.Show("输入为空,分析失败");
return;
}
// 初始化分析器
analyse = new Stack<char>();
input = new Stack<char>();
result_analys = new List<string>();
result_input = new List<string>();
result_parse = new List<string>();
step = 0;
// 将输入字符串压入输入栈
string input_str = textBox1.Text + "$";
for (int i = input_str.Length - 1; i >= 0; i--)
input.Push(input_str[i]);
// 将文法起始符号和结束符号压入分析栈
analyse.Push('$');
analyse.Push(production.Keys.First());
// 清空展示结果的ListView
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 button8_Click(object sender, EventArgs e)
{
// 在界面第二行之后展示步骤、分析串、剩余输入串、推导所用产生式或匹配
//点一下按钮对应出来一行结果
}
private void button9_Click(object sender, EventArgs e)
{
// 自动分析直到分析结束
button8.Enabled = false;
button9.Enabled = false;
}
}
}
private void button7_Click(object sender, EventArgs e)
{
// 判断输入是否为空
if (string.IsNullOrWhiteSpace(textBox1.Text))
{
MessageBox.Show("输入为空,分析失败");
return;
}
// 初始化分析器
analyse = new Stack<char>();
input = new Stack<char>();
result_analys = new List<string>();
result_input = new List<string>();
result_parse = new List<string>();
step = 0;
// 将输入字符串压入输入栈
string input_str = textBox1.Text + "$";
for (int i = input_str.Length - 1; i >= 0; i--)
input.Push(input_str[i]);
// 将文法起始符号和结束符号压入分析栈
analyse.Push('$');
analyse.Push(production.Keys.First());
// 清空展示结果的ListView
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 button8_Click(object sender, EventArgs e)
{
// 单步分析
if (analyse.Count == 0)
{
MessageBox.Show("分析已结束");
button8.Enabled = false;
button9.Enabled = false;
return;
}
// 获取分析栈栈顶符号和输入栈栈顶符号
char X = analyse.Pop();
char a = input.Pop();
// 如果X是终结符号
if (terminals.Contains(X.ToString()))
{
// 如果X和a匹配,则分析成功
if (X == a)
{
result_parse.Add("匹配 " + a);
}
// 否则分析失败
else
{
result_parse.Add("分析失败:分析栈栈顶符号为 " + X + ",但输入栈栈顶符号为 " + a);
listView4.Items.Add(new ListViewItem(new string[] { step.ToString(), GetStackString(analyse), GetStackString(input), GetResultParseString() }));
return;
}
}
// 如果X是非终结符号
else if (nonterminals.Contains(X.ToString()))
{
// 获取X对应的产生式
string prod = GetProduction(X.ToString(), a.ToString());
if (prod == null)
{
result_parse.Add("分析失败:找不到 " + X + " 对应的产生式");
listView4.Items.Add(new ListViewItem(new string[] { step.ToString(), GetStackString(analyse), GetStackString(input), GetResultParseString() }));
return;
}
// 如果产生式是空产生式,则不需要入栈
else if (prod == "ε")
{
result_parse.Add("推导 " + X + " → ε");
}
// 否则将产生式右部符号逆序入栈
else
{
for (int i = prod.Length - 1; i >= 0; i--)
analyse.Push(prod[i]);
result_parse.Add("推导 " + X + " → " + prod);
}
}
// 如果X是错误符号
else
{
result_parse.Add("分析失败:分析栈栈顶符号为 " + X + ",但不是终结符号或非终结符号");
listView4.Items.Add(new ListViewItem(new string[] { step.ToString(), GetStackString(analyse), GetStackString(input), GetResultParseString() }));
return;
}
// 将分析栈和输入栈的变化加入展示结果的List
result_analys.Add(GetStackString(analyse));
result_input.Add(GetStackString(input));
// 将当前步骤的展示结果加入ListView
listView4.Items.Add(new ListViewItem(new string[] { step.ToString(), GetStackString(analyse), GetStackString(input), GetResultParseString() }));
// 步骤数加1
step++;
}
private void button9_Click(object sender, EventArgs e)
{
// 自动分析直到分析结束
while (analyse.Count > 0)
button8_Click(sender, e);
}
原文地址: https://www.cveoy.top/t/topic/fXPQ 著作权归作者所有。请勿转载和采集!