• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
ExpressionParser(ExprModel model)42     public ExpressionParser(ExprModel model) {
43         mModel = model;
44         visitor = new ExpressionVisitor(mModel);
45     }
46 
parse(String input, @Nullable Location locationInFile)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 
getModel()91     public ExprModel getModel() {
92         return mModel;
93     }
94 }
95