public class SentenceAnalyzer
{
    private string text;
    private SelectCollection 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, SelectCollection 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>();
        AnalyzeResult();
    }

    private void AnalyzeResult()
    {
        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(GetString(analyse));
        result_input.Add(GetString(input));

        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(GetString(analyse));
                    result_input.Add(GetString(input));
                    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(GetString(analyse));
                    result_input.Add(GetString(input));
                    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 string GetString(Stack<char> stack)
    {
        return new string(stack.Reverse().ToArray());
    }

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

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

    // ... (代码逻辑与之前相同) 
}

private void button9_Click(object sender, EventArgs e)
{
    listView4.Items.Clear();
    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#语法分析器实现:LR(1)分析算法

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

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