//--------------------预处理
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; // 每一步分析的结果,包括推导所用产生式或匹配成功/失败的信息

public class analyse_sentence
{
    public string text; // 输入句子
    public Dictionary<string, List<string>> select; // 选择集
    public Stack<char> analyse; // 分析栈
    public Stack<char> input; // 输入栈
    public List<string> result_analys; // 分析栈的每一步变化
    public List<string> result_input; // 输入栈的每一步变化
    public List<string> result_parse; // 每一步分析的结果,包括推导所用产生式或匹配成功/失败的信息

    public analyse_sentence(string text, Dictionary<string, List<string>> 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>();
        analyseresult();
    }

    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('成功'.ToString());
                    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('失败'.ToString());
                    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('失败'.ToString());
                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);
    }

    public string getString()
    {
        string result = string.Empty;
        foreach (char c in analyse)
        {
            result += c;
        }
        return result;
    }
}

//--------------------单步分析
private void button8_Click(object sender, EventArgs e)
{
    // 判断是否已经初始化分析器
    if (production == null)
    {
        MessageBox.Show("请先进行文法分析");
        return;
    }

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

    // 初始化分析器
    analyse_sentence analyser = new analyse_sentence(textBox1.Text, selects);

    // 获取分析器结果
    List<string> analys = analyser.result_analys; // 分析栈变化
    List<string> inputs = analyser.result_input; // 输入栈变化
    List<string> parses = analyser.result_parse; // 推导过程

    // 如果listView4中已有内容,则从上次分析的位置继续显示
    int startIndex = listView4.Items.Count;

    // 将每一步分析结果显示在listView4中
    for (int i = startIndex; i < analys.Count; i++)
    {
        ListViewItem item = new ListViewItem((i + 1).ToString());
        item.SubItems.Add(analys[i]);
        item.SubItems.Add(inputs[i]);
        item.SubItems.Add(parses[i]);
        listView4.Items.Add(item);
    }
}

//--------------------初始化
private void button7_Click(object sender, EventArgs e)
{
    // 清空listView4中的内容
    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 = false;
    button9.Enabled = false;
}

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

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