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