void ScanTree(PredictionTree tree, Alts alts, DList<Prematched> path) { int oldCount = path.Count; while (path.Count <= tree.Lookahead) path.Add(new Prematched { Terminals = Anything }); Prematched pm = path.Last; if (tree.IsAssertionLevel) { foreach (PredictionBranch b in tree.Children) { var old = pm.AndPreds.Clone(); var verified = Enumerable.Aggregate(b.AndPreds, (set1, set2) => (set1.Union(set2))); // usually empty if more than one pm.AndPreds.UnionWith(verified); if (b.Sub.Tree != null) { ScanTree(b.Sub.Tree, alts, path); } else { Debug.Assert(b.Sub.Alt != ErrorAlt); if (b.Sub.Alt == ExitAlt) _apply.ApplyPrematchData(alts.Next, path); else _apply.ApplyPrematchData(alts.Arms[b.Sub.Alt], path); } pm.AndPreds = old; } } else // !IsAssertionLevel (terminal-matching level) { bool needErrorBranch = LLPG.NeedsErrorBranch(tree, alts); for (int i = 0; i < tree.Children.Count; i++) { PredictionBranch b = tree.Children[i]; IPGTerminalSet set = b.Set; if (!needErrorBranch && i + 1 == tree.Children.Count) // Add all the default cases set = set.Union(tree.TotalCoverage.Inverted()); pm.Terminals = set; if (b.Sub.Tree != null) { ScanTree(b.Sub.Tree, alts, path); } else { if (b.Sub.Alt == ExitAlt) _apply.ApplyPrematchData(alts.Next, path); else if (b.Sub.Alt != ErrorAlt) _apply.ApplyPrematchData(alts.Arms[b.Sub.Alt], path); } } path.PopLast(); } path.Resize(oldCount); }
void ScanTree(PredictionTree tree, Alts alts, DList <Prematched> path) { int oldCount = path.Count; while (path.Count <= tree.Lookahead) { path.Add(new Prematched { Terminals = Anything }); } Prematched pm = path.Last; if (tree.IsAssertionLevel) { foreach (PredictionBranch b in tree.Children) { var old = pm.AndPreds.Clone(); var verified = Enumerable.Aggregate(b.AndPreds, (set1, set2) => (set1.Union(set2))); // usually empty if more than one pm.AndPreds.UnionWith(verified); if (b.Sub.Tree != null) { ScanTree(b.Sub.Tree, alts, path); } else { Debug.Assert(b.Sub.Alt != ErrorAlt); if (b.Sub.Alt == ExitAlt) { _apply.ApplyPrematchData(alts.Next, path); } else { _apply.ApplyPrematchData(alts.Arms[b.Sub.Alt], path); } } pm.AndPreds = old; } } else // !IsAssertionLevel (terminal-matching level) { bool needErrorBranch = LLPG.NeedsErrorBranch(tree, alts); for (int i = 0; i < tree.Children.Count; i++) { PredictionBranch b = tree.Children[i]; IPGTerminalSet set = b.Set; if (!needErrorBranch && i + 1 == tree.Children.Count) { // Add all the default cases set = set.Union(tree.TotalCoverage.Inverted()); } pm.Terminals = set; if (b.Sub.Tree != null) { ScanTree(b.Sub.Tree, alts, path); } else { if (b.Sub.Alt == ExitAlt) { _apply.ApplyPrematchData(alts.Next, path); } else if (b.Sub.Alt != ErrorAlt) { _apply.ApplyPrematchData(alts.Arms[b.Sub.Alt], path); } } } path.PopLast(); } path.Resize(oldCount); }
LNode Process(ref RVList <LNode> list, LNode single, bool asRoot, bool resetOpenNamespaces, bool areAttributesOrIsTarget) { if (single == null && list.Count == 0) { return(null); // no-op requested } var oldS = _s; var oldAncestors = _ancestorStack; var oldMP = MacroProcessor._current; MacroProcessor._current = _parent; bool newScope = false; try { bool reentrant = _reentrancyCounter++ != 0; if (!reentrant) { asRoot = true; } Debug.Assert(reentrant || _scopes.Count == 0); Debug.Assert(reentrant || _ancestorStack == null); if (asRoot) { _ancestorStack = new DList <LNode>(); } _s = new CurNodeState(); if (asRoot || resetOpenNamespaces) { var namespaces = !reentrant || resetOpenNamespaces?_parent.PreOpenedNamespaces.Clone() : _curScope.OpenNamespaces.Clone(); var properties = asRoot ? new MMap <object, object>() : _curScope.ScopedProperties; newScope = true; _curScope = new Scope(namespaces, properties, this, true); _scopes.Add(_curScope); } int maxExpansions = asRoot ? MaxExpansions : _s.MaxExpansions - 1; if (single != null) { return(ApplyMacros(single, maxExpansions, areAttributesOrIsTarget)); } else { int oldStackCount = _ancestorStack.Count; LNode splice = null; if (asRoot) { splice = list.AsLNode(S.Splice); _ancestorStack.PushLast(splice); } list = ApplyMacrosToList(list, maxExpansions, areAttributesOrIsTarget); _ancestorStack.PopLast(); Debug.Assert(_ancestorStack.Count == oldStackCount); return(splice); } } finally { _reentrancyCounter--; MacroProcessor._current = oldMP; _ancestorStack = oldAncestors; _s = oldS; if (newScope) { PopScope(); } } }