| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 1 | package de.ids_mannheim.korap.query.serialize; |
| 2 | |
| 3 | import java.lang.reflect.Method; |
| 4 | import java.util.ArrayList; |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 5 | import java.util.LinkedHashMap; |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 6 | |
| 7 | import org.antlr.v4.runtime.ANTLRInputStream; |
| 8 | import org.antlr.v4.runtime.BailErrorStrategy; |
| 9 | import org.antlr.v4.runtime.CharStream; |
| 10 | import org.antlr.v4.runtime.CommonTokenStream; |
| 11 | import org.antlr.v4.runtime.Lexer; |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 12 | import org.antlr.v4.runtime.ParserRuleContext; |
| 13 | import org.antlr.v4.runtime.tree.ParseTree; |
| Joachim Bingel | 3d5b69b | 2015-01-14 10:46:44 +0000 | [diff] [blame] | 14 | import org.slf4j.Logger; |
| 15 | import org.slf4j.LoggerFactory; |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 16 | |
| Joachim Bingel | 3d5b69b | 2015-01-14 10:46:44 +0000 | [diff] [blame] | 17 | //TODO replace AqlLexer with lexer for your Antlr4 grammar! |
| Joachim Bingel | 6003b85 | 2014-12-18 14:20:55 +0000 | [diff] [blame] | 18 | import de.ids_mannheim.korap.query.parse.annis.AqlLexer; |
| Joachim Bingel | 3d5b69b | 2015-01-14 10:46:44 +0000 | [diff] [blame] | 19 | //TODO replace AqlParser with parser for your Antlr4 grammar! |
| Joachim Bingel | 6003b85 | 2014-12-18 14:20:55 +0000 | [diff] [blame] | 20 | import de.ids_mannheim.korap.query.parse.annis.AqlParser; |
| Joachim Bingel | aa4ab2f | 2015-01-16 14:26:51 +0000 | [diff] [blame] | 21 | import de.ids_mannheim.korap.query.serialize.util.KoralObjectGenerator; |
| Joachim Bingel | 3d5b69b | 2015-01-14 10:46:44 +0000 | [diff] [blame] | 22 | import de.ids_mannheim.korap.query.serialize.util.StatusCodes; |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 23 | |
| 24 | /** |
| 25 | * Map representation of syntax tree as returned by ANTLR |
| Joachim Bingel | 3d5b69b | 2015-01-14 10:46:44 +0000 | [diff] [blame] | 26 | * @author Joachim Bingel (bingel@ids-mannheim.de) |
| Joachim Bingel | 7cb346e | 2015-03-09 10:56:20 +0100 | [diff] [blame^] | 27 | * @version 0.3.0 |
| 28 | * @since 0.1.0 |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 29 | */ |
| Joachim Bingel | 1faf8a5 | 2015-01-09 13:17:34 +0000 | [diff] [blame] | 30 | public class TreeTemplate extends Antlr4AbstractQueryProcessor { |
| Joachim Bingel | 3d5b69b | 2015-01-14 10:46:44 +0000 | [diff] [blame] | 31 | private static Logger log = LoggerFactory.getLogger(TreeTemplate.class); |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 32 | /** |
| 33 | * |
| 34 | * @param tree The syntax tree as returned by ANTLR |
| 35 | * @param parser The ANTLR parser instance that generated the parse tree |
| 36 | */ |
| 37 | public TreeTemplate(String query) { |
| Joachim Bingel | aa4ab2f | 2015-01-16 14:26:51 +0000 | [diff] [blame] | 38 | KoralObjectGenerator.setQueryProcessor(this); |
| Joachim Bingel | 3d5b69b | 2015-01-14 10:46:44 +0000 | [diff] [blame] | 39 | process(query); |
| 40 | } |
| 41 | |
| 42 | @Override |
| 43 | public void process(String query) { |
| 44 | ParseTree tree = parseQuery(query); |
| 45 | super.parser = this.parser; |
| 46 | if (tree != null) { |
| 47 | log.debug("ANTLR parse tree: "+tree.toStringTree(parser)); |
| 48 | processNode(tree); |
| 49 | } else { |
| 50 | addError(StatusCodes.MALFORMED_QUERY, "Could not parse query >>> "+query+" <<<."); |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 51 | } |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 52 | } |
| Joachim Bingel | 3d5b69b | 2015-01-14 10:46:44 +0000 | [diff] [blame] | 53 | |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 54 | private void processNode(ParseTree node) { |
| 55 | // Top-down processing |
| 56 | if (visited.contains(node)) return; |
| 57 | else visited.add(node); |
| Joachim Bingel | 3d5b69b | 2015-01-14 10:46:44 +0000 | [diff] [blame] | 58 | |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 59 | String nodeCat = getNodeCat(node); |
| 60 | openNodeCats.push(nodeCat); |
| Joachim Bingel | 3d5b69b | 2015-01-14 10:46:44 +0000 | [diff] [blame] | 61 | |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 62 | stackedObjects = 0; |
| Joachim Bingel | 3d5b69b | 2015-01-14 10:46:44 +0000 | [diff] [blame] | 63 | |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 64 | if (verbose) { |
| 65 | System.err.println(" "+objectStack); |
| 66 | System.out.println(openNodeCats); |
| 67 | } |
| 68 | |
| 69 | /* |
| 70 | **************************************************************** |
| 71 | **************************************************************** |
| 72 | * Processing individual node categories * |
| 73 | **************************************************************** |
| 74 | **************************************************************** |
| 75 | */ |
| 76 | |
| 77 | objectsToPop.push(stackedObjects); |
| Joachim Bingel | 3d5b69b | 2015-01-14 10:46:44 +0000 | [diff] [blame] | 78 | |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 79 | /* |
| 80 | **************************************************************** |
| 81 | **************************************************************** |
| 82 | * recursion until 'request' node (root of tree) is processed * |
| 83 | **************************************************************** |
| 84 | **************************************************************** |
| 85 | */ |
| 86 | for (int i=0; i<node.getChildCount(); i++) { |
| 87 | ParseTree child = node.getChild(i); |
| 88 | processNode(child); |
| 89 | } |
| Joachim Bingel | 3d5b69b | 2015-01-14 10:46:44 +0000 | [diff] [blame] | 90 | |
| 91 | |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 92 | /* |
| 93 | ************************************************************** |
| 94 | * Stuff that happens after processing the children of a node * |
| 95 | ************************************************************** |
| 96 | */ |
| Joachim Bingel | 3d5b69b | 2015-01-14 10:46:44 +0000 | [diff] [blame] | 97 | |
| 98 | |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 99 | for (int i=0; i<objectsToPop.pop(); i++) { |
| 100 | objectStack.pop(); |
| 101 | } |
| Joachim Bingel | 3d5b69b | 2015-01-14 10:46:44 +0000 | [diff] [blame] | 102 | |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 103 | |
| 104 | openNodeCats.pop(); |
| Joachim Bingel | 3d5b69b | 2015-01-14 10:46:44 +0000 | [diff] [blame] | 105 | |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 106 | } |
| 107 | |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 108 | @SuppressWarnings("unused") |
| 109 | private void putIntoSuperObject(LinkedHashMap<String, Object> object) { |
| 110 | putIntoSuperObject(object, 0); |
| 111 | } |
| Joachim Bingel | 3d5b69b | 2015-01-14 10:46:44 +0000 | [diff] [blame] | 112 | |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 113 | @SuppressWarnings({ "unchecked" }) |
| 114 | private void putIntoSuperObject(LinkedHashMap<String, Object> object, int objStackPosition) { |
| Joachim Bingel | 3d5b69b | 2015-01-14 10:46:44 +0000 | [diff] [blame] | 115 | if (objectStack.size()>objStackPosition) { |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 116 | ArrayList<Object> topObjectOperands = (ArrayList<Object>) objectStack.get(objStackPosition).get("operands"); |
| 117 | topObjectOperands.add(0, object); |
| Joachim Bingel | 3d5b69b | 2015-01-14 10:46:44 +0000 | [diff] [blame] | 118 | |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 119 | } else { |
| 120 | requestMap.put("query", object); |
| 121 | } |
| 122 | } |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 123 | |
| Joachim Bingel | 3d5b69b | 2015-01-14 10:46:44 +0000 | [diff] [blame] | 124 | private ParserRuleContext parseQuery (String q) { |
| 125 | //TODO replace AqlLexer with lexer for your Antlr4 grammar! |
| 126 | Lexer qlLexer = new AqlLexer((CharStream)null); |
| 127 | ParserRuleContext tree = null; |
| 128 | // Like p. 111 |
| 129 | try { |
| 130 | // Tokenize input data |
| 131 | ANTLRInputStream input = new ANTLRInputStream(q); |
| 132 | qlLexer.setInputStream(input); |
| 133 | CommonTokenStream tokens = new CommonTokenStream(qlLexer); |
| 134 | //TODO replace AqlParser with parser for your Antlr4 grammar! |
| 135 | parser = new AqlParser(tokens); |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 136 | |
| Joachim Bingel | 3d5b69b | 2015-01-14 10:46:44 +0000 | [diff] [blame] | 137 | // Don't throw out erroneous stuff |
| 138 | parser.setErrorHandler(new BailErrorStrategy()); |
| 139 | parser.removeErrorListeners(); |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 140 | |
| Joachim Bingel | 3d5b69b | 2015-01-14 10:46:44 +0000 | [diff] [blame] | 141 | // Get starting rule from parser |
| 142 | //TODO replace AqlParser with parser for your Antlr4 grammar! |
| 143 | Method startRule = AqlParser.class.getMethod("start"); |
| 144 | tree = (ParserRuleContext) startRule.invoke(parser, (Object[])null); |
| 145 | } |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 146 | |
| Joachim Bingel | 3d5b69b | 2015-01-14 10:46:44 +0000 | [diff] [blame] | 147 | // Some things went wrong ... |
| 148 | catch (Exception e) { |
| 149 | System.err.println( e.getMessage() ); |
| 150 | } |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 151 | |
| Joachim Bingel | 3d5b69b | 2015-01-14 10:46:44 +0000 | [diff] [blame] | 152 | // Return the generated tree |
| 153 | return tree; |
| 154 | } |
| Joachim Bingel | c8a28e4 | 2014-04-24 15:06:42 +0000 | [diff] [blame] | 155 | } |