using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

public class SentenceAnalyzer
{
    private string text;
    private Selects select;
    private Stack<char> analyse;
    private Stack<char> input;
    private List<string> result_analys;
    private List<string> result_input;
    private List<string> result_parse;

    public SentenceAnalyzer(string text, Selects select)
    {
        this.text = text;
        this.select = select;
        this.analyse = new Stack<char>();
        this.input = new Stack<char>();
        this.result_analys = new List<string>();
        this.result_input = new List<string>();
        this.result_parse = new List<string>();
        analyseresult();
    }

    private void analyseresult()
    {
        var selects = select.getselects();
        analyse.Push('#');
        analyse.Push(selects.First().Key[0]);
        input.Push('#');
        for (int i = text.Length - 1; i >= 0; i--)
            input.Push(text[i]);
        result_analys.Add(analyse.getString());
        result_input.Add(input.getString());

        while (true)
        {
            //如果分析栈栈顶元素为终结符
            if (IsTerminal(analyse.Peek()))
            {
                //当两个栈都只剩下#时,说明匹配成功
                if (analyse.Peek() == input.Peek() && analyse.Count == 1 && input.Count == 1)
                {
                    result_parse.Add("成功");
                    return;
                }
                if (analyse.Peek() == input.Peek())
                {
                    result_parse.Add(''' + analyse.Peek() + ''' + "匹配");
                    analyse.Pop();
                    input.Pop();
                    result_analys.Add(analyse.getString());
                    result_input.Add(input.getString());
                    continue;
                }
                else
                {
                    result_parse.Add("失败");
                    return;
                }
            }

            int flag = 0;
            string nofinal = analyse.Peek().ToString();
            string final = input.Peek().ToString();
            foreach (var parse in selects[nofinal])
            {
                if (parse.Value.Contains(final))
                {
                    result_parse.Add(nofinal + "->" + parse.Key);
                    analyse.Pop();
                    //当推出的产生式不为空时,对分析栈进行添加
                    if (!parse.Key.Equals("#"))
                    {
                        addanalyse(parse.Key);
                    }
                    result_analys.Add(analyse.getString());
                    result_input.Add(input.getString());
                    flag = 1; break;
                }
            }
            //说明该非终结符中没有可推导出该终结符的产生式
            if (flag == 0)
            {
                result_parse.Add("失败");
                return;
            }
        }
    }

    private void addanalyse(string t)
    {
        for (int i = t.Length - 1; i >= 0; i--)
        {
            analyse.Push(t[i]);
        }
    }

    private static bool IsTerminal(char symbol)
    {
        return !char.IsUpper(symbol);
    }

    private string getString()
    {
        return string.Join("", this.Reverse().ToArray());
    }
}

public class Selects
{
    private Dictionary<string, List<KeyValuePair<string, string>>> selects;

    public Selects()
    {
        selects = new Dictionary<string, List<KeyValuePair<string, string>>>(){
            {
                "S", new List<KeyValuePair<string, string>>()
                {
                    new KeyValuePair<string, string>("E", "aBc"),
                    new KeyValuePair<string, string>("E", "aBcD"),
                    new KeyValuePair<string, string>("E", "aBcDE"),
                }
            },
            {
                "E", new List<KeyValuePair<string, string>>()
                {
                    new KeyValuePair<string, string>("E", "aBc"),
                    new KeyValuePair<string, string>("E", "aBcD"),
                    new KeyValuePair<string, string>("E", "aBcDE"),
                }
            },
        };
    }

    public Dictionary<string, List<KeyValuePair<string, string>>> getselects()
    {
        return selects;
    }
}

public partial class Form1 : Form
{
    //--------------------预处理
    private Dictionary<string, List<string>> production;
    private Dictionary<string, List<string>> firsts;
    private Dictionary<string, List<string>> follows;
    private Dictionary<string, List<string>> selects;
    private Dictionary<string, Dictionary<string, string>> table;
    private List<string> terminals;
    private List<string> nonterminals;
    private Stack<char> analyse; // 分析栈
    private Stack<char> input; // 输入栈
    private List<string> result_analys; // 分析栈的每一步变化
    private List<string> result_input; // 输入栈的每一步变化
    private List<string> result_parse; // 每一步分析的结果,包括推导所用产生式或匹配成功/失败的信息

    private void button7_Click(object sender, EventArgs e)
    {
        // 判断输入是否为空
        if (string.IsNullOrWhiteSpace(textBox1.Text))
        {
            MessageBox.Show("输入为空,分析失败");
            return;
        }

        // 初始化分析器
        SentenceAnalyzer analyzer = new SentenceAnalyzer(textBox1.Text, new Selects());
        analyse = analyzer.analyse;
        input = analyzer.input;
        result_analys = analyzer.result_analys;
        result_input = analyzer.result_input;
        result_parse = analyzer.result_parse;

        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 (result_parse.Count == 0)
        {
            MessageBox.Show("请先进行句子分析");
            return;
        }

        // 清空listView4
        listView4.Items.Clear();

        // 将分析结果逐步添加到listView4中
        for (int i = 0; i < result_parse.Count; i++)
        {
            ListViewItem item = new ListViewItem((i + 1).ToString());
            item.SubItems.Add(result_analys[i]);
            item.SubItems.Add(result_input[i]);
            item.SubItems.Add(result_parse[i]);
            listView4.Items.Add(item);
        }
    }
}
C# 代码实现句子分析的单步显示功能

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

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