All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.edurt.datacap.parser.ast.AstCommon Maven / Gradle / Ivy

There is a newer version: 2024.3.11
Show newest version
package io.edurt.datacap.parser.ast;

import com.google.common.graph.SuccessorsFunction;
import com.google.common.graph.Traverser;
import io.edurt.datacap.parser.node.Node;

import java.util.List;
import java.util.OptionalInt;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Stream;

import static com.google.common.collect.Streams.stream;
import static java.util.Objects.requireNonNull;

public final class AstCommon
{
    private AstCommon()
    {
    }

    public static Stream preOrder(Node node)
    {
        return stream(
                Traverser.forTree((SuccessorsFunction) Node::getChildren)
                        .depthFirstPreOrder(requireNonNull(node, "node is null")));
    }

    /**
     * 

Compares two AST trees recursively by applying the provided comparator to each pair of nodes.

* *

The comparator can perform a hybrid shallow/deep comparison. If it returns true or false, the * nodes and any subtrees are considered equal or different, respectively. If it returns null, * the nodes are considered shallowly-equal and their children will be compared recursively.

*/ public static boolean treeEqual(Node left, Node right, BiFunction subtreeComparator) { Boolean equal = subtreeComparator.apply(left, right); if (equal != null) { return equal; } List leftChildren = left.getChildren(); List rightChildren = right.getChildren(); if (leftChildren.size() != rightChildren.size()) { return false; } for (int i = 0; i < leftChildren.size(); i++) { if (!treeEqual(leftChildren.get(i), rightChildren.get(i), subtreeComparator)) { return false; } } return true; } /** *

Computes a hash of the given AST by applying the provided subtree hasher at each level.

* *

If the hasher returns a non-empty {@link OptionalInt}, the value is treated as the hash for * the subtree at that node. Otherwise, the hashes of its children are computed and combined.

*/ public static int treeHash(Node node, Function subtreeHasher) { OptionalInt hash = subtreeHasher.apply(node); if (hash.isPresent()) { return hash.getAsInt(); } List children = node.getChildren(); int result = node.getClass().hashCode(); for (Node element : children) { result = 31 * result + treeHash(element, subtreeHasher); } return result; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy