package edu.stanford.nlp.trees.tregex.tsurgeon; import java.util.List; import java.util.Map; import edu.stanford.nlp.trees.Tree; import edu.stanford.nlp.trees.Trees; import edu.stanford.nlp.trees.tregex.TregexMatcher; /** Pruning differs from deleting in that if a non-terminal node winds up having no children, it is pruned as well. * @author Roger Levy (rog@nlp.stanford.edu) */ class PruneNode extends TsurgeonPattern { public PruneNode(TsurgeonPattern[] children) { super("prune", children ); } public PruneNode(List<TsurgeonPattern> children) { this(children.toArray(new TsurgeonPattern[children.size()])); } @Override public TsurgeonMatcher matcher(Map<String,Tree> newNodeNames, CoindexationGenerator coindexer) { return new Matcher(newNodeNames, coindexer); } private class Matcher extends TsurgeonMatcher { public Matcher(Map<String,Tree> newNodeNames, CoindexationGenerator coindexer) { super(PruneNode.this, newNodeNames, coindexer); } @Override public Tree evaluate(Tree tree, TregexMatcher tregex) { boolean prunedWholeTree = false; for(TsurgeonMatcher child : childMatcher) { final Tree nodeToPrune = child.evaluate(tree, tregex); if(pruneHelper(tree,nodeToPrune) == null) prunedWholeTree = true; } return prunedWholeTree ? null : tree; } } private static Tree pruneHelper(Tree root, Tree nodeToPrune) { if(nodeToPrune==root) return null; Tree parent = nodeToPrune.parent(root); parent.removeChild(Trees.objectEqualityIndexOf(parent,nodeToPrune)); if(parent.children().length==0) return pruneHelper(root,parent); return root; } }