    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    }