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