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

commonMain.org.antlr.v4.kotlinruntime.tree.pattern.ParseTreeMatch.kt Maven / Gradle / Ivy

// Copyright 2017-present Strumenta and contributors, licensed under Apache 2.0.
// Copyright 2024-present Strumenta and contributors, licensed under BSD 3-Clause.

package org.antlr.v4.kotlinruntime.tree.pattern

import org.antlr.v4.kotlinruntime.misc.MultiMap
import org.antlr.v4.kotlinruntime.tree.ParseTree

/**
 * Represents the result of matching a [ParseTree] against a tree pattern.
 *
 * @param tree The parse tree to match against the pattern
 * @param pattern The parse tree pattern we are matching against
 * @param labels A mapping from label names to collections of [ParseTree]
 *   objects located by the tree pattern matching process.
 *
 *   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 [getAll].
 *
 *   If the parse tree pattern did not contain any rule or token tags,
 *   this map will be empty.
 * @param mismatchedNode The first node which failed to match the tree
 *   pattern during the matching process.
 *   It is `null` if the match was successful.
 */
@Suppress("MemberVisibilityCanBePrivate")
public class ParseTreeMatch(
  public val tree: ParseTree,
  public val pattern: ParseTreePattern,
  public val labels: MultiMap,
  public val mismatchedNode: ParseTree?,
) {
  /**
   * Get the last node associated with a specific [label].
   *
   * For example, for pattern ``, `this["id"]` returns the
   * node matched for that `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 `null`.
   *
   * Pattern tags like `` and `` without labels are
   * considered to be labeled with `ID` and `expr`, respectively.
   *
   * @param label The label to check
   * @return The last [ParseTree] to match a tag with the specified label,
   *   or `null` if no parse tree matched a tag with the label
   */
  public operator fun get(label: String): ParseTree? {
    val parseTrees = labels[label]
    return if (parseTrees.isNullOrEmpty()) {
      null
    } else {
      // Return last if multiple
      parseTrees[parseTrees.size - 1]
    }
  }

  /**
   * Return all nodes matching a rule or token tag with the specified label.
   *
   * If the [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 [label] is `"foo"`,
   * the result will contain *all* of the following.
   *
   * - Parse tree nodes matching tags of the form `` and ``
   * - Parse tree nodes matching tags of the form ``
   * - Parse tree nodes matching tags of the form ``
   *
   * @param label The label
   * @return A collection of all [ParseTree] nodes matching tags with
   *   the specified [label]. If no nodes matched the label,
   *   an empty list is returned
   */
  public fun getAll(label: String): List =
    labels[label] ?: emptyList()

  /**
   * Gets a value indicating whether the match operation succeeded.
   *
   * @return `true` if the match operation succeeded, otherwise `false`
   */
  public fun succeeded(): Boolean =
    mismatchedNode == null

  override fun toString(): String {
    val state = if (succeeded()) {
      "succeeded"
    } else {
      "failed"
    }

    return "Match $state; found ${labels.size} labels"
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy