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

org.antlr.v4.runtime.tree.pattern.ParseTreeMatch Maven / Gradle / Ivy

/*
 * Copyright (c) 2012 The ANTLR Project. All rights reserved.
 * Use of this file is governed by the BSD-3-Clause license that
 * can be found in the LICENSE.txt file in the project root.
 */

package org.antlr.v4.runtime.tree.pattern;

import org.antlr.v4.runtime.misc.MultiMap;
import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.runtime.misc.Nullable;
import org.antlr.v4.runtime.tree.ParseTree;

import java.util.Collections;
import java.util.List;

/**
 * Represents the result of matching a {@link ParseTree} against a tree pattern.
 */
public class ParseTreeMatch {
	/**
	 * This is the backing field for {@link #getTree()}.
	 */
	private final ParseTree tree;

	/**
	 * This is the backing field for {@link #getPattern()}.
	 */
	private final ParseTreePattern pattern;

	/**
	 * This is the backing field for {@link #getLabels()}.
	 */
	private final MultiMap labels;

	/**
	 * This is the backing field for {@link #getMismatchedNode()}.
	 */
	private final ParseTree mismatchedNode;

	/**
	 * Constructs a new instance of {@link ParseTreeMatch} from the specified
	 * parse tree and pattern.
	 *
	 * @param tree The parse tree to match against the pattern.
	 * @param pattern The parse tree pattern.
	 * @param labels A mapping from label names to collections of
	 * {@link ParseTree} objects located by the tree pattern matching process.
	 * @param mismatchedNode The first node which failed to match the tree
	 * pattern during the matching process.
	 *
	 * @exception IllegalArgumentException if {@code tree} is {@code null}
	 * @exception IllegalArgumentException if {@code pattern} is {@code null}
	 * @exception IllegalArgumentException if {@code labels} is {@code null}
	 */
	public ParseTreeMatch(@NotNull ParseTree tree, @NotNull ParseTreePattern pattern, @NotNull MultiMap labels, @Nullable ParseTree mismatchedNode) {
		if (tree == null) {
			throw new IllegalArgumentException("tree cannot be null");
		}

		if (pattern == null) {
			throw new IllegalArgumentException("pattern cannot be null");
		}

		if (labels == null) {
			throw new IllegalArgumentException("labels cannot be null");
		}

		this.tree = tree;
		this.pattern = pattern;
		this.labels = labels;
		this.mismatchedNode = mismatchedNode;
	}

	/**
	 * Get the last node associated with a specific {@code label}.
	 *
	 * 

For example, for pattern {@code }, {@code get("id")} returns the * node matched for that {@code ID}. If more than one node * matched the specified label, only the last is returned. If there is * no node associated with the label, this returns {@code null}.

* *

Pattern tags like {@code } and {@code } without labels are * considered to be labeled with {@code ID} and {@code expr}, respectively.

* * @param label The label to check. * * @return The last {@link ParseTree} to match a tag with the specified * label, or {@code null} if no parse tree matched a tag with the label. */ @Nullable public ParseTree get(String label) { List parseTrees = labels.get(label); if ( parseTrees==null || parseTrees.size()==0 ) { return null; } return parseTrees.get( parseTrees.size()-1 ); // return last if multiple } /** * Return all nodes matching a rule or token tag with the specified label. * *

If the {@code label} is the name of a parser rule or token in the * grammar, the resulting list will contain both the parse trees matching * rule or tags explicitly labeled with the label and the complete set of * parse trees matching the labeled and unlabeled tags in the pattern for * the parser rule or token. For example, if {@code label} is {@code "foo"}, * the result will contain all of the following.

* *
    *
  • Parse tree nodes matching tags of the form {@code } and * {@code }.
  • *
  • Parse tree nodes matching tags of the form {@code }.
  • *
  • Parse tree nodes matching tags of the form {@code }.
  • *
* * @param label The label. * * @return A collection of all {@link ParseTree} nodes matching tags with * the specified {@code label}. If no nodes matched the label, an empty list * is returned. */ @NotNull public List getAll(@NotNull String label) { List nodes = labels.get(label); if ( nodes==null ) { return Collections.emptyList(); } return nodes; } /** * Return a mapping from label → [list of nodes]. * *

The map includes special entries corresponding to the names of rules and * tokens referenced in tags in the original pattern. For additional * information, see the description of {@link #getAll(String)}.

* * @return A mapping from labels to parse tree nodes. If the parse tree * pattern did not contain any rule or token tags, this map will be empty. */ @NotNull public MultiMap getLabels() { return labels; } /** * Get the node at which we first detected a mismatch. * * @return the node at which we first detected a mismatch, or {@code null} * if the match was successful. */ @Nullable public ParseTree getMismatchedNode() { return mismatchedNode; } /** * Gets a value indicating whether the match operation succeeded. * * @return {@code true} if the match operation succeeded; otherwise, * {@code false}. */ public boolean succeeded() { return mismatchedNode == null; } /** * Get the tree pattern we are matching against. * * @return The tree pattern we are matching against. */ @NotNull public ParseTreePattern getPattern() { return pattern; } /** * Get the parse tree we are trying to match to a pattern. * * @return The {@link ParseTree} we are trying to match to a pattern. */ @NotNull public ParseTree getTree() { return tree; } /** * {@inheritDoc} */ @Override public String toString() { return String.format( "Match %s; found %d labels", succeeded() ? "succeeded" : "failed", getLabels().size()); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy