001 package org.maltparser.parser; 002 003 import java.util.HashMap; 004 005 import org.maltparser.core.exception.MaltChainedException; 006 import org.maltparser.core.propagation.PropagationManager; 007 import org.maltparser.core.symbol.SymbolTable; 008 import org.maltparser.core.symbol.SymbolTableHandler; 009 import org.maltparser.core.symbol.TableHandler; 010 import org.maltparser.core.syntaxgraph.DependencyGraph; 011 import org.maltparser.core.syntaxgraph.LabelSet; 012 import org.maltparser.core.syntaxgraph.edge.Edge; 013 import org.maltparser.parser.history.GuideUserHistory; 014 import org.maltparser.parser.history.action.GuideUserAction; 015 import org.maltparser.parser.history.container.ActionContainer; 016 import org.maltparser.parser.transition.TransitionTable; 017 import org.maltparser.parser.transition.TransitionTableHandler; 018 /** 019 * @author Johan Hall 020 * 021 */ 022 public abstract class TransitionSystem { 023 protected HashMap<String, TableHandler> tableHandlers; 024 protected TransitionTableHandler transitionTableHandler; 025 protected ActionContainer[] actionContainers; 026 protected ActionContainer transActionContainer; 027 protected ActionContainer[] arcLabelActionContainers; 028 protected PropagationManager propagationManager = null; 029 030 public TransitionSystem() throws MaltChainedException { } 031 032 public abstract void apply(GuideUserAction currentAction, ParserConfiguration config) throws MaltChainedException; 033 public abstract boolean permissible(GuideUserAction currentAction, ParserConfiguration config) throws MaltChainedException; 034 public abstract GuideUserAction getDeterministicAction(GuideUserHistory history, ParserConfiguration config) throws MaltChainedException; 035 protected abstract void addAvailableTransitionToTable(TransitionTable ttable) throws MaltChainedException; 036 protected abstract void initWithDefaultTransitions(GuideUserHistory history) throws MaltChainedException; 037 public abstract String getName(); 038 public abstract GuideUserAction defaultAction(GuideUserHistory history, ParserConfiguration configuration) throws MaltChainedException; 039 040 protected GuideUserAction updateActionContainers(GuideUserHistory history, int transition, LabelSet arcLabels) throws MaltChainedException { 041 transActionContainer.setAction(transition); 042 043 if (arcLabels == null) { 044 for (int i = 0; i < arcLabelActionContainers.length; i++) { 045 arcLabelActionContainers[i].setAction(-1); 046 } 047 } else { 048 for (int i = 0; i < arcLabelActionContainers.length; i++) { 049 if (arcLabelActionContainers[i] == null) { 050 throw new MaltChainedException("arcLabelActionContainer " + i + " is null when doing transition " + transition); 051 } 052 053 Integer code = arcLabels.get(arcLabelActionContainers[i].getTable()); 054 if (code != null) { 055 arcLabelActionContainers[i].setAction(code.shortValue()); 056 } else { 057 arcLabelActionContainers[i].setAction(-1); 058 } 059 } 060 } 061 GuideUserAction oracleAction = history.getEmptyGuideUserAction(); 062 oracleAction.addAction(actionContainers); 063 return oracleAction; 064 } 065 066 protected boolean isActionContainersLabeled() { 067 for (int i = 0; i < arcLabelActionContainers.length; i++) { 068 if (arcLabelActionContainers[i].getActionCode() < 0) { 069 return false; 070 } 071 } 072 return true; 073 } 074 075 protected void addEdgeLabels(Edge e) throws MaltChainedException { 076 if (e != null) { 077 for (int i = 0; i < arcLabelActionContainers.length; i++) { 078 if (arcLabelActionContainers[i].getActionCode() != -1) { 079 e.addLabel((SymbolTable)arcLabelActionContainers[i].getTable(), arcLabelActionContainers[i].getActionCode()); 080 } else { 081 e.addLabel((SymbolTable)arcLabelActionContainers[i].getTable(), ((DependencyGraph)e.getBelongsToGraph()).getDefaultRootEdgeLabelCode((SymbolTable)arcLabelActionContainers[i].getTable())); 082 } 083 } 084 if (propagationManager != null) { 085 propagationManager.propagate(e); 086 } 087 } 088 } 089 090 public void initTransitionSystem(GuideUserHistory history) throws MaltChainedException { 091 this.actionContainers = history.getActionContainerArray(); 092 if (actionContainers.length < 1) { 093 throw new ParsingException("Problem when initialize the history (sequence of actions). There are no action containers. "); 094 } 095 int nLabels = 0; 096 for (int i = 0; i < actionContainers.length; i++) { 097 if (actionContainers[i].getTableContainerName().startsWith("A.")) { 098 nLabels++; 099 } 100 } 101 int j = 0; 102 for (int i = 0; i < actionContainers.length; i++) { 103 if (actionContainers[i].getTableContainerName().equals("T.TRANS")) { 104 transActionContainer = actionContainers[i]; 105 } else if (actionContainers[i].getTableContainerName().startsWith("A.")) { 106 if (arcLabelActionContainers == null) { 107 arcLabelActionContainers = new ActionContainer[nLabels]; 108 } 109 arcLabelActionContainers[j++] = actionContainers[i]; 110 } 111 } 112 initWithDefaultTransitions(history); 113 } 114 115 public void initTableHandlers(String decisionSettings, SymbolTableHandler symbolTableHandler) throws MaltChainedException { 116 transitionTableHandler = new TransitionTableHandler(); 117 tableHandlers = new HashMap<String, TableHandler>(); 118 119 final String[] decisionElements = decisionSettings.split(",|#|;|\\+"); 120 121 int nTrans = 0; 122 for (int i = 0; i < decisionElements.length; i++) { 123 int index = decisionElements[i].indexOf('.'); 124 if (index == -1) { 125 throw new ParsingException("Decision settings '"+decisionSettings+"' contain an item '"+decisionElements[i]+"' that does not follow the format {TableHandler}.{Table}. "); 126 } 127 if (decisionElements[i].substring(0,index).equals("T")) { 128 if (!getTableHandlers().containsKey("T")) { 129 getTableHandlers().put("T", getTransitionTableHandler()); 130 } 131 if (decisionElements[i].substring(index+1).equals("TRANS")) { 132 if (nTrans == 0) { 133 TransitionTable ttable = (TransitionTable)getTransitionTableHandler().addSymbolTable("TRANS"); 134 addAvailableTransitionToTable(ttable); 135 } else { 136 throw new ParsingException("Illegal decision settings '"+decisionSettings+"'"); 137 } 138 nTrans++; 139 } 140 } else if (decisionElements[i].substring(0,index).equals("A")) { 141 if (!getTableHandlers().containsKey("A")) { 142 getTableHandlers().put("A", symbolTableHandler); 143 } 144 } else { 145 throw new ParsingException("The decision settings '"+decisionSettings+"' contains an unknown table handler '"+decisionElements[i].substring(0,index)+"'. " + 146 "Only T (Transition table handler) and A (ArcLabel table handler) is allowed. "); 147 } 148 } 149 } 150 151 public void copyAction(GuideUserAction source, GuideUserAction target) throws MaltChainedException { 152 source.getAction(actionContainers); 153 target.addAction(actionContainers); 154 } 155 156 public HashMap<String, TableHandler> getTableHandlers() { 157 return tableHandlers; 158 } 159 160 public TransitionTableHandler getTransitionTableHandler() { 161 return transitionTableHandler; 162 } 163 164 public PropagationManager getPropagationManager() { 165 return propagationManager; 166 } 167 168 // protected void doPropagation(Edge e) throws MaltChainedException{ 169 // 170 // } 171 172 public void setPropagationManager(PropagationManager propagationManager) { 173 this.propagationManager = propagationManager; 174 } 175 176 public String getActionString(GuideUserAction action) throws MaltChainedException { 177 StringBuilder sb = new StringBuilder(); 178 action.getAction(actionContainers); 179 TransitionTable ttable = (TransitionTable)getTransitionTableHandler().getSymbolTable("TRANS"); 180 sb.append(ttable.getSymbolCodeToString(transActionContainer.getActionCode())); 181 for (int i = 0; i < arcLabelActionContainers.length; i++) { 182 if (arcLabelActionContainers[i].getActionCode() != -1) { 183 sb.append("+"); 184 sb.append(arcLabelActionContainers[i].getTable().getSymbolCodeToString(arcLabelActionContainers[i].getActionCode())); 185 } 186 } 187 return sb.toString(); 188 } 189 }