    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                    StackConfig config = (StackConfig)configuration;
    031                    Stack<DependencyNode> stack = config.getStack();
    032                    Stack<DependencyNode> input = config.getInput();
    033                    currentAction.getAction(actionContainers);
    034                    Edge e = null;
    035                    DependencyNode head = null;
    036                    DependencyNode dep = null;
    037                    switch (transActionContainer.getActionCode()) {
    038                    case LEFTARC:
    039                            head = stack.pop();
    040                            dep = stack.pop();
    041                            e = config.getDependencyStructure().addDependencyEdge(head.getIndex(), dep.getIndex());
    042                            addEdgeLabels(e);
    043                            stack.push(head);
    044                            break;
    045                    case RIGHTARC:
    046                            dep = stack.pop();
    047                            e = config.getDependencyStructure().addDependencyEdge(stack.peek().getIndex(), dep.getIndex());
    048                            addEdgeLabels(e);
    049                            break;
    050                    default:
    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                    StackConfig config = (StackConfig)configuration;
    062                    currentAction.getAction(actionContainers);
    063                    int trans = transActionContainer.getActionCode();
    064                    if ((trans == LEFTARC || trans == RIGHTARC) && !isActionContainersLabeled()) {
    065                            return false;
    066                    }
    067                    Stack<DependencyNode> stack = config.getStack();
    068                    Stack<DependencyNode> input = config.getInput();
    069                    if ((trans == LEFTARC || trans == RIGHTARC) && stack.size() < 2) {
    070                            return false;
    071                    }
    072                    if (trans == LEFTARC && stack.get(stack.size()-2).isRoot()) {
    073                            return false;
    074                    }
    075                    if (trans == SHIFT && input.isEmpty()) {
    076                            return false;
    077                    }
    078
    079                    return true;
    080            }
    081
    082            public GuideUserAction getDeterministicAction(GuideUserHistory history, ParserConfiguration config) throws MaltChainedException {
    083                    return null;
    084            }
    085
    086            protected void addAvailableTransitionToTable(TransitionTable ttable) throws MaltChainedException {
    087                    ttable.addTransition(SHIFT, "SH", false, null);
    088                    ttable.addTransition(RIGHTARC, "RA", true, null);
    089                    ttable.addTransition(LEFTARC, "LA", true, null);
    090            }
    091
    092            protected void initWithDefaultTransitions(GuideUserHistory history) throws MaltChainedException {
    093                    GuideUserAction currentAction = new ComplexDecisionAction((History)history);
    094
    095                    transActionContainer.setAction(SHIFT);
    096                    for (int i = 0; i < arcLabelActionContainers.length; i++) {
    097                            arcLabelActionContainers[i].setAction(-1);
    098                    }
    099                    currentAction.addAction(actionContainers);
    100            }
    101
    102            public String getName() {
    103                    return "projective";
    104            }
    105
    106            public GuideUserAction defaultAction(GuideUserHistory history, ParserConfiguration configuration) throws MaltChainedException {
    107                    if (((StackConfig)configuration).getInput().isEmpty()) {
    108                            LabelSet labelSet = ((StackConfig)configuration).getDependencyGraph().getDefaultRootEdgeLabels();
    109                            return updateActionContainers(history, RIGHTARC, labelSet);
    110                    }
    111                    return updateActionContainers(history, SHIFT, null);
    112            }
    113    }