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 }