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