private void button2_Click(object sender, EventArgs e)
{
    string str = richTextBox1.Text;
    if (str.Length == 0)
    {
        MessageBox.Show('输入为空');
        return;
    }
    string temp = "";
    int i = 0;
    while (i < str.Length)
    {
        temp = "";
        while (i < str.Length && str[i] != '\r' && str[i] != '\n')
        {
            if (str[i] != ' ')
                temp += str[i];
            i++;
        }
        i++;
        // int j=0;

        if (temp.Length > 0 && temp[temp.Length - 1] == '|')
        {
            MessageBox.Show('不得包含空串!');
            return;
        }
        if (temp.Length > 3)
        {
            if (temp[0] < 'A' || temp[0] > 'Z')
            {
                MessageBox.Show('含有非法左部!');
                return;
            }
            if (temp[1] != '-' || temp[2] != '>')
            {
                MessageBox.Show('产生式输入不规范!');
                return;
            }
        }
        if (temp.Length <= 3 && temp.Length > 0)
        {
            MessageBox.Show('产生式输入不规范!');
            return;
        }
    }
    MessageBox.Show('正确的LR(0)文法');
    button4.Enabled = true;
    button5.Enabled = true;
    button6.Enabled = true;
}


// 生成项目族信息
private void button4_Click(object sender, EventArgs e)
{
    // ShowDFA.Enabled = true;
    step = 0;//单步计数置零
    lr = new LR();

    listView1.Columns.Clear();
    listView1.Items.Clear();
    listView1.View = View.Details;

    // 添加第一列
    listView1.Columns.Add('状态', 150);
    listView1.Columns.Add('项目族信息', 350);

    lr.Buildprod(richTextBox1.Text);//调用

    for (int i = 0; i < lr.proitemset.Count; i++)//输出
    {
        ListViewItem li = new ListViewItem();
        li.SubItems.Clear();
        li.SubItems[0].Text = i.ToString();
        string tempstr = "";
        for (int j = 0; j < lr.proitemset[i].Container.Count; j++)
        {
            tempstr += lr.LRobjNum[lr.proitemset[i].Container[j]].Left + "->" + lr.LRobjNum[lr.proitemset[i].Container[j]].Right + " ";
        }
        li.SubItems.Add(tempstr);
        listView1.Items.Add(li);
    }
    listView1.GridLines = true;
}

// 构造LR分析表
private void button5_Click(object sender, EventArgs e)
{
    listView2.Clear();

    LR.Table[][] table;
    table = lr.GET_ANA();
    int xlen = table.GetLength(0);
    int ylen = table[1].Length;

    listView2.Columns.Clear();
    listView2.Items.Clear();
    listView2.View = View.Details;

    listView2.Columns.Add(' ');

    for (int i = 0; i < lr.Echar.Count; i++)//添加表头
    {
        string text = lr.Echar[i].ToString();
        listView2.Columns.Add(text,58);

    }
    for (int i = 0; i < lr.Nchar.Count; i++)//添加表头
    {
        string text = lr.Nchar[i].ToString();
        listView2.Columns.Add(text,58);
    }

    for (int i = 0; i < xlen; i++)
    {
        ListViewItem li = new ListViewItem(i.ToString());
        
        for (int j = 0; j < ylen; j++)
        {
            string st = "";
            if (table[i][j].error)
                st = "-";
            else if (table[i][j].type == 'A')
                st = "AC";
            else if (table[i][j].type == 'S')
            {
                st = "S" + table[i][j].id.ToString();
            }
            else if (table[i][j].type == 'R')
            {
                st = "R" + table[i][j].id.ToString();
            }
            else if (table[i][j].type == 'E')
            {
                st = "E" + table[i][j].id.ToString();
            }
            else if (table[i][j].type == 'C')
            {
                st = "C";
            }
            li.SubItems.Add(st);

        }
        listView2.Items.Add(li);
    }

    listView2.GridLines = true;
}


private void button6_Click(object sender, EventArgs e)//分析句子
{
    if (textBox1.Text.Length == 0)
    {
        MessageBox.Show('输入为空,分析失败');
        return;
    }

    // 分析句子
    for (int i = 0; i < textBox1.Text.Length; i++)
    {
        if (!lr.exist(lr.Echar, textBox1.Text[i]))
        {
            MessageBox.Show('含有未知字符!');
            return;
        }
    }
    step = 0;//单步操作置零

    listView3.Clear();
    listView3.Columns.Clear();
    listView3.Items.Clear();
    listView3.View = View.Details;

    string[] text = { "步骤", "状态栈", "符号栈", "输入串", "所用产生式" };
    int[] width = { 45, 70, 70, 70, 100 };
    for (int i = 0; i < text.Count(); i++)
    {
        listView3.Columns.Add(text[i], width[i]);
    }
    lr.sen_Analyze(textBox1.Text);//调用

    
    if (lr.Success)//判断
        MessageBox.Show('分析成功,是该文法的一个句子!');
    else
        MessageBox.Show('分析失败!');

    listView3.GridLines = true;
    button7.Enabled = true;
    button8.Enabled = true;

}

在代码中,我们添加了对移进-归约冲突和归约-归约冲突的处理,分别用'S'和'R'来表示移进和归约,后面的数字表示产生式的编号。如果存在移进-归约冲突,我们用'E'来表示,后面的数字表示归约产生式的编号。如果存在归约-归约冲突,我们用'C'来表示。

在LR分析表构造完成后,需要对表中存在的冲突进行判断和处理,例如在分析过程中遇到了移进-归约冲突,需要进行规约操作,而在遇到归约-归约冲突时,需要选择其中一个归约操作进行处理。

以下是修改后的分析句子代码:

private void button6_Click(object sender, EventArgs e)
{
    if (textBox1.Text.Length == 0)
    {
        MessageBox.Show('输入为空,分析失败');
        return;
    }

    // 分析句子
    for (int i = 0; i < textBox1.Text.Length; i++)
    {
        if (!lr.exist(lr.Echar, textBox1.Text[i]))
        {
            MessageBox.Show('含有未知字符!');
            return;
        }
    }
    step = 0;

    listView3.Clear();
    listView3.Columns.Clear();
    listView3.Items.Clear();
    listView3.View = View.Details;

    string[] text = { "步骤", "状态栈", "符号栈", "输入串", "所用产生式" };
    int[] width = { 45, 70, 70, 70, 100 };
    for (int i = 0; i < text.Count(); i++)
    {
        listView3.Columns.Add(text[i], width[i]);
    }

    lr.sen_Analyze(textBox1.Text);

    if (lr.Success)
    {
        MessageBox.Show('分析成功,是该文法的一个句子!');
    }
    else
    {
        MessageBox.Show('分析失败!');
    }

    listView3.GridLines = true;
    button7.Enabled = true;
    button8.Enabled = true;
}

在分析句子的代码中,我们调用了LR类中的sen_Analyze方法,该方法在分析过程中对冲突进行了处理,确保了分析的正确性。

LR(0) 文法分析器:识别和处理冲突的实现

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

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