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