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 009 import org.maltparser.parser.SingleMalt; 010 import org.maltparser.parser.algorithm.ParsingException; 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 NivreEager extends Nivre { 021 protected static final int REDUCE = 2; 022 protected static final int RIGHTARC = 3; 023 protected static final int LEFTARC = 4; 024 025 public NivreEager(SingleMalt configuration) throws MaltChainedException { 026 super(configuration); 027 } 028 029 protected void transition(DependencyStructure parseDependencyGraph) throws MaltChainedException { 030 currentAction.getAction(actionContainers); 031 while (checkParserAction(parseDependencyGraph) == false) { 032 if (configuration.getMode() == SingleMalt.LEARN || configuration.predictFromKBestList(currentAction) == false) { 033 updateActionContainers(SHIFT, null); 034 break; 035 } 036 currentAction.getAction(actionContainers); 037 } 038 Edge e = null; 039 switch (getTransition()) { 040 case LEFTARC: 041 e = parseDependencyGraph.addDependencyEdge(input.peek().getIndex(), stack.peek().getIndex()); 042 addEdgeLabels(e); 043 stack.pop(); 044 break; 045 case RIGHTARC: 046 e = parseDependencyGraph.addDependencyEdge(stack.peek().getIndex(), input.peek().getIndex()); 047 addEdgeLabels(e); 048 stack.push(input.pop()); 049 break; 050 case REDUCE: 051 stack.pop(); 052 break; 053 default: 054 stack.push(input.pop()); // SHIFT 055 break; 056 } 057 } 058 059 protected boolean checkParserAction(DependencyStructure dg) throws MaltChainedException { 060 final int trans = getTransition(); 061 if ((trans == LEFTARC || trans == RIGHTARC) && !isActionContainersLabeled()) { 062 // LabelCode cannot be found for transition LEFTARC and RIGHTARC 063 return false; 064 } 065 if ((trans == LEFTARC || trans == REDUCE) && stack.peek().isRoot()) { 066 // The token on top of the stack is the root for LEFTARC and REDUCE 067 return false; 068 } 069 if (trans == LEFTARC && stack.peek().hasHead()) { 070 // The token on top of the stack has already a head for transition LEFTARC 071 return false; 072 } 073 if (trans == REDUCE && !stack.peek().hasHead() && rootHandling == STRICT) { 074 // The token on top of the stack have not a head for transition REDUCE 075 return false; 076 } 077 return true; 078 } 079 080 081 protected void oraclePredict(DependencyStructure gold, DependencyStructure parseDependencyGraph) throws MaltChainedException { 082 if (!stack.peek().isRoot() && gold.getTokenNode(stack.peek().getIndex()).getHead().getIndex() == input.peek().getIndex()) { 083 updateActionContainers(LEFTARC, gold.getTokenNode(stack.peek().getIndex()).getHeadEdge().getLabelSet()); 084 } else if (gold.getTokenNode(input.peek().getIndex()).getHead().getIndex() == stack.peek().getIndex()) { 085 updateActionContainers(RIGHTARC, gold.getTokenNode(input.peek().getIndex()).getHeadEdge().getLabelSet()); 086 } else if (gold.getTokenNode(input.peek().getIndex()).hasLeftDependent() && 087 gold.getTokenNode(input.peek().getIndex()).getLeftmostDependent().getIndex() < stack.peek().getIndex()) { 088 updateActionContainers(REDUCE, null); 089 /*} else if (gold.getTokenNode(input.peek().getIndex()).getHead().getIndex() < stack.peek().getIndex() && 090 (!(gold.getTokenNode(input.peek().getIndex()).getLabelCode(deprel) == gold.getRootLabels().getRootLabelCode(deprel)) )) { 091 parserAction.addAction(REDUCE); */ 092 } else if (gold.getTokenNode(input.peek().getIndex()).getHead().getIndex() < stack.peek().getIndex() && 093 (!gold.getTokenNode(input.peek().getIndex()).getHead().isRoot() || rootHandling == NORMAL )) { 094 updateActionContainers(REDUCE, null); 095 } else { 096 updateActionContainers(SHIFT, null); 097 } 098 } 099 100 protected int getTransition() { 101 return transActionContainer.getActionCode(); 102 } 103 104 protected void updateActionContainers(int transition, LabelSet arcLabels) throws MaltChainedException { 105 if (complexTransition) { 106 switch (transition) { 107 case SHIFT: 108 pushActionContainer.setAction(1); 109 transActionContainer.setAction(transition); 110 break; 111 case REDUCE: 112 pushActionContainer.setAction(2); 113 transActionContainer.setAction(transition); 114 break; 115 case RIGHTARC: 116 pushActionContainer.setAction(1); 117 transActionContainer.setAction(transition); 118 break; 119 case LEFTARC: 120 pushActionContainer.setAction(2); 121 transActionContainer.setAction(transition); 122 break; 123 default: 124 throw new ParsingException("Unknown transition "+transition+". "); 125 } 126 } else { 127 transActionContainer.setAction(transition); 128 } 129 if (arcLabels == null) { 130 for (ActionContainer container : arcLabelActionContainers) { 131 container.setAction(-1); 132 } 133 } else { 134 for (ActionContainer container : arcLabelActionContainers) { 135 container.setAction(arcLabels.get(container.getTable()).intValue()); 136 } 137 } 138 currentAction.addAction(actionContainers); 139 } 140 141 protected void addAvailableTransitionToTable(TransitionTable ttable) throws MaltChainedException { 142 ttable.addTransition(SHIFT, "SH", false, null); 143 ttable.addTransition(REDUCE, "RE", false, null); 144 ttable.addTransition(RIGHTARC, "RA", true, null); 145 ttable.addTransition(LEFTARC, "LA", true, null); 146 } 147 148 protected void initWithDefaultTransitions() throws MaltChainedException { 149 if (!complexTransition) { 150 if (transActionContainer == null) { 151 throw new ParsingException("The decision settings does not contain T.TRANS or T.PUSH;T.TRANS"); 152 } 153 addTransition(transActionContainer, currentAction, SHIFT); 154 addTransition(transActionContainer, currentAction, REDUCE); 155 } else { 156 if (pushActionContainer == null || transActionContainer == null) { 157 throw new ParsingException("The decision settings does not contain T.TRANS or T.PUSH;T.TRANS"); 158 } 159 addTransition(transActionContainer, currentAction, SHIFT); 160 addTransition(transActionContainer, currentAction, REDUCE); 161 } 162 } 163 164 public String getName() { 165 return "nivreeager"; 166 } 167 }