/// <summary> /// 计算文法的所有单个的结点的FIRST /// </summary> /// <param name="grammar"></param> /// <param name="nullableDict"></param> /// <returns></returns> private static void GetFirstCollection4Node( this RegulationList grammar, out FIRSTCollection firstCollection, Dictionary <TreeNodeType, bool> nullableDict = null) { // 初始化FIRST firstCollection = new FIRSTCollection(); // 初始化非叶结点的FIRST foreach (var item in grammar.GetAllTreeNodeNonLeaveTypes()) { if (nullableDict[item]) { firstCollection.TryInsert(new FIRST(item, TreeNodeType.NullNode)); } else { firstCollection.TryInsert(new FIRST(item)); } } // 初始化叶结点的FIRST(叶结点的FIRST实际上已经完工) foreach (var item in grammar.GetAllTreeNodeLeaveTypes()) { firstCollection.TryInsert(new FIRST(item, item)); } bool changed = false; do { changed = false; foreach (var regulation in grammar) { FIRST first = FindFirst(firstCollection, regulation.Left); int rightPartCount = regulation.RightPart.Count(); for (int checkCount = 0; checkCount < rightPartCount; checkCount++) { // 如果前面checkCount个结点都可为null, // 就说明RightPart[checkCount]的FIRST是此regulation.Left的FIRST的一部分。 if (Nullable(regulation.RightPart, 0, checkCount, nullableDict)) { FIRST refFirst = FindFirst(firstCollection, regulation.RightNode(checkCount)); if (refFirst == null) { throw new Exception("algorithm error!"); } if (refFirst != first) { foreach (var value in refFirst.Values) { if (value != TreeNodeType.NullNode) { changed = first.TryInsert(value) || changed; } } } } } } } while (changed); }
/// <summary> /// 根据文法和已经计算的所有结点的FIRST集,计算任意一个结点串的FIRST。 /// </summary> /// <param name="grammar"></param> /// <param name="firstList4Node"></param> /// <param name="target"></param> /// <returns></returns> private static FIRST GetFirst(this RegulationList grammar, FIRSTCollection firstList4Node, Dictionary <TreeNodeType, bool> nullableDict, List <TreeNodeType> target) { // 初始化FIRST集 FIRST first = new FIRST(target); bool changed = false; do { changed = false; int count = first.Target.Count(); for (int checkCount = 0; checkCount < count; checkCount++) { // 如果前i个结点都可为null,就说明下一个结点(first.Target[i])的FIRST是此RightPart的FIRST的一部分 if (Nullable(first.Target, 0, checkCount, nullableDict)) { // 找到下一个结点的FIRST FIRST refFirst = FindFirst(firstList4Node, first.GetNode(checkCount)); foreach (var value in refFirst.Values) { if (value != TreeNodeType.NullNode) { changed = first.TryInsert(value) || changed; } } } } { // 如果RightPart的全部结点都可为null,就说明此RightPart的FIRST包含"null"结点。 if (Nullable(first.Target, 0, first.Target.Count(), nullableDict)) { //throw new Exception("如果是在LR1分析器生成工具的设计时走到此处,说明代码有问题。"); if (!first.Values.Contains(TreeNodeType.NullNode)) { changed = first.TryInsert(TreeNodeType.NullNode) || changed; } } } } while (changed); return(first); }