    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    }