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