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;
        List<string> terminals;
        List<string> nonterminals;

        // ... [省略无关代码] ...

        private void button4_Click(object sender, EventArgs e)
        {
            string text = richTextBox1.Text;
            production = new Dictionary<string, List<string>>();
            string[] pro = text.Split('
');
            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);

            // ... [省略无关代码] ...
        }

        // ... [省略无关代码] ...

        private void GetFirst(string symbol, Dictionary<string, List<string>> production1, Dictionary<string, List<string>> firsts1)
        {
            // 如果该非终结符的 FIRST 集已经被计算出,则直接返回
            if (firsts1.ContainsKey(symbol))
            {
                return;
            }
            firsts1.Add(symbol, new List<string>());
            // 遍历产生式,计算 FIRST 集
            foreach (var prod in production1[symbol])
            {
                // ... [省略与原文相同代码] ...

                //如果第一个非终结符能推出#
                if (IsReachEmpty(prod[0].ToString(), production1))
                {
                    // ... [省略与原文相同代码] ...

                    // 如果是最后一个字符且所有非终结符的 FIRST 集都含有空串,则将空串加入该非终结符的 FIRST 集中
                    if (j == prod.Length - 1)
                    {
                        if (!firsts1[symbol].Contains('#'))
                            firsts1[symbol].Add('#');
                    }
                }
            }
        }

        // ... [省略与原文相同代码] ...

        // 判断一个非终结符是否能推出空串
        private bool IsReachEmpty(string symbol, Dictionary<string, List<string>> production1)
        {
            // ... [省略与原文相同代码] ...
        }

        // 计算 FOLLOW 集
        private void GetFollow(string symbol, Dictionary<string, List<string>> production1, Dictionary<string, List<string>> firsts1, Dictionary<string, List<string>> follows1)
        {
            // ... [省略与原文相同代码] ...
        }

        // ... [省略与原文相同代码] ...
    }
}
C#实现LL(1)文法分析器:计算First集和Follow集

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

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