001 package org.maltparser.parser.history; 002 003 import java.util.ArrayList; 004 import java.util.HashMap; 005 006 import org.maltparser.core.exception.MaltChainedException; 007 import org.maltparser.core.symbol.TableHandler; 008 import org.maltparser.parser.history.action.ActionDecision; 009 import org.maltparser.parser.history.action.ComplexDecisionAction; 010 import org.maltparser.parser.history.action.GuideDecision; 011 import org.maltparser.parser.history.action.GuideUserAction; 012 import org.maltparser.parser.history.container.ActionContainer; 013 import org.maltparser.parser.history.container.CombinedTableContainer; 014 import org.maltparser.parser.history.container.TableContainer; 015 import org.maltparser.parser.history.kbest.KBestList; 016 017 /** 018 * 019 * @author Johan Hall 020 * @since 1.1 021 **/ 022 public class History implements GuideUserHistory, GuideHistory { 023 protected ArrayList<ActionDecision> history; 024 protected int currentAction; 025 protected Class<? extends KBestList> kBestListClass = null; 026 protected int kBestSize; 027 protected String separator = "~"; 028 protected String decisionSettings; 029 protected ArrayList<TableContainer> decisionTables; 030 protected ArrayList<TableContainer> actionTables; 031 protected HashMap<String, TableHandler> tableHandlers; 032 033 public History(String decisionSettings, String separator, HashMap<String, TableHandler> tableHandlers) throws MaltChainedException { 034 setTableHandlers(tableHandlers); 035 setSeparator(separator); 036 initDecisionSettings(decisionSettings); 037 history = new ArrayList<ActionDecision>(); 038 clear(); 039 } 040 041 /* GuideUserHistory interface */ 042 public GuideUserAction getEmptyGuideUserAction() throws MaltChainedException { 043 return (GuideUserAction)getEmptyActionObject(); 044 } 045 046 public ArrayList<ActionContainer> getActionContainers() { 047 ArrayList<ActionContainer> actionContainers = new ArrayList<ActionContainer>(); 048 for (int i=0; i<actionTables.size(); i++) { 049 actionContainers.add(new ActionContainer(actionTables.get(i))); 050 } 051 return actionContainers; 052 } 053 054 public void clear() { 055 currentAction = -1; 056 } 057 058 /* GuideHistory interface */ 059 public GuideDecision getEmptyGuideDecision() throws MaltChainedException { 060 return (GuideDecision)getEmptyActionObject(); 061 } 062 063 public int getNumberOfDecisions() { 064 return decisionTables.size(); 065 } 066 067 public TableHandler getTableHandler(String name) { 068 return tableHandlers.get(name); 069 } 070 071 public Class<? extends KBestList> getKBestListClass() { 072 return kBestListClass; 073 } 074 075 public void setKBestListClass(Class<?> kBestListClass) throws MaltChainedException { 076 try { 077 if (kBestListClass != null) { 078 this.kBestListClass = kBestListClass.asSubclass(org.maltparser.parser.history.kbest.KBestList.class); 079 } 080 } catch (ClassCastException e) { 081 throw new HistoryException("The class '"+kBestListClass.getName()+"' is not a subclass of '"+org.maltparser.parser.history.kbest.KBestList.class.getName()+"'. ", e); 082 } 083 } 084 085 public int getKBestSize() { 086 return kBestSize; 087 } 088 089 public void setKBestSize(int kBestSize) { 090 this.kBestSize = kBestSize; 091 } 092 093 public int getNumberOfActions() { 094 return actionTables.size(); 095 } 096 097 public ArrayList<TableContainer> getDecisionTables() { 098 return decisionTables; 099 } 100 101 public ArrayList<TableContainer> getActionTables() { 102 return actionTables; 103 } 104 105 public HashMap<String, TableHandler> getTableHandlers() { 106 return tableHandlers; 107 } 108 109 public String getSeparator() { 110 return separator; 111 } 112 113 public void setSeparator(String separator) throws MaltChainedException { 114 if (separator == null || separator.length() < 1) { 115 throw new HistoryException("The class item separator (--guide-classitem_separator) does not have correct value. "); 116 } 117 this.separator = separator; 118 } 119 120 public String getDecisionSettings() { 121 return decisionSettings; 122 } 123 124 public void setDecisionSettings(String decisionSettings) { 125 this.decisionSettings = decisionSettings; 126 } 127 128 protected void setTableHandlers(HashMap<String, TableHandler> tableHandlers) { 129 this.tableHandlers = tableHandlers; 130 } 131 132 protected ActionDecision getEmptyActionObject() throws MaltChainedException { 133 ActionDecision actionObject = null; 134 if (currentAction + 1 >= history.size()) { 135 actionObject = new ComplexDecisionAction(this); 136 } else { 137 actionObject = history.get(++currentAction); 138 actionObject.clear(); 139 } 140 return actionObject; 141 } 142 143 protected void initDecisionSettings(String decisionSettings) throws MaltChainedException { 144 decisionTables = new ArrayList<TableContainer>(); 145 actionTables = new ArrayList<TableContainer>(); 146 this.decisionSettings = decisionSettings; 147 int start = 0; 148 int k = 0; 149 char prevDecisionSeparator = ' '; 150 TableContainer tmp = null; 151 final StringBuilder sbTableHandler = new StringBuilder(); 152 final StringBuilder sbTable = new StringBuilder(); 153 int state = 0; 154 for (int i = 0; i < decisionSettings.length(); i++) { 155 switch (decisionSettings.charAt(i)) { 156 case '.': 157 if (state != 0) { 158 //error 159 } 160 state = 1; 161 break; 162 case '+': 163 tmp = new TableContainer(tableHandlers.get(sbTableHandler.toString()).getSymbolTable(sbTable.toString()), sbTableHandler.toString()+"."+sbTable.toString(), '+'); 164 actionTables.add(tmp); 165 k++; 166 sbTableHandler.setLength(0); 167 sbTable.setLength(0); 168 state = 0; 169 break; 170 case '#': 171 state = 2; 172 break; 173 case ';': 174 state = 2; 175 break; 176 case ',': 177 state = 2; 178 break; 179 default: 180 if (state == 0) { 181 sbTableHandler.append(decisionSettings.charAt(i)); 182 } else if (state == 1) { 183 sbTable.append(decisionSettings.charAt(i)); 184 } 185 } 186 if (state == 2 || i == decisionSettings.length()-1) { 187 char decisionSeparator = decisionSettings.charAt(i); 188 if (i == decisionSettings.length()-1) { 189 //decisionSeparator = ' '; 190 decisionSeparator = prevDecisionSeparator; 191 } 192 tmp = new TableContainer(tableHandlers.get(sbTableHandler.toString()).getSymbolTable(sbTable.toString()), sbTableHandler.toString()+"."+sbTable.toString(), decisionSeparator); 193 actionTables.add(tmp); 194 k++; 195 if (k-start > 1) { 196 decisionTables.add(new CombinedTableContainer(getTableHandler("A"), separator, actionTables.subList(start, k), decisionSeparator)); 197 } else { 198 decisionTables.add(tmp); 199 } 200 sbTableHandler.setLength(0); 201 sbTable.setLength(0); 202 state = 0; 203 start = k; 204 prevDecisionSeparator = decisionSeparator; 205 } 206 } 207 } 208 209 public String toString() { 210 StringBuilder sb = new StringBuilder(); 211 212 for (int i = 0; i <= currentAction; i++) { 213 sb.append(history.get(i)); 214 } 215 return sb.toString(); 216 } 217 }