1 /*
2  *  Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License, version 2.0,
6  *  as published by the Free Software Foundation.
7  *
8  *  This program is also distributed with certain software (including
9  *  but not limited to OpenSSL) that is licensed under separate terms,
10  *  as designated in a particular file or component or in included license
11  *  documentation.  The authors of MySQL hereby grant you an additional
12  *  permission to link the program and your derivative works with the
13  *  separately licensed software that they have included with MySQL.
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License, version 2.0, for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
23  */
24 
25 package com.mysql.clusterj.jdbc.antlr;
26 
27 import org.antlr.runtime.CharStream;
28 import org.antlr.runtime.Lexer;
29 import org.antlr.runtime.NoViableAltException;
30 import org.antlr.runtime.RecognitionException;
31 import org.antlr.runtime.RecognizerSharedState;
32 
33 import java.util.List;
34 import java.util.logging.Level;
35 import java.util.logging.Logger;
36 
37 /**
38  * Abstract superclass for MySQL Lexers, for now containing some common code, so it's not in the grammar.
39  * Author: kroepke
40  */
41 public abstract class MySQLLexer extends Lexer implements RecognizerErrorDelegate {
42 
43     private static final Logger log = Logger.getLogger(MySQLLexer.class.getName());
44 
45     boolean nextTokenIsID = false;
46     private ErrorListener errorListener;
47 
48 
49     /**
50      * Check ahead in the input stream for a left paren to distinguish between built-in functions
51      * and identifiers.
52      * TODO: This is the place to support certain SQL modes.
53      * @param proposedType the original token type for this input.
54      * @return the new token type to emit a token with
55      */
checkFunctionAsID(int proposedType)56     public int checkFunctionAsID(int proposedType) {
57         return (input.LA(1) != '(') ? MySQL51Lexer.ID : proposedType;
58     }
59 
MySQLLexer()60     public MySQLLexer() {}
61 
MySQLLexer(CharStream input)62     public MySQLLexer(CharStream input) {
63         this(input, new RecognizerSharedState());
64         errorListener = new BaseErrorListener(this);
65     }
66 
MySQLLexer(CharStream input, RecognizerSharedState state)67     public MySQLLexer(CharStream input, RecognizerSharedState state) {
68         super(input, state);
69         errorListener = new BaseErrorListener(this);
70     }
71 
setErrorListener(ErrorListener listener)72     public void setErrorListener(ErrorListener listener) {
73         this.errorListener = listener;
74     }
75 
getErrorListener()76     public ErrorListener getErrorListener() {
77         return errorListener;
78     }
79 
80     /** Delegate error presentation to our errorListener if that's set, otherwise pass up the chain. */
displayRecognitionError(String[] tokenNames, RecognitionException e)81      public void displayRecognitionError(String[] tokenNames, RecognitionException e) {
82          errorListener.displayRecognitionError(tokenNames, e);
83      }
84 
getErrorHeader(RecognitionException e)85      public String getErrorHeader(RecognitionException e) {
86          return errorListener.getErrorHeader(e);
87      }
88 
emitErrorMessage(String msg)89      public void emitErrorMessage(String msg) {
90          errorListener.emitErrorMessage(msg);
91      }
92 
93      /* generate more useful error messages for debugging */
94      @SuppressWarnings("unchecked")
getErrorMessage(RecognitionException re, String[] tokenNames)95     public String getErrorMessage(RecognitionException re, String[] tokenNames) {
96         if (log.isLoggable(Level.FINEST)) {
97             List stack = getRuleInvocationStack(re, this.getClass().getName());
98             String msg;
99             if (re instanceof NoViableAltException) {
100                 NoViableAltException nvae = (NoViableAltException)re;
101                 msg = "  no viable alternative for token="+ re.token + "\n" +
102                         "  at decision="+nvae.decisionNumber + " state=" + nvae.stateNumber;
103                 if (nvae.grammarDecisionDescription != null && nvae.grammarDecisionDescription.length() > 0)
104                     msg = msg + "\n  decision grammar=<< "+ nvae.grammarDecisionDescription + " >>";
105             } else {
106                 msg = super.getErrorMessage(re, tokenNames);
107             }
108             return stack + "\n" + msg;
109         } else {
110             return errorListener.getErrorMessage(re, tokenNames);
111         }
112     }
113 
reportError(RecognitionException e)114      public void reportError(RecognitionException e) {
115          errorListener.reportError(e);
116      }
117 
118     /* trampoline methods to get to super implementation */
originalDisplayError(String[] tokenNames, RecognitionException e)119     public void originalDisplayError(String[] tokenNames, RecognitionException e) {
120         super.displayRecognitionError(tokenNames, e);
121     }
122 
originalReportError(RecognitionException e)123     public void originalReportError(RecognitionException e) {
124         super.reportError(e);
125     }
126 
originalGetErrorHeader(RecognitionException e)127     public String originalGetErrorHeader(RecognitionException e) {
128         return super.getErrorHeader(e);
129     }
130 
originalGetErrorMessage(RecognitionException e, String[] tokenNames)131     public String originalGetErrorMessage(RecognitionException e, String[] tokenNames) {
132         return super.getErrorMessage(e, tokenNames);
133     }
134 
originalEmitErrorMessage(String msg)135     public void originalEmitErrorMessage(String msg) {
136         //super.emitErrorMessage(msg);
137         log.warning(msg);
138     }
139 
140 }
141