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);
}
C# LL(1) 文法分析器:实现语法分析功能

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

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