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

namespace 语法分析器
{
    public partial class Form1 : Form
    {
        // ...其他代码...

        private int step = 0;

        private void button8_Click(object sender, EventArgs e)
        {
            if (step < analyser.Result_parse.Count)
            {
                listView4.Items.Add(new ListViewItem(new string[] { (step + 1).ToString(), analyser.Result_analys[step], analyser.Result_input[step], analyser.Result_parse[step] }));
                step++;
            }
        }

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

            // 初始化分析器
            string text = textBox1.Text;
            select = new Select(production);
            analyser = new Analyser(text, select);

            // 进行语法分析
            analyser.Analyse();

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

        // ...其他代码...

        public class Analyser
        {
            public string Text { get; set; }
            public Select Select { get; set; }
            private Stack<char> analyse;
            private Stack<char> input;
            public List<string> Result_analys { get; set; }
            public List<string> Result_input { get; set; }
            public List<string> Result_parse { get; set; }

            public Analyser(string text, Select select)
            {
                this.Text = text;
                this.Select = select;
                this.analyse = new Stack<char>();
                input = new Stack<char>();
                Result_analys = new List<string>();
                Result_input = new List<string>();
                Result_parse = new List<string>();
            }

            public void Analyse()
            {
                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(new string(analyse.ToArray().Reverse().ToArray()));
                Result_input.Add(new string(input.ToArray().Reverse().ToArray()));

                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(new string(analyse.ToArray().Reverse().ToArray()));
                            Result_input.Add(new string(input.ToArray().Reverse().ToArray()));
                            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(new string(analyse.ToArray().Reverse().ToArray()));
                            Result_input.Add(new string(input.ToArray().Reverse().ToArray()));
                            flag = 1; break;
                        }
                    }
                    //说明该非终结符中没有可推导出该终结符的产生式
                    if (flag == 0)
                    {
                        Result_parse.Add('失败');
                        return;
                    }
                }
            }

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

            static bool IsTerminal(char symbol)
            {
                return !char.IsUpper(symbol);
            }
        } 
        // ...其他代码...
    }
}
C#实现语法分析器:单步解析句子

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

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