C#实现LR(0)文法项目集族构造算法
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace LR0Parser
{
public partial class Form1 : Form
{
private List<string> productions = new List<string>(); // 存储文法产生式
private List<string> symbols = new List<string>(); // 存储文法符号
private List<string> states = new List<string>(); // 存储状态
private List<string> itemsets = new List<string>(); // 存储项目族
private void button2_Click(object sender, EventArgs e) // 判别LR(0)文法
{
// 读取文法产生式
if (Regex.Replace(richTextBox1.Text, '\s', '') == '')
{
MessageBox.Show('输入文法为空');
return;
}
// 读取并处理文法产生式
string[] lines = richTextBox1.Lines;
foreach (string line in lines)
{
if (line.Trim() != '')
{
string[] parts = line.Split(new char[] { '-', '>' }, StringSplitOptions.RemoveEmptyEntries);
string left = parts[0].Trim();
string right = parts[1].Trim();
if (!symbols.Contains(left))
{
symbols.Add(left);
}
string[] symbolsInRight = right.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string symbol in symbolsInRight)
{
productions.Add(left + '->' + symbol);
foreach (char c in symbol)
{
if (!symbols.Contains(c.ToString()))
{
symbols.Add(c.ToString());
}
}
}
}
}
// 生成项目族
BuilditemFamily();
// 生成GOTO表和ACTION表
// BuildTables();
button4.Enabled = true;
button5.Enabled = true;
button6.Enabled = true;
}
private void button4_Click(object sender, EventArgs e) // 生成项目族信息
{
BuilditemFamily();
// 显示状态和项目族信息
listView1.Columns.Clear();
listView1.Items.Clear();
listView1.View = View.Details;
// 添加列名
listView1.Columns.Add('状态', 150);
listView1.Columns.Add('项目集信息', 300);
// 添加数据
for (int i = 0; i < states.Count; i++)
{
ListViewItem lvi = new ListViewItem(states[i]);
lvi.SubItems.Add(itemsets[i]);
listView1.Items.Add(lvi);
}
listView1.GridLines = true;
}
private void BuilditemFamily()
{
// 清空之前的数据
productions.Clear();
symbols.Clear();
states.Clear();
itemsets.Clear();
// 获取文法产生式和符号
string[] lines = richTextBox1.Lines;
foreach (string line in lines)
{
if (line.Trim() != '')
{
string[] parts = line.Split(new char[] { '-', '>' }, StringSplitOptions.RemoveEmptyEntries);
string left = parts[0].Trim();
string right = parts[1].Trim();
if (!symbols.Contains(left))
{
symbols.Add(left);
}
string[] symbolsInRight = right.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string symbol in symbolsInRight)
{
productions.Add(left + '->' + symbol);
foreach (char c in symbol)
{
if (!symbols.Contains(c.ToString()))
{
symbols.Add(c.ToString());
}
}
}
}
}
// 构造初始状态
string initialState = 'S`->.S';
foreach (var prod in productions)
initialState = initialState + ' ' + prod.ToString().Replace('>', '>.');
states.Add('0');
itemsets.Add(initialState);
// 构造其他状态
int index = 0;
while (index < itemsets.Count)
{
string[] items = itemsets[index].Split(' ');
Dictionary<string, List<string>> gotoDict = new Dictionary<string, List<string>>(); // 存储每个符号的GOTO结果
foreach (var item in items)
{
int dotIndex = item.IndexOf('.');
if (dotIndex == item.Length - 1) // 点在最后,无法移进
continue;
string symbol = item[dotIndex + 1].ToString();
string newItem = item.Substring(0, dotIndex + 1) + '.' + item.Substring(dotIndex + 2);
if (!gotoDict.ContainsKey(symbol))
{
gotoDict[symbol] = new List<string>();
}
gotoDict[symbol].Add(newItem);
}
foreach (var kvp in gotoDict)
{
string symbol = kvp.Key;
List<string> newItems = kvp.Value;
string newState = '';
foreach (var newItem in newItems)
{
if (newState == '')
newState = newItem;
else
newState = newState + ' ' + newItem;
}
if (!itemsets.Contains(newState))
{
itemsets.Add(newState);
states.Add(itemsets.Count.ToString());
}
}
index++;
}
}
// 其他代码...
}
}
原文地址: https://www.cveoy.top/t/topic/fZPS 著作权归作者所有。请勿转载和采集!