protected void VisitAndXform(IAstTreeNode node, IAstTreeNode xform) { if (xform != null) { var parent = node.Parent; node.DetachFromParent(); xform.AttachToParent(parent); // TODO. Introduce something more elegant here // The following line is necessary since node being replaced by xform can // also affect parent nodes, say, we had the following fragment in an xformer // that includes arity simplifier. // // Original tree = Or -> And + And // // After some xform one of Ands suddenly gets replaced by an Or. So if we // short-mindedly assume that xform only affected the node being processed, we're // gonna fail, since Or -> Or + And has to be xformed to Or -> And. // // If you still aint here, uncomment a line below and run Sandbox::Program::MainestMain // throw new RestartTraversalException(xform); var topAffectedNode = xform.Parent is L1Expression ? xform : xform.Parent; throw new RestartTraversalException(topAffectedNode); } }
protected override void SpawnMoreVertices(IAstTreeNode node) { foreach (var child in node.Children) { _queue.Enqueue(child); } }
public override void Restart(IAstTreeNode root) { _queue.RemoveAll(node => !node.IsChildOf(Root)); var actualRoot = root ?? Root; _queue.RemoveAll(node => node.IsChildOf(actualRoot)); _queue.Enqueue(actualRoot); }
public static void AttachToParent(this IAstTreeNode node, IAstTreeNode parent) { if (node.Parent != null) { throw new ArgumentException("Cannot perform attachment for a node with non-null parent"); } else { node.Parent = parent; } }
public static bool IsChildOf(this IAstTreeNode node, IAstTreeNode wannabeFather) { var current = node.Parent; while (current != null) { if (current == wannabeFather) { return true; } else { current = current.Parent; } } return false; }
public static IAstTreeNode GetNodeThatFollows(IAstTreeNode node) { if (node == null) { return null; } else { if (!node.Children.Empty()) { var firstChildNode = node.Children[0]; if (!_visited.Contains(firstChildNode)) { return firstChildNode; } } return node.Sibling() ?? GetNodeThatFollows(node.Parent); } }
public override void Initialize(IAstTreeNode root) { base.Initialize(root); _visited.Clear(); _next = root; }
public RestartTraversalException(IAstTreeNode root) { Root = root; }
private static void TraverseTree(IAstTreeNode node, HashSet<string> initializedVariables, HashSet<string> uninitializedVariables) { // variable is uses – is it initialized? if (node.Value is IVariable) { if (!initializedVariables.Contains(node.Value.Name)) { uninitializedVariables.Add(node.Value.Name); } return; } // only “=” operator if (node.Value.GetType() == typeof(AssignmentOperator)) { TraverseTree(node.Children[1], initializedVariables, uninitializedVariables); initializedVariables.Add(node.Children[0].Value.Name); return; } // other “+=”-like operators if (node.Value is AssignmentOperator) { TraverseTree(node.Children[0], initializedVariables, uninitializedVariables); TraverseTree(node.Children[1], initializedVariables, uninitializedVariables); initializedVariables.Add(node.Children[0].Value.Name); return; } // other operators if (node.Value is IOperator) { foreach (var child in node.Children) { TraverseTree(child, initializedVariables, uninitializedVariables); } return; } // “x ?? y” operator with “if (x, y)” function-like syntax if (node.Value is CoalesceStatement) { TraverseTree(node.Children[0], initializedVariables, uninitializedVariables); TraverseTree(node.Children[1], new HashSet<string>(initializedVariables), uninitializedVariables); } // “x ? y : z” operator with “if (x, y, z)” function-like syntax if (node.Value is IfStatement) { TraverseTree(node.Children[0], initializedVariables, uninitializedVariables); TraverseTree(node.Children[1], new HashSet<string>(initializedVariables), uninitializedVariables); TraverseTree(node.Children[2], new HashSet<string>(initializedVariables), uninitializedVariables); } // “while (x) y” statement with “while (x, y)” function-like syntax if (node.Value is WhileStatement) { TraverseTree(node.Children[0], initializedVariables, uninitializedVariables); TraverseTree(node.Children[1], new HashSet<string>(initializedVariables), uninitializedVariables); } // other node – ignored return; }
public IAstTreeNode Next() { Current = ExtractNext(); SpawnMoreVertices(Current); return Current; }
protected abstract void SpawnMoreVertices(IAstTreeNode node);
private static void TraverseTree(IAstTreeNode node, HashSet <string> initializedVariables, HashSet <string> uninitializedVariables) { // variable is uses – is it initialized? if (node.Value is IVariable) { if (!initializedVariables.Contains(node.Value.Name)) { uninitializedVariables.Add(node.Value.Name); } return; } // only “=” operator if (node.Value.GetType() == typeof(AssignmentOperator)) { TraverseTree(node.Children[1], initializedVariables, uninitializedVariables); initializedVariables.Add(node.Children[0].Value.Name); return; } // other “+=”-like operators if (node.Value is AssignmentOperator) { TraverseTree(node.Children[0], initializedVariables, uninitializedVariables); TraverseTree(node.Children[1], initializedVariables, uninitializedVariables); initializedVariables.Add(node.Children[0].Value.Name); return; } // other operators if (node.Value is IOperator) { foreach (var child in node.Children) { TraverseTree(child, initializedVariables, uninitializedVariables); } return; } // “x ?? y” operator with “if (x, y)” function-like syntax if (node.Value is CoalesceStatement) { TraverseTree(node.Children[0], initializedVariables, uninitializedVariables); TraverseTree(node.Children[1], new HashSet <string>(initializedVariables), uninitializedVariables); } // “x ? y : z” operator with “if (x, y, z)” function-like syntax if (node.Value is IfStatement) { TraverseTree(node.Children[0], initializedVariables, uninitializedVariables); TraverseTree(node.Children[1], new HashSet <string>(initializedVariables), uninitializedVariables); TraverseTree(node.Children[2], new HashSet <string>(initializedVariables), uninitializedVariables); } // “while (x) y” statement with “while (x, y)” function-like syntax if (node.Value is WhileStatement) { TraverseTree(node.Children[0], initializedVariables, uninitializedVariables); TraverseTree(node.Children[1], new HashSet <string>(initializedVariables), uninitializedVariables); } // other node – ignored return; }
public override void Initialize(IAstTreeNode root) { base.Initialize(root); _queue.Clear(); _queue.Enqueue(root); }
public override void Restart(IAstTreeNode root) { throw new NotImplementedException(); }
public virtual void Initialize(IAstTreeNode root) { Root = root; Current = null; }
protected override void SpawnMoreVertices(IAstTreeNode node) { _next = GetNodeThatFollows(node); }
public abstract void Restart(IAstTreeNode root);
private static string ExpressionToStringWithParentheses(IBinaryOperator parent, IAstTreeNode childNode, bool isLeftChild) { string text = childNode.ToString(); var child = childNode.Value as IBinaryOperator; if (child == null || parent.Precedence < child.Precedence) { return(text); } if (parent.Precedence == child.Precedence) { if (!(parent.Associativity == OperatorAssociativity.RightAssociative || child.Associativity == OperatorAssociativity.RightAssociative)) { if (isLeftChild) { return(text); } if (parent.Associativity == OperatorAssociativity.NonAssociative && child.Associativity == OperatorAssociativity.NonAssociative) { return(text); } } } return(string.Format("({0})", text)); }
private static string ExpressionToStringWithParentheses(IBinaryOperator parent, IAstTreeNode childNode, bool isLeftChild) { string text = childNode.ToString(); var child = childNode.Value as IBinaryOperator; if (child == null || parent.Precedence < child.Precedence) return text; if (parent.Precedence == child.Precedence) { if (!(parent.Associativity == OperatorAssociativity.RightAssociative || child.Associativity == OperatorAssociativity.RightAssociative)) { if (isLeftChild) return text; if (parent.Associativity == OperatorAssociativity.NonAssociative && child.Associativity == OperatorAssociativity.NonAssociative) return text; } } return string.Format("({0})", text); }