LR(1)分析程序实验目的与要求
实验内容
- 本次实验最主要的部分构建语法分析表,理解分析表的使用,明确分析步骤。
本次实验主要用到的数据结构有List, Stack,二维数组等。 - 根据用户输入,给出分析过程。
实验步骤
- Main函数:在while循环中,根据状态栈栈顶元素,输入字符串的首字符,查询Action表,根据其值判断分析是否结束。未结束,则分为成功,移进,规约三种状态进行分析。
主要函数介绍:
- 根据S后的数字,获取产生式右部:static string GetRight(int n)
- 打印分析步骤:Display(string inputString,string action,string Go)
- 用于将状态栈,符号栈的内容逆序转化成字符串:GetStringFromStack(Stack stack)
- 根据终结符查找其在Vt表的位置:GetIndexByTerminalOnVt (char target)
- 根据非终结符查找其在Vn表的位置:GetIndexByNonTerminalOnVt (char target)
实验中遇到的问题:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using static System.Console; namespace LR1 { class Program { static List<char> Vt = new List<char> { 'i', '+', '*', '(', ')', '#' };//终结符集合 static List<char> Vn = new List<char> { 'E', 'T', 'F' };//非终结符集合 static List<string> production = new List<string> { "","E->E+T", "E->T", "T->T*F", "T->F", "F->(E)", "F->i"};//产生式 static int[,] GoTo = { {1,2,3 }, {-1,-1,-1 }, {-1,-1,-1 }, {-1,-1,-1 }, {8,2,3 }, {-1,-1,-1 }, {-1,9,3 }, {-1,-1,10 }, {-1,-1,-1 }, {-1,-1,-1 }, {-1,-1,-1 }, {-1,-1,-1 }, }; static string[,] actions = { {"S5",null,null,"S4",null,null }, {null,"S6",null,null,null,"acc" }, {null,"r2","S7",null,"r2","r2" }, {null,"r4","r4",null,"r4","r4" }, {"S5",null,null,"S4",null,null }, {null,"r6", "r6", null, "r6", "r6" }, {"S5",null,null,"S4",null,null }, {"S5",null,null,"S4",null,null }, {null,"S6",null,null, "S11",null }, {null,"r1","S7",null,"r1","r1" }, {null,"r3","r3",null, "r3", "r3" }, {null,"r5","r5",null, "r5", "r5" }, }; static Stack<int> status = new Stack<int>();//状态栈 static Stack<char> symbol = new Stack<char>();//符号栈 static void Main(string[] args) { Write("请输入待分析的句子:"); string inputString = ReadLine(); inputString += "#"; status.Push(0); WriteLine($"{"状态栈",-15}{"符号栈",-15}{"剩余输入串",-15}{"Action",-20}{"GoTo",-15}"); while (true) { char terminal = inputString[0]; int state = status.Peek(); int index = GetIndexByTerminalOnVt(terminal); if (index < 0 || actions[state, index] == null) { Error(); } else { string action = actions[state, index]; if (action == "acc") { Display(inputString, action, ""); WriteLine("分析结束,该文法接受此类型句子,接受成功"); Environment.Exit(0); } else if (action[0] == 'S') { Display(inputString,action, ""); int next = Convert.ToInt32(action.Remove(0, 1));//查找动作表,移进后转到第几个状态 symbol.Push(terminal); status.Push(next); if (inputString[0]!='#') { inputString = inputString.Remove(0, 1); } } else if (action[0] == 'r') { //归约动作 int n = Convert.ToInt32(action.Remove(0, 1));//查找动作表,用第几个产生式归约 string right = GetRight(n);//获取第n个产生式的右部 int sp = status.ElementAt(right.Length); int go = GetIndexByNonTerminalOnVt(production[n][0]); int k = GoTo[sp,go];//查找goto表,转到第几号状态 Display(inputString,action, k.ToString()); for (int i = 0; i < right.Length; i++) { symbol.Pop(); status.Pop(); } status.Push(k); symbol.Push(production[n][0]); } } } } /// <summary> /// 获取产生式右部 /// </summary> /// <param name="n"></param> /// <returns></returns> static string GetRight(int n) { try { return production[n].Remove(0, 3); } catch { Error(); } return ""; } static void Display(string inputString,string action,string Go) { string state = GetStringFromStack(status); string sym = GetStringFromStack(symbol); WriteLine($"{state,-20}{sym,-20}{inputString,-20}{action,-20}{Go,-20}"); } static string GetStringFromStack(Stack<int> stack) { Stack<int> s = new Stack<int>(); StringBuilder sb = new StringBuilder(); foreach(int o in stack) { s.Push(o); } foreach(int o in s) { sb.Append(o); } return sb.ToString(); } static string GetStringFromStack(Stack<char> stack) { Stack<char> s = new Stack<char>(); StringBuilder sb = new StringBuilder(); foreach (char o in stack) { s.Push(o); } foreach (char o in s) { sb.Append(o.ToString()); } return sb.ToString(); } /// <summary> /// 根据终结符查找其在Vt表的位置 /// </summary> /// <param name="target"></param> /// <returns></returns> static int GetIndexByTerminalOnVt(char target) { return Vt.FindLastIndex(r=>r==target); } /// <summary> /// 根据非终结符查找其在Vn表的位置 /// </summary> /// <param name="target"></param> /// <returns></returns> static int GetIndexByNonTerminalOnVt(char target) { return Vn.FindLastIndex(r => r == target); } /// <summary> /// 出错处理函数 /// </summary> static void Error() { WriteLine("分析结束,该文法不接受此类型句子,接受失败"); Environment.Exit(0); } } }
来源:51CTO
作者:郭麻花
链接:https://blog.csdn.net/qq_40404477/article/details/100857222