001 package org.maltparser.parser; 002 003 import java.io.BufferedWriter; 004 import java.io.FileWriter; 005 import java.io.IOException; 006 import java.io.OutputStreamWriter; 007 import java.lang.reflect.Constructor; 008 import java.lang.reflect.InvocationTargetException; 009 010 import org.maltparser.core.config.ConfigurationException; 011 import org.maltparser.core.exception.MaltChainedException; 012 import org.maltparser.core.symbol.SymbolTable; 013 import org.maltparser.core.syntaxgraph.DependencyStructure; 014 import org.maltparser.core.syntaxgraph.edge.Edge; 015 import org.maltparser.core.syntaxgraph.node.DependencyNode; 016 import org.maltparser.parser.guide.ClassifierGuide; 017 /** 018 * @author Johan Hall 019 * 020 */ 021 public abstract class Algorithm { 022 protected DependencyParserConfig manager; 023 protected ClassifierGuide classifierGuide; 024 protected ParserState parserState; 025 protected ParserConfiguration currentParserConfiguration; 026 protected boolean diagnostics = false; 027 protected BufferedWriter diaWriter; 028 /** 029 * Creates a parsing algorithm 030 * 031 * @param manager a reference to the single malt configuration 032 * @throws MaltChainedException 033 */ 034 public Algorithm(DependencyParserConfig manager) throws MaltChainedException { 035 setManager(manager); 036 setDiagnostics((Boolean)manager.getOptionValue("singlemalt", "diagnostics")); 037 if (diagnostics) { 038 openDiaWriter(manager.getOptionValue("singlemalt", "diafile").toString()); 039 } 040 } 041 042 public abstract void terminate() throws MaltChainedException; 043 044 public boolean isDiagnostics() { 045 return diagnostics; 046 } 047 048 public void setDiagnostics(boolean diagnostics) { 049 this.diagnostics = diagnostics; 050 } 051 052 053 public BufferedWriter getDiaWriter() { 054 return diaWriter; 055 } 056 057 public void writeToDiaFile(String message) throws MaltChainedException { 058 try { 059 getDiaWriter().write(message); 060 } catch (IOException e) { 061 throw new MaltChainedException("Could not write to the diagnostic file. ", e); 062 } 063 } 064 065 public void closeDiaWriter() throws MaltChainedException { 066 if (diaWriter != null) { 067 try { 068 diaWriter.flush(); 069 diaWriter.close(); 070 } catch (IOException e) { 071 throw new MaltChainedException("Could not close the diagnostic file. ", e); 072 } 073 } 074 } 075 076 public void openDiaWriter(String fileName) throws MaltChainedException { 077 if (diagnostics) { 078 try { 079 if (fileName.equals("stdout")) { 080 diaWriter = new BufferedWriter(new OutputStreamWriter(System.out)); 081 } else if (fileName.equals("stderr")) { 082 diaWriter = new BufferedWriter(new OutputStreamWriter(System.err)); 083 } else { 084 diaWriter = new BufferedWriter(new FileWriter(fileName)); 085 } 086 } catch (IOException e) { 087 throw new MaltChainedException("Could not open the diagnostic file. ", e); 088 } 089 } 090 } 091 092 /** 093 * Returns the classifier guide. 094 * 095 * @return the classifier guide 096 */ 097 public ClassifierGuide getGuide() { 098 return classifierGuide; 099 } 100 101 /** 102 * Sets the classifier guide 103 * 104 * @param guide a classifier guide 105 */ 106 public void setGuide(ClassifierGuide guide) { 107 this.classifierGuide = guide; 108 } 109 110 /** 111 * Returns the current active parser configuration 112 * 113 * @return the current active parser configuration 114 */ 115 public ParserConfiguration getCurrentParserConfiguration() { 116 return currentParserConfiguration; 117 } 118 119 /** 120 * Sets the current parser configuration 121 * 122 * @param currentParserConfiguration a parser configuration 123 */ 124 protected void setCurrentParserConfiguration(ParserConfiguration currentParserConfiguration) { 125 this.currentParserConfiguration = currentParserConfiguration; 126 } 127 128 /** 129 * Returns the parser state 130 * 131 * @return the parser state 132 */ 133 public ParserState getParserState() { 134 return parserState; 135 } 136 137 /** 138 * Sets the parser state 139 * 140 * @param parserState a parser state 141 */ 142 protected void setParserState(ParserState parserState) { 143 this.parserState = parserState; 144 } 145 146 /** 147 * Creates a parser factory specified by the --singlemalt-parsing_algorithm option 148 * 149 * @return a parser factory 150 * @throws MaltChainedException 151 */ 152 protected AbstractParserFactory makeParserFactory() throws MaltChainedException { 153 Class<?> clazz = (Class<?>)manager.getOptionValue("singlemalt", "parsing_algorithm"); 154 try { 155 Class<?>[] params = new Class<?>[1]; 156 params[0] = org.maltparser.parser.Algorithm.class; 157 Object[] arguments = new Object[params.length]; 158 arguments[0] = this; 159 Constructor<?> constructor = clazz.getConstructor(params); 160 return (AbstractParserFactory)constructor.newInstance(arguments); 161 } catch (NoSuchMethodException e) { 162 throw new ConfigurationException("The parser factory '"+clazz.getName()+"' cannot be initialized. ", e); 163 } catch (InstantiationException e) { 164 throw new ConfigurationException("The parser factory '"+clazz.getName()+"' cannot be initialized. ", e); 165 } catch (IllegalAccessException e) { 166 throw new ConfigurationException("The parser factory '"+clazz.getName()+"' cannot be initialized. ", e); 167 } catch (InvocationTargetException e) { 168 throw new ConfigurationException("The parser factory '"+clazz.getName()+"' cannot be initialized. ", e); 169 } 170 } 171 172 protected void initParserState(int k) throws MaltChainedException { 173 AbstractParserFactory parserFactory = makeParserFactory(); 174 ((SingleMalt)manager).addRegistry(parserFactory.getClass(), parserFactory); 175 parserState = new ParserState(this, parserFactory, k); 176 } 177 178 /** 179 * Returns the single malt configuration 180 * 181 * @return the single malt configuration 182 */ 183 public DependencyParserConfig getManager() { 184 return manager; 185 } 186 187 /** 188 * Sets the single malt configuration 189 * 190 * @param manager a single malt configuration 191 */ 192 public void setManager(DependencyParserConfig manager) { 193 this.manager = manager; 194 } 195 196 /** 197 * Copies the edges of the source dependency structure to the target dependency structure 198 * 199 * @param source a source dependency structure 200 * @param target a target dependency structure 201 * @throws MaltChainedException 202 */ 203 protected void copyEdges(DependencyStructure source, DependencyStructure target) throws MaltChainedException { 204 for (int index : source.getTokenIndices()) { 205 DependencyNode snode = source.getTokenNode(index); 206 207 if (snode.hasHead()) { 208 Edge s = snode.getHeadEdge(); 209 Edge t = target.addDependencyEdge(s.getSource().getIndex(), s.getTarget().getIndex()); 210 211 for (SymbolTable table : s.getLabelTypes()) { 212 t.addLabel(table, s.getLabelSymbol(table)); 213 } 214 } 215 } 216 } 217 218 protected void copyDynamicInput(DependencyStructure source, DependencyStructure target) throws MaltChainedException { 219 for (int index : source.getTokenIndices()) { 220 DependencyNode snode = source.getTokenNode(index); 221 DependencyNode tnode = target.getTokenNode(index); 222 for (SymbolTable table : snode.getLabelTypes()) { 223 if (!tnode.hasLabel(table)) { 224 tnode.addLabel(table,snode.getLabelSymbol(table)); 225 } 226 } 227 } 228 } 229 }