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