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