001    // This file is part of AceWiki.
002    // Copyright 2008-2012, AceWiki developers.
003    // 
004    // AceWiki is free software: you can redistribute it and/or modify it under the terms of the GNU
005    // Lesser General Public License as published by the Free Software Foundation, either version 3 of
006    // the License, or (at your option) any later version.
007    // 
008    // AceWiki is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
009    // even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
010    // Lesser General Public License for more details.
011    // 
012    // You should have received a copy of the GNU Lesser General Public License along with AceWiki. If
013    // not, see http://www.gnu.org/licenses/.
014    
015    package ch.uzh.ifi.attempto.acewiki.gf;
016    
017    import java.io.InputStream;
018    import java.util.HashMap;
019    import java.util.List;
020    import java.util.Map;
021    
022    import org.grammaticalframework.Linearizer;
023    import org.grammaticalframework.PGF;
024    import org.grammaticalframework.PGFBuilder;
025    import org.grammaticalframework.Parser;
026    import org.grammaticalframework.parser.ParseState;
027    
028    /**
029     * This class wraps GF features of a particular GF grammar.
030     * 
031     * @author Tobias Kuhn
032     */
033    public class GFGrammar {
034            
035            private String fileName;
036            private String serializationLanguage;
037            private PGF pgf;
038            private Map<String, Parser> parsers = new HashMap<String, Parser>();
039            private Map<String, Linearizer> linearizers = new HashMap<String, Linearizer>();
040            
041            /**
042             * Creates a new GF grammar object.
043             * 
044             * @param pgfFile Path and name of the pgf file.
045             * @param serializationLanguage The language used for serialization.
046             */
047            public GFGrammar(String pgfFile, String serializationLanguage) {
048                    if (!pgfFile.matches("^.*/[^\\/]+.pgf$")) {
049                            throw new RuntimeException("Illegal pgf filename");
050                    }
051                    fileName = pgfFile.replaceFirst("^.*/([^\\/]+).pgf$", "$1");
052                    this.serializationLanguage = serializationLanguage;
053                    try {
054                            ClassLoader cl = Thread.currentThread().getContextClassLoader();
055                            InputStream in = cl.getResourceAsStream(pgfFile);
056                            pgf = PGFBuilder.fromInputStream(in);
057                    } catch (Exception ex) {
058                            ex.printStackTrace();
059                    }
060            }
061            
062            private Parser getGFParser(String language) {
063                    Parser p = parsers.get(language);
064                    if (p == null) {
065                            try {
066                                    p = new Parser(pgf, fileName + language);
067                            } catch (Exception ex) {
068                                    ex.printStackTrace();
069                            }
070                            parsers.put(language, p);
071                    }
072                    return p;
073            }
074            
075            /**
076             * Parses the given text in the given language.
077             * 
078             * @param text The text.
079             * @param language The language.
080             * @return The parse result.
081             */
082            public ParseState parse(String text, String language) {
083                    return getGFParser(language).parse(text);
084            }
085    
086            /**
087             * Parses the given tokens in the given language.
088             * 
089             * @param tokens The tokens.
090             * @param language The language.
091             * @return The parse result.
092             */
093            public ParseState parse(String[] tokens, String language) {
094                    return getGFParser(language).parse(tokens);
095            }
096            
097            /**
098             * Deserializes a serialized representation into a parse state.
099             * 
100             * @param serialized The serialized representation
101             * @return The parse state.
102             */
103            public ParseState deserialize(String serialized) {
104                    return parse(serialized, serializationLanguage);
105            }
106            
107            private Linearizer getGFLinearizer(String language) {
108                    Linearizer l = linearizers.get(language);
109                    if (l == null) {
110                            try {
111                                    l = new Linearizer(pgf, fileName + language);
112                            } catch (Exception ex) {
113                                    ex.printStackTrace();
114                            }
115                            linearizers.put(language, l);
116                    }
117                    return l;
118            }
119            
120            /**
121             * Linearizes a parse state in the given language.
122             * 
123             * @param parseState The parse state.
124             * @param language The language.
125             * @return The linearization as a string.
126             */
127            public String linearizeAsString(ParseState parseState, String language) {
128                    try {
129                            return getGFLinearizer(language).linearizeString(parseState.getTrees()[0]);
130                    } catch (Exception ex) {
131                            ex.printStackTrace();
132                    }
133                    return null;
134            }
135    
136            /**
137             * Linearizes a parse state in the given language.
138             * 
139             * @param parseState The parse state.
140             * @param language The language.
141             * @return The linearization as a list of tokens.
142             */
143            public List<String> linearizeAsTokens(ParseState parseState, String language) {
144                    try {
145                            return getGFLinearizer(language).linearizeTokens(parseState.getTrees()[0]);
146                    } catch (Exception ex) {
147                            ex.printStackTrace();
148                    }
149                    return null;
150            }
151            
152            /**
153             * Serializes a given parse state.
154             * 
155             * @param parseState The parse state.
156             * @return The serialization.
157             */
158            public String serialize(ParseState parseState) {
159                    return linearizeAsString(parseState, serializationLanguage);
160            }
161    
162    }