    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    }