/// <summary> /// 计算actionTable,产生下一步的ItemSet /// </summary> private void CalcAction() { foreach (Item project in this.items) { if (project.Type == ProjectType.Convention) { BuildConvertionAction(project); //规约项 } else { BuildGotoAction(project); //移进项 } } //检查生产的GotoAction所指的项目是否存在 foreach (var GotoActionItem in actionTable.Where(c => c.Value.GetType() == typeof(GotoAction))) { GotoAction gotoAction = (GotoAction)GotoActionItem.Value; bool exist = false; foreach (ItemSet itemSet in this.family.AllItemSet) { if (gotoAction.ItemSet.IsSameWith(itemSet))// 已经存在,直接指向已有的项目 { gotoAction.ItemSet = itemSet; exist = true; break; } } if (!exist) //将转移后的ItemSet注册到family中,family将会调用CaluClosure计算闭包 { this.family.Register(gotoAction.ItemSet); } } }
public void Analyze() { Item firstItem = new Item() { Rule = grammer.GrammerRuleSet[0], DotPosition = 0, IsCore = true, FowardSearch = new List <VertexTerminator>() { VertexTerminator.End } }; ItemSet firstItemSet = new ItemSet(); firstItemSet.AddItem(firstItem); ItemFamily itemFamily = new ItemFamily(grammer); itemFamily.FirstItemSet = firstItemSet; itemFamily.Register(firstItemSet); Queue <ItemSet> queue = new Queue <ItemSet>(); queue.Enqueue(firstItemSet); int maxIndex = 0; while (queue.Count > 0) { ItemSet currentItemSet = queue.Dequeue(); foreach (var actionItem in currentItemSet.ActionTable) { var v = actionItem.Key; var action = actionItem.Value; if (action.GetType() == typeof(GotoAction)) { GotoAction gotoAction = (GotoAction)action; if (gotoAction.ItemSet.Index > maxIndex) { queue.Enqueue(gotoAction.ItemSet); } maxIndex = Math.Max(maxIndex, gotoAction.ItemSet.Index); } } } this.ItemFamily = itemFamily; }
private void BuildGotoAction(Item project) { GotoAction action = new GotoAction(); //移进 Vertex vert = project.AfterDot(0); Item proAfterShift = project.Shift(); proAfterShift.IsCore = true; if (actionTable.ContainsKey(vert)) { if (actionTable[vert].IsConflicWith(action)) { throw new Exception(String.Format("在 {0} 遇到 {1} 产生冲突:{2} 和 {3}", this, vert, actionTable[vert], action)); } action = (GotoAction)actionTable[vert]; action.ItemSet.items.Add(proAfterShift); } else { action.ItemSet = new ItemSet(); action.ItemSet.items.Add(proAfterShift); this.actionTable.Add(vert, action); } }