{ "title": "class Select\n {\n LL1Item LL1Item;\n First first;\n Follow follow;\n Dictionary<string, Dictionary<string, List>> selects;\n\n public Select(LL1Item LL1Item, First first, Follow follow)\n {\n this.LL1Item = LL1Item;\n this.first = first;\n this.follow = follow;\n selects = new Dictionary<string, Dictionary<string, List>>();\n GetSelect();\n }\n\n public void GetSelect()\n {\n var production=LL1Item.getproduction();\n foreach (var nofinal in LL1Item.nofinal)\n {\n selects.Add(nofinal,new Dictionary<string, List>());\n //对非终结符的每个产生式获取select值\n foreach (var f in production[nofinal])\n {\n selects[nofinal].Add(f,new List());\n for(int i=0; i < f.Length; i++)\n {\n //如果该产生式第一个字符为终结符\n if (IsTerminal(f[i]))\n {\n if (f[i].Equals('#'))\n {\n foreach (var fol in follow.getfollows()[nofinal])\n selects[nofinal][f].Add(fol);\n }\n else if (!selects[nofinal][f].Contains(f[i].ToString()))\n selects[nofinal][f].Add(f[i].ToString());\n break;\n }\n //如果该产生式第一个字符为非终结符\n else\n {\n int flag = 0;\n foreach(var fir in first.getfirsts()[f[i].ToString()])\n {\n if (fir.Equals('#'))\n flag = 1;\n else\n {\n if (!selects[nofinal][f].Contains(fir))\n selects[nofinal][f].Add(fir);\n }\n }\n if (flag == 0) break;\n }\n if (i == f.Length - 1)\n {\n foreach (var fol in follow.getfollows()[nofinal])\n if (!selects[nofinal][f].Contains(fol))\n selects[nofinal][f].Add(fol);\n }\n }\n }\n }\n }\n static bool IsTerminal(char symbol)\n {\n return !char.IsUpper(symbol);\n }\n\n public Dictionary<string, Dictionary<string, List>> getselects()\n {\n return selects;\n }\n }\n根据以上代码补充完整,构造以下GetSelect函数,不使用LL1Item\nprivate Dictionary<string, List> GetSelect(Dictionary<string, List> production1, Dictionary<string, List> firsts1, Dictionary<string, List> follows1)\n {\n // 初始化 SELECT 集\n Dictionary<string, List> selects1 = new Dictionary<string, List>(); \n foreach (var item in production1)\n selects1.Add(item.Key, new List());\n\n // 遍历每个产生式,计算对应的 SELECT 集\n foreach (var nonterm in production1.Keys)\n {\n foreach (var prod in production1[nonterm])\n {\n List select = new List();\n bool flag = true;\n // 对于产生式中的每个符号,计算其 FIRST 集\n foreach (var s in prod)\n {\n if (IsTerminal(s))\n {\n select.Add(s.ToString());\n flag = false;\n break;\n }\n else\n {\n GetFirst(s.ToString(), production1, firsts1);\n foreach (var f in firsts1[s.ToString()])\n {\n if (!f.Equals('#') && !select.Contains(f))\n select.Add(f);\n }\n if (!IsReachEmpty(s.ToString(), production1))\n {\n flag = false; \n break;\n }\n }\n }\n // 如果产生式中所有符号的 FIRST 集都包含空串,则将 FOLLOW 集加入 SELECT 集中\n if (flag)\n {\n GetFollow(nonterm, production1, firsts1, follows1);\n foreach (var f in follows1[nonterm])\n {\n if (!select.Contains(f))\n select.Add(f);\n }\n }\n selects1[nonterm].Add(string.Join("", select.ToArray()));\n }\n }\n return selects1;\n }\n内容:// 修改后的 GetSelect 函数\npublic void GetSelect()\n{\n var production = LL1Item.getproduction();\n foreach (var nonterm in LL1Item.nofinal)\n {\n selects.Add(nonterm, new Dictionary<string, List>());\n foreach (var prod in production[nonterm])\n {\n selects[nonterm].Add(prod, new List());\n List select = new List();\n bool flag = true;\n foreach (var s in prod)\n {\n if (IsTerminal(s))\n {\n select.Add(s.ToString());\n flag = false;\n break;\n }\n else\n {\n foreach (var f in first.getfirsts()[s.ToString()])\n {\n if (!f.Equals('#') && !select.Contains(f))\n select.Add(f);\n }\n if (!first.getfirsts()[s.ToString()].Contains('#'))\n {\n flag = false;\n break;\n }\n }\n }\n if (flag)\n {\n foreach (var f in follow.getfollows()[nonterm])\n {\n if (!select.Contains(f))\n select.Add(f);\n }\n }\n selects[nonterm][prod] = select;\n }\n }\n}

LL(1) 语法分析器中的 Select 集计算方法

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

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