/* * Copyright 2016, Red Hat Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.infinispan.objectfilter.impl.ql.parse; import java.util.ArrayDeque; import java.util.Deque; import java.util.LinkedList; import java.util.List; import org.antlr.runtime.EarlyExitException; import org.antlr.runtime.FailedPredicateException; import org.antlr.runtime.MismatchedNotSetException; import org.antlr.runtime.MismatchedSetException; import org.antlr.runtime.MismatchedTokenException; import org.antlr.runtime.MismatchedTreeNodeException; import org.antlr.runtime.NoViableAltException; import org.antlr.runtime.Parser; import org.antlr.runtime.RecognitionException; import org.antlr.runtime.RecognizerSharedState; import org.antlr.runtime.Token; import org.antlr.runtime.TokenStream; /** * Base class for the generated parser. This class is stateful, so it should not be reused for parsing multiple * statements. * * @author anistor@redhat.com * @since 9.0 */ abstract class ParserBase extends Parser { private final Deque<Boolean> enableParameterUsage = new ArrayDeque<>(); private final List<String> errorMessages = new LinkedList<>(); private int unaliasedCount = 0; protected ParserBase(TokenStream input, RecognizerSharedState state) { super(input, state); } protected final String buildUniqueImplicitAlias() { return "<gen:" + unaliasedCount++ + ">"; } protected final boolean isParameterUsageEnabled() { return !enableParameterUsage.isEmpty() && enableParameterUsage.peek(); } protected final void pushEnableParameterUsage(boolean enable) { enableParameterUsage.push(enable); } protected final void popEnableParameterUsage() { enableParameterUsage.pop(); } protected final boolean validateSoftKeyword(String text) { return validateSoftKeyword(1, text); } protected final boolean validateSoftKeyword(int offset, String text) { if (input == null) { return false; } Token token = input.LT(offset); return token != null && text.equalsIgnoreCase(token.getText()); } public final boolean hasErrors() { return !errorMessages.isEmpty(); } public final List<String> getErrorMessages() { return errorMessages; } public final void reportError(RecognitionException e) { errorMessages.add(generateError(getRuleInvocationStack(e, getClass().getName()), getTokenNames(), e)); super.reportError(e); } private String generateError(List invocationStack, String[] tokenNames, RecognitionException e) { String localization = invocationStack + ": line " + e.line + ":" + e.charPositionInLine + " "; return generateError(localization, tokenNames, e); } private String generateError(String localization, String[] tokenNames, RecognitionException e) { String message = ""; if (e instanceof MismatchedTokenException) { MismatchedTokenException mte = (MismatchedTokenException) e; String tokenName = "<unknown>"; if (mte.expecting == Token.EOF) { tokenName = "EOF"; } else { if (tokenNames != null) { tokenName = tokenNames[mte.expecting]; } } message = localization + "mismatched token: " + e.token + "; expecting type " + tokenName; } else if (e instanceof MismatchedTreeNodeException) { MismatchedTreeNodeException mtne = (MismatchedTreeNodeException) e; String tokenName = "<unknown>"; if (mtne.expecting == Token.EOF) { tokenName = "EOF"; } else { if (tokenNames != null) { tokenName = tokenNames[mtne.expecting]; } } message = localization + "mismatched tree node: " + mtne.node + "; expecting type " + tokenName; } else if (e instanceof NoViableAltException) { NoViableAltException nvae = (NoViableAltException) e; message = localization + "state " + nvae.stateNumber + " (decision=" + nvae.decisionNumber + ") no viable alt; token=" + e.token; } else if (e instanceof EarlyExitException) { EarlyExitException eee = (EarlyExitException) e; message = localization + "required (...)+ loop (decision=" + eee.decisionNumber + ") did not match anything; token=" + e.token; } else if (e instanceof MismatchedNotSetException) { MismatchedNotSetException mse = (MismatchedNotSetException) e; message = localization + "mismatched token: " + e.token + "; expecting set " + mse.expecting; } else if (e instanceof MismatchedSetException) { MismatchedSetException mse = (MismatchedSetException) e; message = localization + "mismatched token: " + e.token + "; expecting set " + mse.expecting; } else if (e instanceof FailedPredicateException) { FailedPredicateException fpe = (FailedPredicateException) e; message = localization + "rule " + fpe.ruleName + " failed predicate: {" + fpe.predicateText + "}?"; } return message; } }