001package org.maltparser.parser.algorithm.stack; 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 017/** 018 * @author Johan Hall 019 * 020 */ 021public 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(PropagationManager propagationManager) throws MaltChainedException { 028 super(propagationManager); 029 } 030 031 public void apply(GuideUserAction currentAction, ParserConfiguration configuration) throws MaltChainedException { 032 final StackConfig config = (StackConfig)configuration; 033 final Stack<DependencyNode> stack = config.getStack(); 034 final 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 config.lookaheadIncrement(); 057 break; 058 default: 059 if (input.isEmpty()) { 060 stack.pop(); 061 } else { 062 stack.push(input.pop()); // SHIFT 063 } 064 config.lookaheadDecrement(); 065 break; 066 } 067 } 068 069 public boolean permissible(GuideUserAction currentAction, ParserConfiguration configuration) throws MaltChainedException { 070 currentAction.getAction(actionContainers); 071 int trans = transActionContainer.getActionCode(); 072 if ((trans == LEFTARC || trans == RIGHTARC) && !isActionContainersLabeled()) { 073 return false; 074 } 075 final StackConfig config = (StackConfig)configuration; 076 final Stack<DependencyNode> stack = config.getStack(); 077 if ((trans == LEFTARC || trans == RIGHTARC || trans == SWAP) && stack.size() < 2) { 078 return false; 079 } 080 if ((trans == LEFTARC || trans == SWAP) && stack.get(stack.size()-2).isRoot()) { 081 return false; 082 } 083 final Stack<DependencyNode> input = config.getInput(); 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); 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}