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 集表格。代码结构清晰,注释详细,方便理解和使用。

代码功能:

  1. 识别 LL(1) 文法: 通过输入的文法规则,判断该文法是否为 LL(1) 文法。
  2. 计算 First 集: 计算每个非终结符的 First 集,并将其显示在 ListView1 中。
  3. 计算 Follow 集: 计算每个非终结符的 Follow 集,并将其显示在 ListView2 中。
  4. 表格展示: 将 First 集和 Follow 集以表格形式展示,便于查看。

使用方法:

  1. 将代码添加到您的 C# 项目中。
  2. 在窗体上添加两个 ListView 控件,分别用于展示 First 集和 Follow 集。
  3. 在窗体上添加一个 RichTextBox 控件,用于输入文法规则。
  4. 在窗体上添加三个 Button 控件,分别用于触发识别 LL(1) 文法、显示 First 集表格和显示 Follow 集表格。
  5. 运行程序,在 RichTextBox 中输入文法规则,然后点击相应的按钮即可查看结果。

注意事项:

  1. 该代码仅用于演示目的,实际应用中可能需要根据具体情况进行修改。
  2. 文法规则的输入格式必须符合规范,否则可能导致错误的结果。
  3. 代码中使用了 Regex 类进行字符串匹配,需要添加 using System.Text.RegularExpressions; 语句。

示例文法规则:

E -> T + E | T
T -> F * T | F
F -> ( E ) | i

该文法规则表示一个简单的算术表达式。您可以将该文法规则输入到 RichTextBox 中,然后点击按钮进行测试。

C# 实现 LL(1) 文法识别并显示 First 集和 Follow 集表格

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

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