SLR 分析器 C# 代码实现
{ "title": "SLR 分析器 C# 代码实现", "description": "本文提供完整的 SLR 分析器 C# 代码实现,包含产生式定义、项目集构造、分析表生成和分析过程。", "keywords": "SLR 分析器, C#, 编译原理, 语法分析, 自动机, 形式语言", "content": "namespace WindowsFormsApp4
{
class SLR
{
//产生式结点类
public class SLRproNode
{
public string Left;
public string Right;
public SLRproNode(string Left, string Right)
{
this.Left = Left;
this.Right = Right;
}
}
//项目集类
public class SLR_club
{
public List
//DFA结点
public struct DFA
{
public int from;
public char symbol;
public int to;
public DFA(int from, char symbol, int to)
{
this.from = from;
this.symbol = symbol;
this.to = to;
}
}
//分析表 结点
public class Table
{
public bool error;//是否为ERROR
public char type;//结点类型
public int id;//数值
public Table()
{
this.error = true;
}
public Table(char type, int id)
{
this.type = type;
this.id = id;
this.error = false;
}
}
public DFA[] dfa = new DFA[100];
public int Pindex = 0; //dfa数组指针
public Table[][] SLRAna;//分析表
public ANA_JUZI Jz;
public bool Success = false;
public List<SLRproNode> SLRproNum = new List<SLRproNode>(50);//产生式 列表
public List<SLRproNode> SLRobjNum = new List<SLRproNode>(50);//项目 列表
public List<SLR_club> pro_club = new List<SLR_club>(100);//项目集合
public List<int> Gy_obj = new List<int>(50);//归约项目序号集合
public List<int> Gy_club = new List<int>(50);//含有归约项目的集合的序号 的集合
public List<char> Nchar = new List<char>(50);//非终结符集合
public List<char> Echar = new List<char>(50);//终结符集合
public string RETStr = "";
public string RETStr_obclub = "";//输出返回
public string RETStr_DFA = "";
public string RETStr_ANA = "";
//读取传递过来的文件信息str后,对str的或运算加以处理,变成多个产生式
//返回处理过的信息
//public void Start(string str)
{
}
//求项目集
public void Cre_club()
{
List<int> slr_club = new List<int>(100);//记录项目的序号
slr_club.Add(0);
slr_club = Closure(slr_club);//构造初始项目集 求闭包
SLR_club SLR_C = new SLR_club();
SLR_C.Container = slr_club;//集合----项目集序号的集合
pro_club.Add(SLR_C);//集合的集合----存放项目集序号集合 的集合
for (int i = 0; i < pro_club.Count; i++)//整体集合中 第i个项目集
{
pro_club[i].Container.Sort();//排序由小到大 后面用于判断是否存在的比较
int[] flag = new int[pro_club[i].Container.Count];
for (int fi = 0; fi < pro_club[i].Container.Count; fi++)//标志位,用来判断该序号是否已经构造
{
flag[fi] = 0;
}
for (int j = 0; j < pro_club[i].Container.Count; j++)//第i个项目集的第j个项目
{
if (flag[j] == 1)//如果已经访问过 就不再构造 找下一个项目
continue;
int index = pro_club[i].Container[j];
for (int pi = 0; pi < SLRobjNum[index].Right.Length - 1; pi++)//length-1是避免匹配到.在最后的规约项目
{
if (SLRobjNum[index].Right[pi] == '.')
{
List<int> slr2_club = new List<int>(100);//记录项目的序号
char symbol = SLRobjNum[index].Right[pi + 1];//记录.a转移状态a.的符号a
slr2_club.Add((index + 1));//如果遇到.a形式的项目序号为index 那么项目a.的序号为index+1
for (int m1 = j + 1; m1 < pro_club[i].Container.Count; m1++)
{//在第i个项目集中找到了可以移动的.:.a 重新遍历第i个项目集j项目之后的 找到同样可以移动a的项目集
int index2 = pro_club[i].Container[m1];
for (int m2 = 0; m2 < SLRobjNum[index2].Right.Length - 1; m2++)
{
if (SLRobjNum[index2].Right[m2] == '.' && SLRobjNum[index2].Right[m2 + 1] == symbol)
{
flag[m1] = 1;//标记位置为1 已经访问 之后不再访问
slr2_club.Add(index2 + 1);
}
}
}
slr2_club = Closure(slr2_club);//求闭包
int value = isexist(slr2_club);
if (value == -1)//-1表示不存在相同的
{
for (int m3 = 0; m3 < Gy_obj.Count; m3++)
{
if (isnexist(slr2_club, Gy_obj[m3]))
{
Gy_club.Add(pro_club.Count);
}
}
SLR_club SLR_C2 = new SLR_club();
dfa[Pindex++] = new DFA(i, symbol, pro_club.Count);//count不用加1 本身从0开始
SLR_C2.Container = slr2_club;
pro_club.Add(SLR_C2);
}
else
{
dfa[Pindex++] = new DFA(i, symbol, value);
}
break;
}
}
}//end-forj
}//end-fori
}//end-Cre_club
//构造ACTION和GOTO表
public void Cre_table()
{
SLRAna = new Table[pro_club.Count][];
for (int i = 0; i < pro_club.Count; i++)
{
SLRAna[i] = new Table[Echar.Count + Nchar.Count + 1];
for (int j = 0; j < Echar.Count + Nchar.Count + 1; j++)
{
SLRAna[i][j] = new Table();
}
}
for (int i = 0; i < pro_club.Count; i++)
{
for (int j = 0; j < pro_club[i].Container.Count; j++)
{
int index = pro_club[i].Container[j];
for (int k = 0; k < Echar.Count; k++)//Echar为终结符集合
{
char ch = Echar[k];
if (SLRobjNum[index].Right.Contains('.'))
{
if (SLRobjNum[index].Right.IndexOf('.') == SLRobjNum[index].Right.Length - 1)//最后一个字符是'.',表示可以规约
{
for (int m = 0; m < Gy_obj.Count; m++)
{
if (Gy_obj[m] == index)
{
SLRAna[i][k] = new Table('r', m);
}
}
}
else
{
int to = Find_to(index, ch);
if (to != -1)
{
SLRAna[i][k] = new Table('s', to);
}
}
}
}
for (int k = 0; k < Nchar.Count; k++)//Nchar为非终结符集合
{
char ch = Nchar[k];
if (SLRobjNum[index].Right.Contains('.'))
{
if (SLRobjNum[index].Right.IndexOf('.') == SLRobjNum[index].Right.Length - 1)//最后一个字符是'.',表示可以规约
{
for (int m = 0; m < Gy_obj.Count; m++)
{
if (Gy_obj[m] == index)
{
SLRAna[i][Echar.Count + k] = new Table('r', m);
}
}
}
else
{
int to = Find_to(index, ch);
if (to != -1)
{
SLRAna[i][Echar.Count + k] = new Table('g', to);
}
}
}
}
if (SLRobjNum[index].Right.Contains('.'))
{
if (SLRobjNum[index].Right.IndexOf('.') == SLRobjNum[index].Right.Length - 1)//最后一个字符是'.',表示可以规约
{
SLRAna[i][Echar.Count + Nchar.Count] = new Table('a', 0);
}
}
}
}
}
//SLR分析器
public void SLR_Analysis(string input)
{
Stack<int> stateStack = new Stack<int>();
Stack<char> symbolStack = new Stack<char>();
stateStack.Push(0);//初始状态
symbolStack.Push('#');//初始符号
int index = 0;
while (index < input.Length)
{
int state = stateStack.Peek();
char symbol = input[index];
int col = -1;
if (Echar.Contains(symbol))
{
col = Echar.IndexOf(symbol);
}
else if (Nchar.Contains(symbol))
{
col = Nchar.IndexOf(symbol) + Echar.Count;
}
if (SLRAna[state][col].error)
{
Success = false;
break;
}
else if (SLRAna[state][col].type == 's')
{
stateStack.Push(SLRAna[state][col].id);
symbolStack.Push(symbol);
index++;
}
else if (SLRAna[state][col].type == 'r')
{
int num = SLRAna[state][col].id;
SLRproNode node = SLRproNum[num];
for (int i = 0; i < node.Right.Length; i++)
{
stateStack.Pop();
symbolStack.Pop();
}
int newState = stateStack.Peek();
symbolStack.Push(node.Left[0]);
int col2 = -1;
if (Nchar.Contains(node.Left[0]))
{
col2 = Nchar.IndexOf(node.Left[0]) + Echar.Count;
}
stateStack.Push(SLRAna[newState][col2].id);
原文地址: https://www.cveoy.top/t/topic/f0lp 著作权归作者所有。请勿转载和采集!