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