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

public class analyse_sentence
{
    string text;
    Select select;
    Stack analyse;
    Stack input;
    public List<string> result_analys;
    public List<string> result_input;
    public List<string> result_parse;

    public analyse_sentence(string text, Select select)
    {
        this.text = text;
        this.select = select;
        this.analyse = new Stack();
        input = new Stack();
        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.length()==1 && input.length()==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;
            }
        }
    }

    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 class Select
{
    public Dictionary<string, List<KeyValuePair<string, List<string>>>> selects;

    public Select()
    {
        selects = new Dictionary<string, List<KeyValuePair<string, List<string>>>>();
    }

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

// Stack 扩展方法,用于获取栈中元素的字符串表示
public static class StackExtensions
{
    public static string getString(this Stack<char> stack)
    {
        return string.Join("", stack.Reverse().ToArray());
    }

    public static int length(this Stack<char> stack)
    {
        return stack.Count;
    }
}

// ... 其余代码 ...

private void button7_Click(object sender, EventArgs e)
{
    string text = textBox1.Text;

    // 初始化分析栈和输入栈
    analyseStack = new Stack<char>();
    inputStack = new Stack<char>();

    analyseStack.Push('#');
    inputStack.Push('#');
    for (int i = text.Length - 1; i >= 0; i--)
    {
        inputStack.Push(text[i]);
    }

    // 初始化分析结果列表
    resultAnalyse = new List<string>();
    resultInput = new List<string>();
    resultParse = new List<string>();

    // 将开始符号加入分析栈
    analyseStack.Push(nonterminals[0][0]);

    analyze();

    // 在界面第二行之后展示步骤、分析串、剩余输入串、推导所用产生式或匹配
    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 analyze()
{
    while (true)
    {
        // 如果分析栈为空或者输入栈为空,则分析结束
        if (analyseStack.Count == 0 || inputStack.Count == 0)
        {
            break;
        }

        // 获取分析栈的栈顶元素和输入栈的栈顶元素
        char topAnalyse = analyseStack.Peek();
        char topInput = inputStack.Peek();

        // 如果分析栈的栈顶元素和输入栈的栈顶元素相同,则进行匹配
        if (topAnalyse == topInput)
        {
            // 将匹配的元素从分析栈和输入栈中弹出
            analyseStack.Pop();
            inputStack.Pop();

            // 在分析结果列表中添加匹配信息
            resultAnalyse.Add(analyseStack.ToString());
            resultInput.Add(inputStack.ToString());
            resultParse.Add("'" + topAnalyse + "'" + " 匹配");
        }
        else
        {
            // 如果分析栈的栈顶元素为终结符,则出错
            if (IsTerminal(topAnalyse))
            {
                resultParse.Add("出错");
                break;
            }
            else
            {
                // 获取分析表中的产生式
                string production = table[topAnalyse.ToString()][topInput.ToString()];

                // 如果分析表中没有产生式,则出错
                if (production == null)
                {
                    resultParse.Add("出错");
                    break;
                }
                else
                {
                    // 将产生式从分析栈中弹出
                    analyseStack.Pop();

                    // 如果产生式不是空串,则将产生式中的符号逆序压入分析栈中
                    if (production != "#")
                    {
                        for (int i = production.Length - 1; i >= 0; i--)
                        {
                            analyseStack.Push(production[i]);
                        }
                    }

                    // 在分析结果列表中添加产生式信息
                    resultAnalyse.Add(analyseStack.ToString());
                    resultInput.Add(inputStack.ToString());
                    resultParse.Add(topAnalyse + " -> " + production);
                }
            }
        }
    }

    // 如果分析栈和输入栈都为空,则分析成功
    if (analyseStack.Count == 0 && inputStack.Count == 0)
    {
        resultParse.Add("成功");
    }
}

private int step = 0;

private void button8_Click(object sender, EventArgs e)
{
    if (step < resultAnalyse.Count)
    {
        ListViewItem item = new ListViewItem((step + 1).ToString());
        item.SubItems.Add(resultAnalyse[step]);
        item.SubItems.Add(resultInput[step]);
        item.SubItems.Add(resultParse[step]);
        listView4.Items.Add(item);
        step++;
    }
}

private void button9_Click(object sender, EventArgs e)
{
    listView4.Items.Clear();
    for (int i = 0; i < resultAnalyse.Count; i++)
    {
        ListViewItem item = new ListViewItem((i + 1).ToString());
        item.SubItems.Add(resultAnalyse[i]);
        item.SubItems.Add(resultInput[i]);
        item.SubItems.Add(resultParse[i]);
        listView4.Items.Add(item);
    }
}
C# 实现语法分析器:LL(1) 预测分析法

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

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