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