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

de.claas.parser.Rule Maven / Gradle / Ivy

package de.claas.parser;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import de.claas.parser.visitors.RuleEquality;
import de.claas.parser.visitors.RuleHashCode;

/**
 * Superclass of all (grammar) rules within this package. This class is intended
 * to model rules that describe grammars. Implementations of this class are
 * utilized by {@link Grammar} instances to describe abstract concepts such as
 * words, phrases and sentences.
 * 

* The hierarchy of this class resembles the composite design pattern. * This is due to the fact that {@link Grammar} instances can largely be * described by a tree of nested (grammar) rules. * * @author Claas Ahlrichs * * @see Grammar */ public abstract class Rule implements Iterable { /** * Internal list of children. This is not intended to be exposed for outside * access. The {@link #iterator()} function already provides access to this * list, but in a way that decouples the internal representation of children * from the way outside classes access them. */ private final List children = new ArrayList<>(); /** * Internal flag for signaling that the hash code needs to be updated. The * actual update is done in a lazy fashion (i.e. hash code is updated the * next time it is needed). */ private boolean invalidHashCode = true; /** * Internally cached hash code. The hash code is kept in local storage for * performance reasons. It will be updated in accordance with the * {@link #invalidHashCode}-flag. */ private int hashCode; /** * Creates an instance with the given parameters. All children are added by * calling {@link #addChild(Rule)} in the order they are passed into this * constructor. * * @param children * the children */ public Rule(Rule... children) { for (Rule rule : children) { addChild(rule); } } /** * Adds the given (child) rule. Returns true if the child was * successfully added. Otherwise false is returned. * * @param rule * the (child) rule * @return true if the child was successfully added. * false otherwise */ public boolean addChild(Rule rule) { invalidateHashCode(); return rule != null && this.children.add(rule); } /** * Removes the given (child) rule. Returns true if the child * was successfully removed. Otherwise false is returned. * * @param rule * the (child) rule * @return true if the child was successfully removed. * false otherwise */ public boolean removeChild(Rule rule) { invalidateHashCode(); return this.children.remove(rule); } /** * Returns true if this rule has children. Otherwise * false is returned (i.e. number of children is zero). * * @return true if this rule has children. false * otherwise */ public boolean hasChildren() { return !this.children.isEmpty(); } @Override public Iterator iterator() { return this.children.iterator(); } /** * Instructs this rule to visit the given {@link RuleVisitor} instance. * * @param visitor * the visitor */ public abstract void visit(RuleVisitor visitor); /** * Notifies this node that its hash code is invalid. The hash code will be * lazily updated the time it is needed. */ protected void invalidateHashCode() { this.invalidHashCode = true; } @Override public int hashCode() { // it is acceptable that the hash code only changes if (local) fields // are changed. This hash code has no way of knowing whether any child // was modified, since this hash code was last updated, and does not // reflect any such changes in any of its children. if (this.invalidHashCode) { RuleHashCode visitor = new RuleHashCode(); this.visit(visitor); this.hashCode = visitor.getHashCode(); this.invalidHashCode = false; } return this.hashCode; } @Override public boolean equals(Object obj) { RuleEquality visitor = new RuleEquality(obj); this.visit(visitor); return visitor.isEquality(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy