/// <summary> /// 从一个LR(1)状态跳转到另一个LR(1)状态 /// </summary> /// <param name="from"></param> /// <param name="x"></param> /// <param name="to"></param> public LR1Edge(SmallerLR1State from, TreeNodeType x, SmallerLR1State to) : base(GetUniqueString) { this.From = from; this.X = x; this.To = to; }
/// <summary> /// 从一个LR(0)状态跳转到另一个LR(0)状态 /// </summary> /// <param name="from"></param> /// <param name="x"></param> /// <param name="to"></param> public LR0Edge(LR0State from, TreeNodeType x, LR0State to) : base(GetUniqueString) { this.From = from; this.X = x; this.To = to; }
/// <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 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(); } }
private static string GetUniqueString(HashCache cache) { TreeNodeType obj = cache as TreeNodeType; return(obj.Dump()); //return string.Format("({0})[{1}][{2}]", obj.Type, obj.Content, obj.Nickname); }
public override void Dump(System.IO.TextWriter stream) { this.Regulation.Left.Dump(stream); stream.Write(" ::= "); int count = this.Regulation.RightPart.Count(); for (int i = 0; i < count; i++) { if (i == this.DotPosition) { stream.Write('.'); stream.Write(' '); } TreeNodeType item = this.Regulation.RightNode(i); item.Dump(stream); stream.Write(' '); } if (this.DotPosition == count) { stream.Write('.'); stream.Write(' '); } stream.Write(';'); stream.Write(", "); this.LookAheadNodeType.Dump(stream); }
public SyntaxTree Parse(TokenList tokenList) { LRParsingMap parsingMap = GetParsingMap(); RegulationList grammar = GetGrammar(); //TODO:这个convertor以后是可以配置的。 var tokenTypeConvertor = new TokenType2TreeNodeType(); var context = new ParsingContext(tokenList, grammar, parsingMap, tokenTypeConvertor); while (context.CurrentTokenIndex < context.TokenList.Count + 1) { PrintParsingProgress(context); TreeNodeType nodeType = context.CurrentNodeType(); int stateId = context.StateIdStack.Peek(); LRParsingAction action = parsingMap.GetAction(stateId, nodeType); int currentTokenIndex = action.Execute(context); context.CurrentTokenIndex = currentTokenIndex; } PrintLastState(context); if (context.TreeStack.Count > 0) { return(context.TreeStack.Peek()); } else { return(new SyntaxTree()); } }
private void PrintParsingProgress(ParsingContext context) { #if DEBUG if (!print) { return; } // 调试时快速取消print Debug.WriteLine("======================="); { Debug.WriteLine("Current Stack:"); Debug.Write(" "); var stateIdArray = context.StateIdStack.ToArray(); var treeArray = context.TreeStack.ToArray(); for (int i = stateIdArray.Length - 1; i > 0; i--) { Debug.Write(stateIdArray[i]); Debug.Write('['); Debug.Write(treeArray[i - 1].NodeType.Nickname); Debug.Write(']'); } Debug.Write(stateIdArray[0]); Debug.Write(' '); Debug.WriteLine(""); } { Debug.WriteLine("Current token list:"); Debug.Write(" "); for (int i = context.CurrentTokenIndex; i < context.TokenList.Count; i++) { Debug.Write(context.TokenList[i].TokenType.Content); Debug.Write(' '); } Debug.WriteLine(""); } { Debug.WriteLine("Next action:"); TreeNodeType nodeType = context.CurrentNodeType(); int stateId = context.StateIdStack.Peek(); LRParsingAction action = context.ParsingMap.GetAction(stateId, nodeType); Debug.Write(" "); Debug.WriteLine(action); } { Debug.WriteLine("Current syntax tree:"); SyntaxTree virtualParent = new SyntaxTree(); virtualParent.NodeType = new TreeNodeType("VirtualParent", "", "Virtual Parent"); var treeArray = context.TreeStack.ToArray(); for (int i = treeArray.Length - 1; i >= 0; i--) { virtualParent.Children.Add(treeArray[i]); treeArray[i].Parent = virtualParent; } Debug.WriteLine(virtualParent); foreach (var item in context.TreeStack) { item.Parent = null; } } Debug.WriteLine("======================="); #endif }
public virtual TreeNodeType GetNodeType(TokenType tokenType) { //TODO:“Leave__”后缀,这是个自定义规则 string strTreeNodeType = tokenType.Type + "Leave__"; string content = tokenType.Content; TreeNodeType result = new TreeNodeType(strTreeNodeType, content, tokenType.Nickname); return(result); }
public virtual TokenType GetTokenType(TreeNodeType treeNodeType) { //TODO:“Leave__”后缀,这是个自定义规则 string strTokenType = treeNodeType.Type.Substring(0, treeNodeType.Type.Length - "Leave__".Length); string content = treeNodeType.Content; TokenType result = new TokenType(strTokenType, treeNodeType.Content, treeNodeType.Nickname); return(result); }
public Regulation(TreeNodeType left, params TreeNodeType[] rights) : base(getUniqueString) { if (left == null) { throw new ArgumentNullException(); } this.Left = left; this.rightPart.AddRange(rights); }
/// <summary> /// 一个FOLLOW集 /// </summary> /// <param name="target"></param> /// <param name="values"></param> public FOLLOW(TreeNodeType target, params TreeNodeType[] values) : base(GetUniqueString) { this.Target = target; if (values != null) { foreach (var item in values) { this.values.TryInsert(item); } } }
private static FOLLOW FindFollow(FOLLOWCollection followCollection, TreeNodeType target) { foreach (var item in followCollection) { if (item.Target == target) { return(item); } } return(null); }
/// <summary> /// 一个FIRST集 /// </summary> /// <param name="target"></param> /// <param name="values"></param> public FIRST(TreeNodeType target, params TreeNodeType[] values) : base(GetUniqueString) { this.target.Add(target); if (values != null) { foreach (var item in values) { this.values.TryInsert(item); } } }
public bool TryInsert(TreeNodeType value) { if (this.values.TryInsert(value)) { this.SetDirty(); return(true); } else { return(false); } }
private static FIRST FindFirst(FIRSTCollection firstCollection, TreeNodeType target) { foreach (var item in firstCollection) { if (item.Target.Count() == 1 && item.Target.First() == target) { return(item); } } return(null); }
private void PrintLastState(ParsingContext context) { #if DEBUG if (!print) { return; } // 调试时快速取消print Debug.WriteLine("======================="); Debug.WriteLine("***********************"); { Debug.WriteLine("Last Stack:"); Debug.Write(" "); var stateIdArray = context.StateIdStack.ToArray(); var treeArray = context.TreeStack.ToArray(); for (int i = stateIdArray.Length - 1; i > 0; i--) { Debug.Write(stateIdArray[i]); Debug.Write('['); Debug.Write(treeArray[i - 1].NodeType.Nickname); Debug.Write(']'); } Debug.Write(stateIdArray[0]); Debug.Write(' '); Debug.WriteLine(""); } { Debug.WriteLine("Last token list:"); Debug.Write(" "); for (int i = context.CurrentTokenIndex; i < context.TokenList.Count; i++) { Debug.Write(context.TokenList[i].TokenType.Content); Debug.Write(' '); } Debug.WriteLine(""); } { Debug.WriteLine("Last action:"); TreeNodeType nodeType = context.CurrentNodeType(); int stateId = context.StateIdStack.Peek(); LRParsingAction action = context.ParsingMap.GetAction(stateId, nodeType); Debug.Write(" "); Debug.WriteLine(action); } { Debug.WriteLine("Last syntax tree:"); Debug.WriteLine(context.TreeStack.Peek()); foreach (var item in context.TreeStack) { item.Parent = null; } } Debug.WriteLine("***********************"); Debug.WriteLine("======================="); #endif }
// rename "next" /// <summary> /// 获取处理函数 /// </summary> /// <param name="leftNode">当前结非终点类型</param> /// <param name="nodeType">要处理的结点类型</param> /// <returns></returns> public LRParsingAction GetAction(int stateId, TreeNodeType nodeType) { string key = stateId.ToString() + "+" + nodeType.Type.ToString(); List <LRParsingAction> value = null; if (parserMap.TryGetValue(key, out value)) { return(value[0]); } else { return(null);// new LR1ParsingAction(); // TODO:将来这里可以放对语法错误进行分析的函数 } }
/// <summary> /// 获取以指定结点为左部的规则。 /// </summary> /// <param name="node"></param> /// <returns></returns> public List <Regulation> GetRegulations(TreeNodeType node) { List <Regulation> list = new List <Regulation>(); foreach (var item in this) { if (item.Left == node) { list.Add(item); } } return(list); }
/// <summary> /// 获取所有非叶结点。 /// </summary> /// <returns></returns> public List <TreeNodeType> GetAllTreeNodeNonLeaveTypes() { var result = new List <TreeNodeType>(); foreach (var item in this) { TreeNodeType node = item.Left; if (!result.Contains(node)) { result.Add(node); } } return(result); }
//TODO: rename "next" /// <summary> /// 设置给定语法类型、单词类型所对应的分析函数 /// </summary> /// <param name="leftNode"></param> /// <param name="next"></param> /// <param name="function"></param> public void SetAction(int stateId, TreeNodeType next, LRParsingAction function) { string key = stateId.ToString() + "+" + next.Type.ToString(); List <LRParsingAction> value = null; if (parserMap.TryGetValue(key, out value)) { value.Add(function); } else { List <LRParsingAction> list = new List <LRParsingAction>(); list.Add(function); parserMap.Add(key, list); } }
/// <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> /// 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)); }
/// <summary> /// list中指定的某一段结点是否都能产生null? /// </summary> /// <param name="list"></param> /// <param name="startIndex"></param> /// <param name="count"></param> /// <param name="nullableDict"></param> /// <returns></returns> static bool Nullable(IReadOnlyList <TreeNodeType> list, int startIndex, int count, Dictionary <TreeNodeType, bool> nullableDict) { bool result = true; for (int i = 0; i < count; i++) { TreeNodeType node = list[i + startIndex]; if (!nullableDict[node]) { result = false; break; } } return(result); }
/// <summary> /// LR(1)的Goto操作。 /// 将圆点移到所有LR(1)项中的符号<paramref name="x"/>之后。 /// </summary> /// <param name="list"></param> /// <param name="state"></param> /// <param name="x">一个文法符号,终结点或非终结点。</param> /// <param name="firstList"></param> /// <returns></returns> static SmallerLR1State Goto(this RegulationList list, SmallerLR1State state, TreeNodeType x, Dictionary <TreeNodeType, bool> nullableDict, FIRSTCollection firstList = null) { var toState = new SmallerLR1State(); foreach (var group in state.GetGroups()) { TreeNodeType nextNode = group.Item1.GetNodeNext2Dot(); if (nextNode == x) { toState.TryInsert( new LR0Item(group.Item1.Regulation, group.Item1.DotPosition + 1), group.Item2); } } return(Closure(list, toState, nullableDict, firstList)); }
/// <summary> /// LR(1)的Closure操作。 /// 补全一个状态。 /// </summary> /// <param name="grammar"></param> /// <param name="state"></param> /// <returns></returns> static SmallerLR1State Closure(this RegulationList grammar, SmallerLR1State state, Dictionary <TreeNodeType, bool> nullableDict = null, FIRSTCollection firstCollection = null) { if (nullableDict == null) { grammar.GetNullableDict(out nullableDict); } if (firstCollection == null) { grammar.GetFirstCollection(out firstCollection, nullableDict); } Queue <LR1Item> queue = new Queue <LR1Item>(); foreach (var item in state) { queue.Enqueue(item); } while (queue.Count > 0) { LR1Item item = queue.Dequeue(); TreeNodeType node = item.GetNodeNext2Dot(); if (node == null || node.IsLeave) { continue; } List <TreeNodeType> betaZ = item.GetBetaZ(); FIRST first = grammar.GetFirst(firstCollection, nullableDict, betaZ); List <Regulation> regulations = grammar.GetRegulations(node); foreach (var regulation in regulations) { foreach (var value in first.Values) { LR1Item newItem = new LR1Item(regulation, 0, value); if (state.TryInsert(newItem)) { queue.Enqueue(newItem); } } } } return(state); }
public List <TreeNodeType> GetAllTreeNodeTypes() { var result = new List <TreeNodeType>(); foreach (var item in this) { { TreeNodeType node = item.Left; if (!result.Contains(node)) { result.Add(node); } } foreach (var node in item.RightPart) { if (!result.Contains(node)) { result.Add(node); } } } return(result); }
/// <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))); } } } }
/// <summary> /// 计算文法的FOLLOW集 /// </summary> /// <param name="grammar"></param> /// <param name="nullableDict"></param> /// <param name="firstList4Node"></param> /// <returns></returns> private static void DoGetFollowList( this RegulationList grammar, out FOLLOWCollection followCollection, Dictionary <TreeNodeType, bool> nullableDict, FIRSTCollection firstList4Node) { // 初始化Follow list followCollection = new FOLLOWCollection(); foreach (var item in grammar.GetAllTreeNodeNonLeaveTypes()) { followCollection.TryInsert(new FOLLOW(item)); } // 迭代到不动点 bool changed = false; do { changed = false; foreach (var regulation in grammar) { int count = regulation.RightPart.Count(); for (int index = 0; index < count; index++) { // 准备为target添加follow元素 TreeNodeType target = regulation.RightNode(index); if (target.IsLeave) { continue; } // 叶结点没有follow FOLLOW follow = FindFollow(followCollection, target); // 找到follow对象 for (int checkCount = 0; checkCount < count - (index + 1); checkCount++) { if (Nullable(regulation.RightPart, index + 1, checkCount, nullableDict)) { // nullable之后的FIRST是target的follow的一部分 FIRST first = FindFirst( firstList4Node, regulation.RightNode(index + 1 + checkCount)); foreach (var value in first.Values) { if (value != TreeNodeType.NullNode) { changed = follow.TryInsert(value) || changed; } } } } { // 如果target之后的全部结点都是nullable,说明此regulation.Left的folow也是target的一部分。 if (Nullable(regulation.RightPart, index + 1, count - (index + 1), nullableDict)) { // 找到此regulation.Left的folow FOLLOW refFollow = FindFollow(followCollection, regulation.Left); if (refFollow != follow) { foreach (var item in refFollow.Values) { changed = follow.TryInsert(item) || changed; } } } } } } } while (changed); }
/// <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); } } } } }