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('
');
            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;
            }


            // 初始化分析器
            string text = textBox1.Text;
            analyse = new Stack<char>();
            input = new Stack<char>();
            result_analys = new List<string>();
            result_input = new List<string>();
            result_parse = new List<string>();
            analyse.Push('#');
            analyse.Push(production.Keys.First()[0]);
            input.Push('#');
            for (int i = text.Length - 1; i >= 0; i--)
            {
                input.Push(text[i]);
            }

            // 进行语法分析
            while (true)
            {
                // 如果分析栈栈顶元素为终结符
                if (!char.IsUpper(analyse.Peek()))
                {
                    // 当两个栈都只剩下#时,说明匹配成功
                    if (analyse.Peek() == input.Peek() && analyse.Count == 1 && input.Count == 1)
                    {
                        result_parse.Add("成功");
                        break;
                    }
                    if (analyse.Peek() == input.Peek())
                    {
                        result_parse.Add("'" + analyse.Peek() + "'匹配");
                        analyse.Pop();
                        input.Pop();
                        result_analys.Add(new string(analyse.Reverse().ToArray()));
                        result_input.Add(new string(input.Reverse().ToArray()));
                        continue;
                    }
                    else
                    {
                        result_parse.Add("失败");
                        break;
                    }
                }

                // 如果分析栈栈顶元素为非终结符
                string nonterminal = analyse.Peek().ToString();
                string terminal = input.Peek().ToString();
                if (!table.ContainsKey(nonterminal) || !table[nonterminal].ContainsKey(terminal))
                {
                    result_parse.Add("失败");
                    break;
                }
                string production = table[nonterminal][terminal];
                result_parse.Add(nonterminal + "->" + production);
                analyse.Pop();
                if (production != "#")
                {
                    for (int i = production.Length - 1; i >= 0; i--)
                    {
                        analyse.Push(production[i]);
                    }
                }
                result_analys.Add(new string(analyse.Reverse().ToArray()));
                result_input.Add(new string(input.Reverse().ToArray()));
            }

            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);

            step = 0;

            button8.Enabled = true;
            button9.Enabled = true;
        }

        // ... (其他代码)
    }
}

该代码实现了以下功能:

  1. LL(1) 文法识别: 检查用户输入的文法是否为 LL(1) 文法。
  2. 语法分析: 接受用户输入的字符串,并根据 LL(1) 分析表进行语法分析,并记录分析过程的每一步信息。
  3. 分析过程记录: 使用列表 result_analysresult_inputresult_parse 分别记录分析栈的变化、输入栈的变化和每一步的分析结果(包括推导所用产生式或匹配成功/失败的信息)。
  4. 单步执行: 用户可以通过点击 "下一步" 按钮,逐步查看语法分析过程,直到分析结束。

代码中包含了 GetFirstGetFollowGetSelect 函数,用于计算文法的 FIRST 集、FOLLOW 集和 SELECT 集,以及 JudgeLL1 函数,用于判断文法是否为 LL(1) 文法。

该代码可以作为学习 LL(1) 语法分析器实现的参考,并可以进一步扩展以支持更复杂的语法分析功能。

C# LL(1) 语法分析器实现代码 - 完整实现分析过程记录和单步执行功能

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

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