    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.syntaxgraph.edge.Edge;
    007    import org.maltparser.core.syntaxgraph.node.DependencyNode;
    008    import org.maltparser.parser.ParserConfiguration;
    009    import org.maltparser.parser.TransitionSystem;
    010    import org.maltparser.parser.history.GuideUserHistory;
    011    import org.maltparser.parser.history.History;
    012    import org.maltparser.parser.history.action.ComplexDecisionAction;
    013    import org.maltparser.parser.history.action.GuideUserAction;
    014    import org.maltparser.parser.transition.TransitionTable;
    015
    016
    017    /**
    018     * @author Johan Hall
    019     *
    020     */
    021    public class NonProjective extends TransitionSystem {
    022            protected static final int SHIFT = 1;
    023            protected static final int SWAP = 2;
    024            protected static final int RIGHTARC = 3;
    025            protected static final int LEFTARC = 4;
    026
    027            public NonProjective() throws MaltChainedException {
    028                    super();
    029            }
    030
    031            public void apply(GuideUserAction currentAction, ParserConfiguration configuration) throws MaltChainedException {
    032                    StackConfig config = (StackConfig)configuration;
    033                    Stack<DependencyNode> stack = config.getStack();
    034                    Stack<DependencyNode> input = config.getInput();
    035                    currentAction.getAction(actionContainers);
    036                    Edge e = null;
    037                    DependencyNode head = null;
    038                    DependencyNode dep = null;
    039                    switch (transActionContainer.getActionCode()) {
    040                    case LEFTARC:
    041                            head = stack.pop();
    042                            dep = stack.pop();
    043                            e = config.getDependencyStructure().addDependencyEdge(head.getIndex(), dep.getIndex());
    044                            addEdgeLabels(e);
    045                            stack.push(head);
    046                            break;
    047                    case RIGHTARC:
    048                            dep = stack.pop();
    049                            e = config.getDependencyStructure().addDependencyEdge(stack.peek().getIndex(), dep.getIndex());
    050                            addEdgeLabels(e);
    051                            break;
    052                    case SWAP:
    053                            dep = stack.pop();
    054                            input.push(stack.pop());
    055                            stack.push(dep);
    056                            ((StackConfig)configuration).lookaheadIncrement();
    057                            break;
    058                    default:
    059                            if (input.isEmpty()) {
    060                                    stack.pop();
    061                            } else {
    062                                    stack.push(input.pop()); // SHIFT
    063                            }
    064                            ((StackConfig)configuration).lookaheadDecrement();
    065                            break;
    066                    }
    067            }
    068
    069            public boolean permissible(GuideUserAction currentAction, ParserConfiguration configuration) throws MaltChainedException {
    070                    StackConfig config = (StackConfig)configuration;
    071                    currentAction.getAction(actionContainers);
    072                    int trans = transActionContainer.getActionCode();
    073                    if ((trans == LEFTARC || trans == RIGHTARC) && !isActionContainersLabeled()) {
    074                            return false;
    075                    }
    076                    Stack<DependencyNode> stack = config.getStack();
    077                    Stack<DependencyNode> input = config.getInput();
    078                    if ((trans == LEFTARC || trans == RIGHTARC || trans == SWAP) && stack.size() < 2) {
    079                            return false;
    080                    }
    081                    if ((trans == LEFTARC || trans == SWAP) && stack.get(stack.size()-2).isRoot()) {
    082                            return false;
    083                    }
    084                    if (trans == SHIFT && input.isEmpty()) {
    085                            return false;
    086                    }
    087                    if (trans == SWAP && stack.get(stack.size()-2).getIndex() > stack.get(stack.size()-1).getIndex()) {
    088                            return false;
    089                    }
    090                    return true;
    091            }
    092
    093            public GuideUserAction getDeterministicAction(GuideUserHistory history, ParserConfiguration config) throws MaltChainedException {
    094                    return null;
    095            }
    096
    097            protected void addAvailableTransitionToTable(TransitionTable ttable) throws MaltChainedException {
    098                    ttable.addTransition(SHIFT, "SH", false, null);
    099                    ttable.addTransition(SWAP, "SW", false, null);
    100                    ttable.addTransition(RIGHTARC, "RA", true, null);
    101                    ttable.addTransition(LEFTARC, "LA", true, null);
    102            }
    103
    104            protected void initWithDefaultTransitions(GuideUserHistory history) throws MaltChainedException {
    105                    GuideUserAction currentAction = new ComplexDecisionAction((History)history);
    106
    107                    transActionContainer.setAction(SHIFT);
    108                    //transActionContainer.setAction(SWAP);
    109                    for (int i = 0; i < arcLabelActionContainers.length; i++) {
    110                            arcLabelActionContainers[i].setAction(-1);
    111                    }
    112                    currentAction.addAction(actionContainers);
    113            }
    114
    115            public String getName() {
    116                    return "nonprojective";
    117            }
    118
    119            public GuideUserAction defaultAction(GuideUserHistory history, ParserConfiguration configuration) throws MaltChainedException {
    120                    if (((StackConfig)configuration).getInput().isEmpty()) {
    121                            return updateActionContainers(history, RIGHTARC, ((StackConfig)configuration).getDependencyGraph().getDefaultRootEdgeLabels());
    122                    }
    123                    return updateActionContainers(history, SHIFT, null);
    124            }
    125    }