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                    NivreConfig nivreConfig = (NivreConfig)config;
031                    Stack<DependencyNode> stack = nivreConfig.getStack();
032                    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                    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                    int trans = transActionContainer.getActionCode();
090                    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    }