001package org.maltparser.parser.algorithm.nivre; 002 003import java.util.Stack; 004 005import org.maltparser.core.exception.MaltChainedException; 006import org.maltparser.core.syntaxgraph.DependencyStructure; 007import org.maltparser.core.syntaxgraph.node.DependencyNode; 008import org.maltparser.parser.ParserConfiguration; 009import org.maltparser.parser.ParsingException; 010/** 011 * @author Johan Hall 012 * 013 */ 014public class NivreConfig extends ParserConfiguration { 015 private final Stack<DependencyNode> stack; 016 private final Stack<DependencyNode> input; 017 private DependencyStructure dependencyGraph; 018 private final boolean allowRoot; 019 private final boolean allowReduce; 020 private final boolean enforceTree; 021 022 private boolean end; //Added 023 024 public NivreConfig(boolean allowRoot, boolean allowReduce, boolean enforceTree) throws MaltChainedException { 025 super(); 026 this.stack = new Stack<DependencyNode>(); 027 this.input = new Stack<DependencyNode>(); 028 this.allowRoot = allowRoot; 029 this.allowReduce = allowReduce; 030 this.enforceTree = enforceTree; 031 this.end = false; // Added 032 } 033 034 public Stack<DependencyNode> getStack() { 035 return stack; 036 } 037 038 public Stack<DependencyNode> getInput() { 039 return input; 040 } 041 042 public DependencyStructure getDependencyStructure() { 043 return dependencyGraph; 044 } 045 046 public boolean isTerminalState() { 047 if (isEnforceTree()) { 048 return input.isEmpty() && stack.size() == 1; 049 } 050 return input.isEmpty(); 051 } 052 053 public DependencyNode getStackNode(int index) throws MaltChainedException { 054 if (index < 0) { 055 throw new ParsingException("Stack index must be non-negative in feature specification. "); 056 } 057 if (stack.size()-index > 0) { 058 return stack.get(stack.size()-1-index); 059 } 060 return null; 061 } 062 063 public DependencyNode getInputNode(int index) throws MaltChainedException { 064 if (index < 0) { 065 throw new ParsingException("Input index must be non-negative in feature specification. "); 066 } 067 if (input.size()-index > 0) { 068 return input.get(input.size()-1-index); 069 } 070 return null; 071 } 072 073 public void setDependencyGraph(DependencyStructure source) throws MaltChainedException { 074 this.dependencyGraph = source; 075 } 076 077 public DependencyStructure getDependencyGraph() { 078 return dependencyGraph; 079 } 080 081 public void initialize(ParserConfiguration parserConfiguration) throws MaltChainedException { 082 if (parserConfiguration != null) { 083 final NivreConfig nivreConfig = (NivreConfig)parserConfiguration; 084 final Stack<DependencyNode> sourceStack = nivreConfig.getStack(); 085 final Stack<DependencyNode> sourceInput = nivreConfig.getInput(); 086 setDependencyGraph(nivreConfig.getDependencyGraph()); 087 for (int i = 0, n = sourceStack.size(); i < n; i++) { 088 stack.add(dependencyGraph.getDependencyNode(sourceStack.get(i).getIndex())); 089 } 090 for (int i = 0, n = sourceInput.size(); i < n; i++) { 091 input.add(dependencyGraph.getDependencyNode(sourceInput.get(i).getIndex())); 092 } 093 } else { 094 stack.push(dependencyGraph.getDependencyRoot()); 095 for (int i = dependencyGraph.getHighestTokenIndex(); i > 0; i--) { 096 final DependencyNode node = dependencyGraph.getDependencyNode(i); 097 if (node != null && !node.hasHead()) { // added !node.hasHead() 098 input.push(node); 099 } 100 } 101 } 102 } 103 104 public void initialize() throws MaltChainedException { 105 stack.push(dependencyGraph.getDependencyRoot()); 106 for (int i = dependencyGraph.getHighestTokenIndex(); i > 0; i--) { 107 final DependencyNode node = dependencyGraph.getDependencyNode(i); 108 if (node != null && !node.hasHead()) { // added !node.hasHead() 109 input.push(node); 110 } 111 } 112 } 113 114 public void setEnd(boolean end) { 115 this.end = end; 116 } 117 118 public boolean isEnd() { 119 return end; 120 } 121 122 public boolean isAllowRoot() { 123 return allowRoot; 124 } 125 126 public boolean isAllowReduce() { 127 return allowReduce; 128 } 129 130 public boolean isEnforceTree() { 131 return enforceTree; 132 } 133 134 public void clear() throws MaltChainedException { 135 stack.clear(); 136 input.clear(); 137 historyNode = null; 138 end = false; // Added 139 } 140 141 public boolean equals(Object obj) { 142 if (this == obj) 143 return true; 144 if (obj == null) 145 return false; 146 if (getClass() != obj.getClass()) 147 return false; 148 NivreConfig that = (NivreConfig)obj; 149 150 if (stack.size() != that.getStack().size()) 151 return false; 152 if (input.size() != that.getInput().size()) 153 return false; 154 if (dependencyGraph.nEdges() != that.getDependencyGraph().nEdges()) 155 return false; 156 for (int i = 0; i < stack.size(); i++) { 157 if (stack.get(i).getIndex() != that.getStack().get(i).getIndex()) { 158 return false; 159 } 160 } 161 for (int i = 0; i < input.size(); i++) { 162 if (input.get(i).getIndex() != that.getInput().get(i).getIndex()) { 163 return false; 164 } 165 } 166 return dependencyGraph.getEdges().equals(that.getDependencyGraph().getEdges()); 167 } 168 169 public String toString() { 170 final StringBuilder sb = new StringBuilder(); 171 sb.append(stack.size()); 172 sb.append(", "); 173 sb.append(input.size()); 174 sb.append(", "); 175 sb.append(dependencyGraph.nEdges()); 176 sb.append(", "); 177 sb.append(allowRoot); 178 sb.append(", "); 179 sb.append(allowReduce); 180 sb.append(", "); 181 sb.append(enforceTree); 182 return sb.toString(); 183 } 184}