private ExpressionNode FindOrInitializeExpressionNode(Expr expr, out ExpressionNode parentNode) { // 1. Ищем дерево, в котором содержится данный expr var root = SeekRootTree(expr); parentNode = null; // 2. Если дерево не нашлось, создаем новый ExpressionNode с expr в качестве листа дерева и initializedNewNode = true if (root == null) { ExpressionNode newNode = new ExpressionNode(expr); if (currentTree == null) { currentTree = new ExpressionTree(); currentTree.AddNode(newNode); exprForest.Add(currentTree); } return(newNode); } // 3. Если дерево нашлось, запускаем поиск в ширину от корня, чтобы найти самое актуальное вхождение переменной в дереве var lastExpression = BFS(root, expr, out parentNode); if (lastExpression == null) { return(new ExpressionNode(expr)); } // 4. Возвращаем найденное вхождение return(lastExpression); }
public List <Node> Optimize(List <Node> inputNodes, out bool applied) { exprForest = new List <ExpressionTree>(); var nodes = inputNodes.OfType <Assign>() .Where(assn => assn.Operation != OpCode.Copy && assn.Left != null); foreach (var node in nodes) { currentTree = null; var leftNode = FindOrInitializeExpressionNode(node.Left, out ExpressionNode leftParentNode); var rightNode = FindOrInitializeExpressionNode(node.Right, out ExpressionNode rightParentNode); if (leftParentNode == null && rightParentNode == null) { // создать новый ExpressionNode: var resultNode = new ExpressionNode(node.Result); resultNode.LeftNode = leftNode; resultNode.RightNode = rightNode; resultNode.OpCode = node.Operation; currentTree.AddNode(resultNode); } else { leftParentNode.AssigneeList.Add(node.Result); applied = true; } } // Тут мы применяем оптимизацию, обходя дерево и строя новые выражения applied = false; return(RecoveryThreeAddrCode(inputNodes)); }