001 package org.maltparser.parser.algorithm.nivre; 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.ParsingException; 010 import org.maltparser.parser.algorithm.helper.TransitionTable; 011 import org.maltparser.parser.history.container.ActionContainer; 012 013 /** 014 * 015 * @author Joakim Nivre 016 * @author Johan Hall 017 * @since 1.0 018 */ 019 public class NivreStandard extends Nivre { 020 protected static final int RIGHTARC = 2; 021 protected static final int LEFTARC = 3; 022 023 public NivreStandard(SingleMalt configuration) throws MaltChainedException { 024 super(configuration); 025 } 026 027 protected void transition(DependencyStructure parseDependencyGraph) throws MaltChainedException { 028 currentAction.getAction(actionContainers); 029 while (checkParserAction(parseDependencyGraph) == false) { 030 if (configuration.getMode() == SingleMalt.LEARN || configuration.predictFromKBestList(currentAction) == false) { 031 updateActionContainers(SHIFT, null); // default parser action 032 break; 033 } 034 currentAction.getAction(actionContainers); 035 } 036 Edge e = null; 037 switch (getTransition()) { 038 case LEFTARC: 039 e = parseDependencyGraph.addDependencyEdge(input.peek().getIndex(), stack.peek().getIndex()); 040 addEdgeLabels(e); 041 stack.pop(); 042 break; 043 case RIGHTARC: 044 e = parseDependencyGraph.addDependencyEdge(stack.peek().getIndex(), input.peek().getIndex()); 045 addEdgeLabels(e); 046 input.pop(); 047 if (!stack.peek().isRoot()) { 048 input.push(stack.pop()); 049 } 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 = getTransition(); 059 if ((trans == LEFTARC || trans == RIGHTARC) && !isActionContainersLabeled()) { 060 // Label code is null for transitions LEFTARC and RIGHTARC 061 return false; 062 } 063 /* if (trans == SHIFT && parserAction.getLastLabelCode() != null) { 064 // Label code is not null for transition SHIFT 065 }*/ 066 if (trans == LEFTARC && stack.peek().isRoot()) { 067 // The token on top of the stack is root for transition LEFTARC 068 return false; 069 } 070 return true; 071 } 072 073 074 protected void oraclePredict(DependencyStructure gold, DependencyStructure parseDependencyGraph) throws MaltChainedException { 075 if (!stack.peek().isRoot() && gold.getTokenNode(stack.peek().getIndex()).getHead().getIndex() == input.peek().getIndex()) { 076 updateActionContainers(LEFTARC, gold.getTokenNode(stack.peek().getIndex()).getHeadEdge().getLabelSet()); 077 } else if (gold.getTokenNode(input.peek().getIndex()).getHead().getIndex() == stack.peek().getIndex() && checkRightDependent(gold, parseDependencyGraph)) { 078 updateActionContainers(RIGHTARC, gold.getTokenNode(input.peek().getIndex()).getHeadEdge().getLabelSet()); 079 } else { 080 updateActionContainers(SHIFT, null); 081 } 082 } 083 084 private boolean checkRightDependent(DependencyStructure gold, DependencyStructure parseDependencyGraph) throws MaltChainedException { 085 if (gold.getTokenNode(input.peek().getIndex()).getRightmostDependent() == null) { 086 return true; 087 } else if (parseDependencyGraph.getTokenNode(input.peek().getIndex()).getRightmostDependent() != null) { 088 if (gold.getTokenNode(input.peek().getIndex()).getRightmostDependent().getIndex() == parseDependencyGraph.getTokenNode(input.peek().getIndex()).getRightmostDependent().getIndex()) { 089 return true; 090 } 091 } 092 return false; 093 } 094 095 096 protected int getTransition() { 097 return transActionContainer.getActionCode(); 098 } 099 100 protected void updateActionContainers(int transition, LabelSet arcLabels) throws MaltChainedException { 101 if (complexTransition) { 102 switch (transition) { 103 case SHIFT: 104 pushActionContainer.setAction(1); 105 transActionContainer.setAction(transition); 106 break; 107 case RIGHTARC: 108 pushActionContainer.setAction(1); 109 transActionContainer.setAction(transition); 110 break; 111 case LEFTARC: 112 pushActionContainer.setAction(2); 113 transActionContainer.setAction(transition); 114 break; 115 default: 116 throw new ParsingException("Unknown transition "+transition+". "); 117 } 118 } else { 119 transActionContainer.setAction(transition); 120 } 121 if (arcLabels == null) { 122 for (ActionContainer container : arcLabelActionContainers) { 123 container.setAction(-1); 124 } 125 } else { 126 for (ActionContainer container : arcLabelActionContainers) { 127 container.setAction(arcLabels.get(container.getTable()).shortValue()); 128 } 129 } 130 currentAction.addAction(actionContainers); 131 } 132 133 134 protected void addAvailableTransitionToTable(TransitionTable ttable) throws MaltChainedException { 135 ttable.addTransition(SHIFT, "SH", false, null); 136 ttable.addTransition(RIGHTARC, "RA", true, null); 137 ttable.addTransition(LEFTARC, "LA", true, null); 138 } 139 140 protected void initWithDefaultTransitions() throws MaltChainedException { 141 if (!complexTransition) { 142 if (transActionContainer == null) { 143 throw new ParsingException("The decision settings does not contain T.TRANS or T.PUSH;T.TRANS"); 144 } 145 addTransition(transActionContainer, currentAction, SHIFT); 146 } else { 147 if (pushActionContainer == null || transActionContainer == null) { 148 throw new ParsingException("The decision settings does not contain T.TRANS or T.PUSH;T.TRANS"); 149 } 150 addTransition(transActionContainer, currentAction, SHIFT); 151 } 152 } 153 154 public String getName() { 155 return "nivrestandard"; 156 } 157 }