001 package org.maltparser.parser.algorithm.nivre.malt04; 002 003 004 import org.maltparser.core.exception.MaltChainedException; 005 import org.maltparser.core.syntaxgraph.DependencyStructure; 006 import org.maltparser.core.syntaxgraph.LabelSet; 007 import org.maltparser.core.syntaxgraph.edge.Edge; 008 import org.maltparser.parser.SingleMalt; 009 import org.maltparser.parser.algorithm.helper.TransitionTable; 010 import org.maltparser.parser.history.container.ActionContainer; 011 012 /** 013 * 014 * @author Joakim Nivre 015 * @author Johan Hall 016 * @since 1.0 017 */ 018 public class NivreEagerMalt04 extends NivreMalt04 { 019 protected static final int REDUCE = 2; 020 protected static final int RIGHTARC = 3; 021 protected static final int LEFTARC = 4; 022 023 public NivreEagerMalt04(SingleMalt configuration) throws MaltChainedException { 024 super(configuration); 025 } 026 027 protected void transition(DependencyStructure parseDependencyGraph) throws MaltChainedException { 028 currentAction.getAction(actionContainers); 029 if (checkParserAction(parseDependencyGraph) == false) { 030 updateActionContainers(SHIFT, null);//default parser action 031 } 032 Edge e = null; 033 switch (transActionContainer.getActionCode()) { 034 case LEFTARC: 035 e = parseDependencyGraph.addDependencyEdge(input.peek().getIndex(), stack.peek().getIndex()); 036 addEdgeLabels(e); 037 stack.pop(); 038 break; 039 case RIGHTARC: 040 if (!(inPostProcessingMode == true && !stack.peek().isRoot() 041 && parseDependencyGraph.getDefaultRootEdgeLabelCode(deprel) == getArcLabels(parseDependencyGraph).get(deprel).intValue() 042 )) { 043 e = parseDependencyGraph.addDependencyEdge(stack.peek().getIndex(), input.peek().getIndex()); 044 addEdgeLabels(e); 045 } 046 stack.push(input.pop()); 047 break; 048 case REDUCE: 049 stack.pop(); 050 break; 051 default: 052 stack.push(input.pop()); // SHIFT 053 break; 054 } 055 } 056 057 protected boolean checkParserAction(DependencyStructure dg) throws MaltChainedException { 058 int trans = transActionContainer.getActionCode(); 059 if ((trans == LEFTARC || trans == RIGHTARC) && !isActionContainersLabeled()) { 060 // LabelCode cannot be found for transition LEFTARC and RIGHTARC 061 return false; 062 } 063 /* if ((trans == SHIFT || trans == REDUCE) && parserAction.getLastLabelCode() != null) { 064 // LabelCode can be found for transition SHIFT and REDUCE 065 return false; 066 }*/ 067 if ((trans == LEFTARC || trans == REDUCE) && stack.peek().isRoot()) { 068 // The token on top of the stack is the root for LEFTARC and REDUCE 069 return false; 070 } 071 if (trans == LEFTARC && stack.peek().hasHead()) { 072 // The token on top of the stack has already a head for transition LEFTARC 073 return false; 074 } 075 if (trans == REDUCE && !stack.peek().hasHead() && rootHandling == STRICT) { 076 // The token on top of the stack have not a head for transition REDUCE 077 return false; 078 } 079 return true; 080 } 081 082 083 protected void oraclePredict(DependencyStructure gold, DependencyStructure parseDependencyGraph) throws MaltChainedException { 084 if (!stack.peek().isRoot() && gold.getTokenNode(stack.peek().getIndex()).getHead().getIndex() == input.peek().getIndex()) { 085 updateActionContainers(LEFTARC, gold.getTokenNode(stack.peek().getIndex()).getHeadEdge().getLabelSet()); 086 } else if (gold.getTokenNode(input.peek().getIndex()).getHead().getIndex() == stack.peek().getIndex()) { 087 updateActionContainers(RIGHTARC, gold.getTokenNode(input.peek().getIndex()).getHeadEdge().getLabelSet()); 088 } else if (gold.getTokenNode(input.peek().getIndex()).hasLeftDependent() && 089 gold.getTokenNode(input.peek().getIndex()).getLeftmostDependent().getIndex() < stack.peek().getIndex()) { 090 updateActionContainers(REDUCE, null); 091 } else if (gold.getTokenNode(input.peek().getIndex()).getHead().getIndex() < stack.peek().getIndex() 092 && (!(gold.getTokenNode(input.peek().getIndex()).getHeadEdgeLabelCode(deprel) == parseDependencyGraph.getDefaultRootEdgeLabelCode(deprel))) 093 ) { 094 updateActionContainers(REDUCE, null); 095 } else { 096 updateActionContainers(SHIFT, null); 097 } 098 } 099 100 public String getName() { 101 return "nivreeager"; 102 } 103 104 105 protected int getTransition() { 106 return transActionContainer.getActionCode(); 107 } 108 109 protected void updateActionContainers(int transition, LabelSet arcLabels) throws MaltChainedException { 110 transActionContainer.setAction(transition); 111 if (arcLabels == null) { 112 for (ActionContainer container : arcLabelActionContainers) { 113 container.setAction(-1); 114 } 115 } else { 116 for (ActionContainer container : arcLabelActionContainers) { 117 container.setAction(arcLabels.get(container.getTable()).shortValue()); 118 } 119 } 120 currentAction.addAction(actionContainers); 121 } 122 123 protected void addAvailableTransitionToTable(TransitionTable ttable) throws MaltChainedException { 124 ttable.addTransition(SHIFT, "SH", false, null); 125 ttable.addTransition(REDUCE, "RE", false, null); 126 ttable.addTransition(RIGHTARC, "RA", true, null); 127 ttable.addTransition(LEFTARC, "LA", true, null); 128 } 129 130 protected void initWithDefaultTransitions() throws MaltChainedException { 131 addTransition(transActionContainer, currentAction, SHIFT); 132 addTransition(transActionContainer, currentAction, REDUCE); 133 deprel = configuration.getSymbolTables().getSymbolTable("DEPREL"); 134 for (int i = 1; i < deprel.getValueCounter(); i++) { 135 if (!getConfiguration().getOptionValue("graph", "root_label").toString().equals(deprel.getSymbolCodeToString(i))) { 136 actionContainers.get(0).setAction(RIGHTARC); 137 actionContainers.get(1).setAction(i); 138 currentAction.addAction(actionContainers); 139 } 140 } 141 for (int i = 1; i < deprel.getValueCounter(); i++) { 142 if (!getConfiguration().getOptionValue("graph", "root_label").toString().equals(deprel.getSymbolCodeToString(i))) { 143 actionContainers.get(0).setAction(LEFTARC); 144 actionContainers.get(1).setAction(i); 145 currentAction.addAction(actionContainers); 146 } 147 } 148 } 149 } 150