1d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar/* 2d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * Copyright (C) 2015 The Android Open Source Project 3d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * 4d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * Licensed under the Apache License, Version 2.0 (the "License"); 5d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * you may not use this file except in compliance with the License. 6d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * You may obtain a copy of the License at 7d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * 8d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * http://www.apache.org/licenses/LICENSE-2.0 9d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * 10d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * Unless required by applicable law or agreed to in writing, software 11d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * distributed under the License is distributed on an "AS IS" BASIS, 12d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * See the License for the specific language governing permissions and 14d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * limitations under the License. 15d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar */ 16d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 17fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountpackage android.databinding.tool; 18d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 19d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarimport org.antlr.v4.runtime.ANTLRInputStream; 20fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyarimport org.antlr.v4.runtime.BaseErrorListener; 21d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarimport org.antlr.v4.runtime.CommonTokenStream; 22c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyarimport org.antlr.v4.runtime.ParserRuleContext; 23fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyarimport org.antlr.v4.runtime.RecognitionException; 24fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyarimport org.antlr.v4.runtime.Recognizer; 25fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyarimport org.antlr.v4.runtime.Token; 26c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyarimport org.antlr.v4.runtime.misc.Nullable; 27c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyarimport org.antlr.v4.runtime.tree.ErrorNode; 28c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyarimport org.antlr.v4.runtime.tree.ParseTreeListener; 29c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyarimport org.antlr.v4.runtime.tree.TerminalNode; 30d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 31fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.parser.BindingExpressionLexer; 32fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.parser.BindingExpressionParser; 33fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.Expr; 34fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.expr.ExprModel; 35fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyarimport android.databinding.tool.processing.ErrorMessages; 36c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyarimport android.databinding.tool.store.Location; 37fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.util.L; 38c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyarimport android.databinding.tool.util.Preconditions; 39c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar 40c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyarimport java.util.ArrayList; 41c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyarimport java.util.List; 42fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount 43d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarpublic class ExpressionParser { 44d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar final ExprModel mModel; 45d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar final ExpressionVisitor visitor; 46d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 47d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar public ExpressionParser(ExprModel model) { 48d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar mModel = model; 49d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar visitor = new ExpressionVisitor(mModel); 50d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 51d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 52c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar public Expr parse(String input, @Nullable Location locationInFile) { 53d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar ANTLRInputStream inputStream = new ANTLRInputStream(input); 54d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar BindingExpressionLexer lexer = new BindingExpressionLexer(inputStream); 55d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar CommonTokenStream tokenStream = new CommonTokenStream(lexer); 56c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar final BindingExpressionParser parser = new BindingExpressionParser(tokenStream); 57fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyar parser.addErrorListener(new BaseErrorListener() { 58fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyar @Override 59fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyar public <T extends Token> void syntaxError(Recognizer<T, ?> recognizer, 60fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyar @Nullable T offendingSymbol, int line, int charPositionInLine, String msg, 61fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyar @Nullable RecognitionException e) { 62fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyar L.e(ErrorMessages.SYNTAX_ERROR, msg); 63fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyar } 64fd8342a51a96282df315cd27055ba539e89a8c9eYigit Boyar }); 65d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar BindingExpressionParser.BindingSyntaxContext root = parser.bindingSyntax(); 66c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar try { 67c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar mModel.setCurrentLocationInFile(locationInFile); 68c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar visitor.setParseTreeListener(new ParseTreeListener() { 69c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar List<ParserRuleContext> mStack = new ArrayList<ParserRuleContext>(); 70c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar @Override 71c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar public void visitTerminal(TerminalNode node) { 72c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar } 73c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar 74c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar @Override 75c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar public void visitErrorNode(ErrorNode node) { 76c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar } 77c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar 78c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar @Override 79c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar public void enterEveryRule(ParserRuleContext ctx) { 80c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar mStack.add(ctx); 81c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar mModel.setCurrentParserContext(ctx); 82c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar } 83c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar 84c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar @Override 85c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar public void exitEveryRule(ParserRuleContext ctx) { 86c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar Preconditions.check(ctx == mStack.get(mStack.size() - 1), 87c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar "Inconsistent exit from context. Received %s, expecting %s", 88c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar ctx.toInfoString(parser), 89c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar mStack.get(mStack.size() - 1).toInfoString(parser)); 90c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar mStack.remove(mStack.size() - 1); 91c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar if (mStack.size() > 0) { 92c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar mModel.setCurrentParserContext(mStack.get(mStack.size() - 1)); 93c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar } else { 94c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar mModel.setCurrentParserContext(null); 95c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar } 96c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar } 97c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar }); 98731b74f7f44e67312a1fc4161c4e0aae221b2417Yigit Boyar return root.accept(visitor); 99c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar } finally { 100c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar mModel.setCurrentLocationInFile(null); 101c1560e6b00b398867da12fbdc5a1fcd1d50b801cYigit Boyar } 102d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 103d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 104d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar public ExprModel getModel() { 105d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return mModel; 106d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 107d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 108