• 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.BaseErrorListener;
21 import org.antlr.v4.runtime.CommonTokenStream;
22 import org.antlr.v4.runtime.ParserRuleContext;
23 import org.antlr.v4.runtime.RecognitionException;
24 import org.antlr.v4.runtime.Recognizer;
25 import org.antlr.v4.runtime.Token;
26 import org.antlr.v4.runtime.tree.ErrorNode;
27 import org.antlr.v4.runtime.tree.ParseTreeListener;
28 import org.antlr.v4.runtime.tree.TerminalNode;
29 
30 import android.databinding.parser.BindingExpressionLexer;
31 import android.databinding.parser.BindingExpressionParser;
32 import android.databinding.tool.expr.Expr;
33 import android.databinding.tool.expr.ExprModel;
34 import android.databinding.tool.processing.ErrorMessages;
35 import android.databinding.tool.store.Location;
36 import android.databinding.tool.util.L;
37 import android.databinding.tool.util.Preconditions;
38 
39 import com.android.annotations.Nullable;
40 
41 import java.util.ArrayList;
42 import java.util.List;
43 
44 public class ExpressionParser {
45     final ExprModel mModel;
46     final ExpressionVisitor visitor;
47 
ExpressionParser(ExprModel model)48     public ExpressionParser(ExprModel model) {
49         mModel = model;
50         visitor = new ExpressionVisitor(mModel);
51     }
52 
parse(String input, @Nullable Location locationInFile, BindingTarget target)53     public Expr parse(String input, @Nullable Location locationInFile, BindingTarget target) {
54         ANTLRInputStream inputStream = new ANTLRInputStream(input);
55         BindingExpressionLexer lexer = new BindingExpressionLexer(inputStream);
56         CommonTokenStream tokenStream = new CommonTokenStream(lexer);
57         final BindingExpressionParser parser = new BindingExpressionParser(tokenStream);
58         visitor.setBindingTarget(target);
59         parser.addErrorListener(new BaseErrorListener() {
60             @Override
61             public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line,
62                     int charPositionInLine, String msg, RecognitionException e) {
63                 L.e(ErrorMessages.SYNTAX_ERROR, msg);
64             }
65         });
66         BindingExpressionParser.BindingSyntaxContext root = parser.bindingSyntax();
67         try {
68             mModel.setCurrentLocationInFile(locationInFile);
69             visitor.setParseTreeListener(new ParseTreeListener() {
70                 List<ParserRuleContext> mStack = new ArrayList<ParserRuleContext>();
71                 @Override
72                 public void visitTerminal(TerminalNode node) {
73                 }
74 
75                 @Override
76                 public void visitErrorNode(ErrorNode node) {
77                 }
78 
79                 @Override
80                 public void enterEveryRule(ParserRuleContext ctx) {
81                     mStack.add(ctx);
82                     mModel.setCurrentParserContext(ctx);
83                 }
84 
85                 @Override
86                 public void exitEveryRule(ParserRuleContext ctx) {
87                     Preconditions.check(ctx == mStack.get(mStack.size() - 1),
88                             "Inconsistent exit from context. Received %s, expecting %s",
89                             ctx.toInfoString(parser),
90                             mStack.get(mStack.size() - 1).toInfoString(parser));
91                     mStack.remove(mStack.size() - 1);
92                     if (mStack.size() > 0) {
93                         mModel.setCurrentParserContext(mStack.get(mStack.size() - 1));
94                     } else {
95                         mModel.setCurrentParserContext(null);
96                     }
97                 }
98             });
99             return root.accept(visitor);
100         } finally {
101             mModel.setCurrentLocationInFile(null);
102         }
103     }
104 
getModel()105     public ExprModel getModel() {
106         return mModel;
107     }
108 }
109