private static string GetUniqueString(HashCache cache) { LR0Item obj = cache as LR0Item; return(obj.Dump()); //StringBuilder builder = new StringBuilder(); //builder.Append(obj.Regulation.Left.Nickname); //builder.Append(" ::= "); //int count = obj.Regulation.RightPart.Count(); //for (int i = 0; i < count; i++) //{ // if (i == obj.DotPosition) // { builder.Append('.'); builder.Append(' '); } // var item = obj.Regulation.RightNode(i); // builder.Append(item.Nickname); // builder.Append(' '); //} //if (obj.DotPosition == count) //{ builder.Append('.'); builder.Append(' '); } //builder.Append(';'); //return builder.ToString(); }
/// <summary> /// /// </summary> /// <param name="lr0Item">group标识</param> /// <param name="lookAheadNodes">此group下包含的lookAhead结点列表</param> /// <returns></returns> public bool TryInsert(LR0Item lr0Item, IEnumerable <TreeNodeType> lookAheadNodes) { if (this.regulationDotList.TryInsert(lr0Item)) { int index = this.regulationDotList.IndexOf(lr0Item); OrderedCollection <TreeNodeType> list = new OrderedCollection <TreeNodeType>(" "); foreach (var node in lookAheadNodes) { list.TryInsert(node); } this.lookAheadCollectionList.Insert(index, list); this.SetDirty(); return(true); } else { int index = this.regulationDotList.IndexOf(lr0Item); bool result = false; OrderedCollection <TreeNodeType> list = this.lookAheadCollectionList[index]; foreach (var item in lookAheadNodes) { result = list.TryInsert(item) || result; } //this.SetDirty();// 无论是否插入新的lookAheadNode,都不影响state的hashcode return(result); } }
public LR1Item this[int index] { get { if (index < 0) { throw new ArgumentOutOfRangeException(); } int current = 0; for (int i = 0; i < this.regulationDotList.Count; i++) { if (index <= current + this.regulationDotList.Count) { TreeNodeType node = this.lookAheadCollectionList[i][index - current]; LR0Item item = this.regulationDotList[i]; return(new LR1Item(item.Regulation, item.DotPosition, node)); } else { current += this.regulationDotList.Count; } } throw new ArgumentOutOfRangeException(); } }
public bool TryInsert(LR1Item item) { LR0Item lr0Item = new LR0Item(item.Regulation, item.DotPosition); if (this.regulationDotList.TryInsert(lr0Item)) { int index = this.regulationDotList.IndexOf(lr0Item); var collection = new OrderedCollection <TreeNodeType>(", "); collection.TryInsert(item.LookAheadNodeType); this.lookAheadCollectionList.Insert(index, collection); this.SetDirty(); return(true); } else { int index = this.regulationDotList.IndexOf(lr0Item); if (this.lookAheadCollectionList[index].TryInsert(item.LookAheadNodeType)) { this.SetDirty(); return(true); } else { return(false); } } }
/// <summary> /// LR(0)的Closure操作。 /// 补全一个状态。 /// </summary> /// <param name="list"></param> /// <param name="state"></param> /// <returns></returns> static LR0State Closure(this RegulationList list, LR0State state) { Queue <LR0Item> queue = new Queue <LR0Item>(); foreach (var item in state) { queue.Enqueue(item); } while (queue.Count > 0) { LR0Item item = queue.Dequeue(); TreeNodeType node = item.GetNodeNext2Dot(); if (node == null) { continue; } foreach (var regulation in list) { if (regulation.Left == node) { var newItem = new LR0Item(regulation, 0); if (state.TryInsert(newItem)) { queue.Enqueue(newItem); } } } } return(state); }
public IEnumerator <LR1Item> GetEnumerator() { for (int i = 0; i < this.regulationDotList.Count; i++) { LR0Item item = this.regulationDotList[i]; foreach (var lookAheadNode in this.lookAheadCollectionList[i]) { yield return(new LR1Item(item.Regulation, item.DotPosition, lookAheadNode)); } } }
/// <summary> /// LR(0)的Goto操作。 /// 将圆点移到所有LR(0)项中的符号<paramref name="x"/>之后。 /// </summary> /// <param name="list"></param> /// <param name="state"></param> /// <param name="x">一个文法符号,终结点或非终结点。</param> /// <returns></returns> static LR0State Goto(this RegulationList list, LR0State state, TreeNodeType x) { LR0State toState = new LR0State(); foreach (var item in state) { TreeNodeType nextNode = item.GetNodeNext2Dot(); if (nextNode == x) { var newItem = new LR0Item(item.Regulation, item.DotPosition + 1); toState.TryInsert(newItem); } } return(Closure(list, toState)); }
public int IndexOf(LR1Item item) { int index = 0; LR0Item lr0Item = new LR0Item(item.Regulation, item.DotPosition); int groupIndex = this.regulationDotList.IndexOf(lr0Item); if (0 <= groupIndex && groupIndex < this.regulationDotList.Count) { for (int i = 0; i < groupIndex; i++) { index += this.lookAheadCollectionList[i].Count; } index += this.lookAheadCollectionList[groupIndex].IndexOf(item.LookAheadNodeType); } else { index = -1; } return(index); }
public bool Contains(LR1Item item) { LR0Item lr0Item = new LR0Item(item.Regulation, item.DotPosition); int groupIndex = this.regulationDotList.IndexOf(lr0Item); if (0 <= groupIndex && groupIndex < this.regulationDotList.Count) { int index = this.lookAheadCollectionList[groupIndex].IndexOf(item.LookAheadNodeType); if (0 <= index && index < this.lookAheadCollectionList[groupIndex].Count) { return(true); } else { return(false); } } else { return(false); } }
/// <summary> /// 用SLR分析法计算分析表 /// </summary> /// <param name="grammar"></param> /// <returns></returns> public static void GetSLRParsingMap(this RegulationList grammar, out LRParsingMap map, out LR0StateCollection stateCollection, out LR0EdgeCollection edgeCollection, TextWriter writer) { // 给文法添加一个辅助的开始产生式 S' -> S $ // 如何添加一个外来的结点类型?用Enum是无法做到的。 var decoratedS = new TreeNodeType("__S2", "S'", "<S'>"); var decoratedEnd = TreeNodeType.endOfTokenListNode; var decoratedRegulation = new Regulation( decoratedS, grammar[0].Left, decoratedEnd); var decoratedGrammar = new RegulationList(decoratedRegulation); decoratedGrammar.AddRange(grammar); // 初始化T为{ Closure(S' -> S $) } var firstItem = new LR0Item(decoratedGrammar[0], 0); var firstState = new LR0State(firstItem); firstState = decoratedGrammar.Closure(firstState); stateCollection = new LR0StateCollection(firstState); edgeCollection = new LR0EdgeCollection(stateCollection); var queue = new Queue <LR0State>(); queue.Enqueue(firstState); int lastOutputLength = 0; int stateListCount = 1; int queueCount = 1; while (queue.Count > 0) { LR0State fromState = queue.Dequeue(); queueCount--; int itemIndex = 0; int itemCount = fromState.Count(); foreach (var item in fromState) { { TextWriter currentWriter = Console.Out; if (Console.Out != writer) { Console.SetOut(writer); } for (int i = 0; i < lastOutputLength; i++) { Console.Write('\u0008'); } string output = string.Format("Calculating SLR State List: {0} <-- {1}, working on {2}/{3} ...", stateListCount, queueCount, 1 + itemIndex++, itemCount); Console.Write(output); lastOutputLength = output.Length; Console.SetOut(currentWriter); } TreeNodeType x = item.GetNodeNext2Dot(); if (x == null || x == decoratedEnd) { continue; } LR0State toState = decoratedGrammar.Goto(fromState, x); if (stateCollection.TryInsert(toState)) { queue.Enqueue(toState); stateListCount++; queueCount++; var edge = new LR0Edge(fromState, x, toState); edgeCollection.TryInsert(edge); } else { int index = stateCollection.IndexOf(toState); toState = stateCollection[index]; var edge = new LR0Edge(fromState, x, toState); edgeCollection.TryInsert(edge); } } } { TextWriter currentWriter = Console.Out; if (Console.Out != writer) { Console.SetOut(writer); } Console.WriteLine(); Console.SetOut(currentWriter); } map = new LRParsingMap(); foreach (var edge in edgeCollection) { if (edge.X.IsLeave) { int stateId = edge.From.ParsingMapIndex + 1; //stateCollection.IndexOf(edge.From) + 1 int gotoStateId = edge.To.ParsingMapIndex + 1; //stateCollection.IndexOf(edge.To) + 1 map.SetAction(stateId, edge.X, new LR1ShiftInAction(gotoStateId)); } else { int stateId = edge.From.ParsingMapIndex + 1; //stateCollection.IndexOf(edge.From) + 1 int gotoStateId = edge.To.ParsingMapIndex + 1; //stateCollection.IndexOf(edge.To) + 1 map.SetAction(stateId, edge.X, new LR1GotoAction(gotoStateId)); } } var endItem = new LR0Item(decoratedRegulation, 1); FOLLOWCollection followCollection; decoratedGrammar.GetFollowCollection(out followCollection); foreach (var state in stateCollection) { if (state.Contains(endItem)) { int stateId = state.ParsingMapIndex + 1;//stateCollection.IndexOf(state) + 1 map.SetAction(stateId, decoratedEnd, new LR1AceptAction()); } foreach (var lr0Item in state) { if (lr0Item.GetNodeNext2Dot() == null) { FOLLOW follow = FindFollow(followCollection, lr0Item.Regulation.Left); foreach (var value in follow.Values) { int stateId = state.ParsingMapIndex + 1;// stateCollection.IndexOf(state) + 1; int reductionId = decoratedGrammar.IndexOf(lr0Item.Regulation); var action = new LR1ReducitonAction(reductionId); map.SetAction(stateId, value, action); } } } } }