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