public override int Execute(ParsingContext context) { Regulation regulation = context.Grammar[RegulationId - 1]; var newNode = new SyntaxTree(); int tokenCount = 0; int count = regulation.RightPart.Count(); for (int i = 0; i < count; i++) { var item = context.TreeStack.Pop(); context.StateIdStack.Pop();//只弹出,不再使用。 newNode.Children.Insert(0, item); item.Parent = newNode; tokenCount += item.MappedTokenLength; if (i == 0) { newNode.MappedTokenStartIndex = item.MappedTokenStartIndex; } } newNode.MappedTokenLength = tokenCount; newNode.MappedTotalTokenList = context.TokenList; newNode.NodeType = regulation.Left; context.TreeStack.Push(newNode); int stateId = context.StateIdStack.Peek(); LRParsingAction gotoAction = context.ParsingMap.GetAction(stateId, regulation.Left); gotoAction.Execute(context); return(context.CurrentTokenIndex); }
private static string getUniqueString(HashCache cache) { Regulation obj = cache as Regulation; return(obj.Dump()); //StringBuilder builder = new StringBuilder(); //builder.Append(obj.Left.Nickname); //builder.Append(" ::= "); //builder.Append(obj.RightPart); //builder.Append(" ;"); //return builder.ToString(); }
/// <summary> /// LR(0)项:Regulation + 圆点的位置 /// </summary> /// <param name="regulation"></param> /// <param name="dotPosition"></param> public LR0Item(Regulation regulation, int dotPosition) : base(GetUniqueString) { if (regulation == null) { throw new ArgumentNullException(); } if (dotPosition < 0 || regulation.RightPart.Count() < dotPosition) { throw new ArgumentOutOfRangeException(); } this.Regulation = regulation; this.DotPosition = dotPosition; }
/// <summary> /// LR(1)项(A->α.β,x)指出,序列α在栈顶,且输入中开头的是可以从βx导出的符号。 /// </summary> /// <param name="regulation">A->αβ/param> /// <param name="dotPosition">圆点的位置</param> /// <param name="lookAheadNodeType">x代表的类型</param> public LR1Item(Regulation regulation, int dotPosition, TreeNodeType lookAheadNodeType) : base(GetUniqueString) { if (regulation == null || lookAheadNodeType == null) { throw new ArgumentNullException(); } if (dotPosition < 0 || regulation.RightPart.Count() < dotPosition) { throw new ArgumentOutOfRangeException(); } this.Regulation = regulation; this.DotPosition = dotPosition; this.LookAheadNodeType = lookAheadNodeType; }
/// <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); } } } } }
/// <summary> /// 用LR(1)分析法计算分析表 /// </summary> /// <param name="grammar"></param> /// <returns></returns> public static void GetLR1ParsingMap(this RegulationList grammar, out LRParsingMap map, out LR1StateCollection stateCollection, out LR1EdgeCollection edgeCollection, TextWriter originalOut) { // 给文法添加一个辅助的开始产生式 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 LR1Item(decoratedGrammar[0], 0, decoratedEnd); var firstState = new SmallerLR1State(firstItem); Dictionary <TreeNodeType, bool> nullableDict; decoratedGrammar.GetNullableDict(out nullableDict); FIRSTCollection firstCollection; decoratedGrammar.GetFirstCollection(out firstCollection, nullableDict); firstState = decoratedGrammar.Closure(firstState, nullableDict, firstCollection); stateCollection = new LR1StateCollection(firstState); edgeCollection = new LR1EdgeCollection(stateCollection); var queue = new Queue <SmallerLR1State>(); queue.Enqueue(firstState); int lastOutputLength = 0; int stateListCount = 1; int queueCount = 1; while (queue.Count > 0) { SmallerLR1State fromState = queue.Dequeue(); queueCount--; int itemIndex = 0; int groupCount = fromState.GroupCount; foreach (var group in fromState.GetGroups()) { { TextWriter currentWriter = Console.Out; if (Console.Out != originalOut) { Console.SetOut(originalOut); } for (int i = 0; i < lastOutputLength; i++) { Console.Write('\u0008'); } string output = string.Format("Calculating LR(1) State List: {0} <-- {1}, working on group {2}/{3} ...", stateListCount, queueCount, 1 + itemIndex++, groupCount); Console.Write(output); lastOutputLength = output.Length; Console.SetOut(currentWriter); } TreeNodeType x = group.Item1.GetNodeNext2Dot(); if (x == null || x == decoratedEnd) { continue; } SmallerLR1State toState = decoratedGrammar.Goto(fromState, x, nullableDict, firstCollection); if (stateCollection.TryInsert(toState))//融入组织之中吧 { int index = stateCollection.IndexOf(toState); toState = stateCollection[index]; queue.Enqueue(toState); stateListCount++; queueCount++; var edge = new LR1Edge(fromState, x, toState); edgeCollection.TryInsert(edge); } else { int index = stateCollection.IndexOf(toState); toState = stateCollection[index]; var edge = new LR1Edge(fromState, x, toState); edgeCollection.TryInsert(edge); } } } { TextWriter currentWriter = Console.Out; if (Console.Out != originalOut) { Console.SetOut(originalOut); } 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 gotoId = edge.To.ParsingMapIndex + 1; //stateCollection.IndexOf(edge.To) + 1 map.SetAction(stateId, edge.X, new LR1ShiftInAction(gotoId)); } else { int stateId = edge.From.ParsingMapIndex + 1; // stateCollection.IndexOf(edge.From) + 1; int gotoId = edge.To.ParsingMapIndex + 1; //stateCollection.IndexOf(edge.To) + 1 map.SetAction(stateId, edge.X, new LR1GotoAction(gotoId)); } } // TODO: not implemented var endItem = new LR1Item(decoratedRegulation, 1, decoratedEnd); 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 LR1Item in state) { if (LR1Item.GetNodeNext2Dot() == null) { int stateId = state.ParsingMapIndex + 1;// stateCollection.IndexOf(state) + 1; map.SetAction(stateId, LR1Item.LookAheadNodeType, new LR1ReducitonAction(decoratedGrammar.IndexOf(LR1Item.Regulation))); } } } }