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