C# 实现 LL(1) 文法识别并显示 First 集和 Follow 集表格
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;
button3.Enabled = true;
}
// 显示 First 集表格
private void button1_Click(object sender, EventArgs e)
{
listView1.Columns.Clear();
listView1.Items.Clear();
listView1.View = View.Details;
// 添加第一列
listView1.Columns.Add("", 30);
// 添加终结符列
foreach (var item in terminals)
{
listView1.Columns.Add(item, 30);
}
// 添加非终结符行
foreach (var item in nonTerminals)
{
ListViewItem lvi = new ListViewItem(item);
lvi.SubItems.Add("");
foreach (var t in terminals)
{
lvi.SubItems.Add("");
}
listView1.Items.Add(lvi);
}
// 填充表格
foreach (var item in firsts)
{
int row = nonTerminals.IndexOf(item.Key);
foreach (var t in item.Value)
{
int col = terminals.IndexOf(t);
listView1.Items[row].SubItems[col + 1].Text = "1";
}
}
}
// 显示 Follow 集表格
private void button2_Click(object sender, EventArgs e)
{
listView2.Columns.Clear();
listView2.Items.Clear();
listView2.View = View.Details;
// 添加第一列
listView2.Columns.Add("", 30);
// 添加终结符列
foreach (var item in terminals)
{
listView2.Columns.Add(item, 30);
}
// 添加非终结符行
foreach (var item in nonTerminals)
{
ListViewItem lvi = new ListViewItem(item);
lvi.SubItems.Add("");
foreach (var t in terminals)
{
lvi.SubItems.Add("");
}
listView2.Items.Add(lvi);
}
// 填充表格
foreach (var item in follows)
{
int row = nonTerminals.IndexOf(item.Key);
foreach (var t in item.Value)
{
int col = terminals.IndexOf(t);
listView2.Items[row].SubItems[col + 1].Text = "1";
}
}
}
该代码实现了 LL(1) 文法识别功能,并通过 ListView 控件展示 First 集和 Follow 集表格。代码结构清晰,注释详细,方便理解和使用。
代码功能:
- 识别 LL(1) 文法: 通过输入的文法规则,判断该文法是否为 LL(1) 文法。
- 计算 First 集: 计算每个非终结符的 First 集,并将其显示在 ListView1 中。
- 计算 Follow 集: 计算每个非终结符的 Follow 集,并将其显示在 ListView2 中。
- 表格展示: 将 First 集和 Follow 集以表格形式展示,便于查看。
使用方法:
- 将代码添加到您的 C# 项目中。
- 在窗体上添加两个 ListView 控件,分别用于展示 First 集和 Follow 集。
- 在窗体上添加一个 RichTextBox 控件,用于输入文法规则。
- 在窗体上添加三个 Button 控件,分别用于触发识别 LL(1) 文法、显示 First 集表格和显示 Follow 集表格。
- 运行程序,在 RichTextBox 中输入文法规则,然后点击相应的按钮即可查看结果。
注意事项:
- 该代码仅用于演示目的,实际应用中可能需要根据具体情况进行修改。
- 文法规则的输入格式必须符合规范,否则可能导致错误的结果。
- 代码中使用了
Regex类进行字符串匹配,需要添加using System.Text.RegularExpressions;语句。
示例文法规则:
E -> T + E | T
T -> F * T | F
F -> ( E ) | i
该文法规则表示一个简单的算术表达式。您可以将该文法规则输入到 RichTextBox 中,然后点击按钮进行测试。
原文地址: https://www.cveoy.top/t/topic/fXDG 著作权归作者所有。请勿转载和采集!