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