C#实现LL(1)文法判断算法及FIRST、FOLLOW集合计算
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace LL1
{
public partial class Form1 : Form
{
Dictionary<string, List<string>> production;
Dictionary<string, List<string>> firsts;
Dictionary<string, List<string>> follows;
List<string> nonterminals;
List<string> terminals;
public Form1()
{
InitializeComponent();
}
private void button4_Click(object sender, EventArgs e)
{
string text = richTextBox1.Text;
production = new Dictionary<string, List<string>>();
string[] pro = text.Split('
');
foreach (string s in pro)
{
if (s == "") continue;
// 去除产生式左右两边的空格
string trimmedS = s.Trim();
// 使用正则表达式替换多个空格为一个空格
trimmedS = Regex.Replace(trimmedS, @'\s+', ' ');
string[] ga = Regex.Split(trimmedS, "->");
if (ga.Length != 2) return;
if (ga[0].Length == 0 || ga[1].Length == 0)
return;
if (ga[0].Length != 1 || !char.IsUpper(ga[0][0])) return;
string[] ga2 = Regex.Split(ga[1], "\|");
if (!production.ContainsKey(ga[0]))
production.Add(ga[0], new List<string>());
foreach (string s1 in ga2)
production[ga[0]].Add(s1.Trim()); // 去除产生式右边的空格
}
firsts = new Dictionary<string, List<string>>();
foreach (var item in production.Keys)
GetFirst(item, production, firsts);
follows = new Dictionary<string, List<string>>();
foreach (var item in production.Keys)
GetFollow(item, production, firsts, follows);
if (JudgeLL1(production, firsts, follows))
{
MessageBox.Show('该文法是LL(1)文法\n');
}
else
{
MessageBox.Show('该文法不是LL(1)文法,存在左递归或者存在FIRST集合有交集的情况!\n');
}
button1.Enabled = true;
button2.Enabled = true;
button3.Enabled = true;
}
// ... 其他代码 ...
// 判断一个字符是否为终结符
private bool IsTerminal(char c)
{
// 将#判断为终结符
if (c == '#' || !char.IsUpper(c))
return true;
return false;
}
// ... 其他代码 ...
}
}
代码说明:
-
去除空格: 在处理产生式时,使用
string.Trim()方法去除字符串开头和结尾的空格,并使用正则表达式@'\s+'匹配多个空格,替换为单个空格,确保产生式格式正确。 -
判断终结符: 在
IsTerminal方法中,将'#'也判断为终结符,以便处理包含空串的产生式。
使用方法:
- 将代码复制到您的C#项目中。
- 在界面上添加一个
RichTextBox控件,用于输入文法规则。 - 添加按钮,并在按钮点击事件中调用
button4_Click方法。 - 运行程序,输入文法规则,点击按钮即可判断文法类型并计算 FIRST 和 FOLLOW 集合。
示例输入:
S -> A a \| b
A -> A c \| #
输出结果:
- 该文法是LL(1)文法
- FIRST(S) = {a, b}
- FIRST(A) = {c, #}
- FOLLOW(S) = {$}
- FOLLOW(A) = {a, c, $}
原文地址: https://www.cveoy.top/t/topic/fXEr 著作权归作者所有。请勿转载和采集!