001package org.maltparser.parser.algorithm.stack; 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 StackConfig extends ParserConfiguration { 015 private final Stack<DependencyNode> stack; 016 private final Stack<DependencyNode> input; 017 private DependencyStructure dependencyGraph; 018 private int lookahead; 019 020 public StackConfig() throws MaltChainedException { 021 super(); 022 stack = new Stack<DependencyNode>(); 023 input = new Stack<DependencyNode>(); 024// dependencyGraph = new DependencyGraph(symbolTableHandler); 025 } 026 027 public Stack<DependencyNode> getStack() { 028 return stack; 029 } 030 031 public Stack<DependencyNode> getInput() { 032 return input; 033 } 034 035 public DependencyStructure getDependencyStructure() { 036 return dependencyGraph; 037 } 038 039 public boolean isTerminalState() { 040 return input.isEmpty() && stack.size() == 1; 041 } 042 043 public DependencyNode getStackNode(int index) throws MaltChainedException { 044 if (index < 0) { 045 throw new ParsingException("Stack index must be non-negative in feature specification. "); 046 } 047 if (stack.size()-index > 0) { 048 return stack.get(stack.size()-1-index); 049 } 050 return null; 051 } 052 053 private DependencyNode getBufferNode(int index) throws MaltChainedException { 054 if (index < 0) { 055 throw new ParsingException("Input index must be non-negative in feature specification. "); 056 } 057 if (input.size()-index > 0) { 058 return input.get(input.size()-1-index); 059 } 060 return null; 061 } 062 063 public DependencyNode getLookaheadNode(int index) throws MaltChainedException { 064 return getBufferNode(lookahead+index); 065 } 066 067 public DependencyNode getInputNode(int index) throws MaltChainedException { 068 if (index < lookahead) { 069 return getBufferNode(index); 070 } 071 return null; 072 } 073 074 public void setDependencyGraph(DependencyStructure source) throws MaltChainedException { 075 this.dependencyGraph = source; 076// dependencyGraph.clear(); 077// for (int index : source.getTokenIndices()) { 078// DependencyNode gnode = source.getDependencyNode(index); 079// DependencyNode pnode = dependencyGraph.addDependencyNode(gnode.getIndex()); 080// for (SymbolTable table : gnode.getLabelTypes()) { 081// pnode.addLabel(table, gnode.getLabelSymbol(table)); 082// } 083// 084// if (gnode.hasHead()) { 085// Edge s = gnode.getHeadEdge(); 086// Edge t = dependencyGraph.addDependencyEdge(s.getSource().getIndex(), s.getTarget().getIndex()); 087// 088// for (SymbolTable table : s.getLabelTypes()) { 089// t.addLabel(table, s.getLabelSymbol(table)); 090// } 091// } 092// } 093// for (SymbolTable table : source.getDefaultRootEdgeLabels().keySet()) { 094// dependencyGraph.setDefaultRootEdgeLabel(table, source.getDefaultRootEdgeLabelSymbol(table)); 095// } 096 } 097 098 public void lookaheadIncrement() { 099 lookahead++; 100 } 101 102 public void lookaheadDecrement() { 103 if (lookahead > 0) { 104 lookahead--; 105 } 106 } 107 108 public DependencyStructure getDependencyGraph() { 109 return dependencyGraph; 110 } 111 112 public void initialize(ParserConfiguration parserConfiguration) throws MaltChainedException { 113 if (parserConfiguration != null) { 114 StackConfig config = (StackConfig)parserConfiguration; 115 Stack<DependencyNode> sourceStack = config.getStack(); 116 Stack<DependencyNode> sourceInput = config.getInput(); 117 setDependencyGraph(config.getDependencyGraph()); 118 for (int i = 0, n = sourceStack.size(); i < n; i++) { 119 stack.add(dependencyGraph.getDependencyNode(sourceStack.get(i).getIndex())); 120 } 121 for (int i = 0, n = sourceInput.size(); i < n; i++) { 122 input.add(dependencyGraph.getDependencyNode(sourceInput.get(i).getIndex())); 123 } 124 } else { 125 stack.push(dependencyGraph.getDependencyRoot()); 126 for (int i = dependencyGraph.getHighestTokenIndex(); i > 0; i--) { 127 final DependencyNode node = dependencyGraph.getDependencyNode(i); 128 if (node != null && !node.hasHead()) { 129 input.push(node); 130 } 131 } 132 } 133 } 134 135 public void initialize() throws MaltChainedException { 136 stack.push(dependencyGraph.getDependencyRoot()); 137 for (int i = dependencyGraph.getHighestTokenIndex(); i > 0; i--) { 138 final DependencyNode node = dependencyGraph.getDependencyNode(i); 139 if (node != null && !node.hasHead()) { 140 input.push(node); 141 } 142 } 143 } 144 145 public boolean equals(Object obj) { 146 if (this == obj) 147 return true; 148 if (obj == null) 149 return false; 150 if (getClass() != obj.getClass()) 151 return false; 152 StackConfig that = (StackConfig)obj; 153 154 if (lookahead != that.lookahead) 155 return false; 156 if (stack.size() != that.getStack().size()) 157 return false; 158 if (input.size() != that.getInput().size()) 159 return false; 160 if (dependencyGraph.nEdges() != that.getDependencyGraph().nEdges()) 161 return false; 162 for (int i = 0; i < stack.size(); i++) { 163 if (stack.get(i).getIndex() != that.getStack().get(i).getIndex()) { 164 return false; 165 } 166 } 167 for (int i = 0; i < input.size(); i++) { 168 if (input.get(i).getIndex() != that.getInput().get(i).getIndex()) { 169 return false; 170 } 171 } 172 return dependencyGraph.getEdges().equals(that.getDependencyGraph().getEdges()); 173 } 174 175 public void clear() throws MaltChainedException { 176// dependencyGraph.clear(); 177 stack.clear(); 178 input.clear(); 179 historyNode = null; 180 lookahead = 0; 181 } 182 183 public String toString() { 184 final StringBuilder sb = new StringBuilder(); 185 sb.append(stack.size()); 186 sb.append(", "); 187 sb.append(input.size()); 188 sb.append(", "); 189 sb.append(dependencyGraph.nEdges()); 190 return sb.toString(); 191 } 192}