ParserBailErrorStrategy.java

// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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.apache.doris.nereids.parser;

import org.antlr.v4.runtime.InputMismatchException;
import org.antlr.v4.runtime.Parser;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.misc.ParseCancellationException;

/**
 * Inspired by {@link org.antlr.v4.runtime.BailErrorStrategy}, which is used in two-stage parsing:
 * This error strategy allows the first stage of two-stage parsing to immediately terminate if an
 * error is encountered, and immediately fall back to the second stage. In addition to avoiding
 * wasted work by attempting to recover from errors here, the empty implementation of sync
 * improves the performance of the first stage.
 */
public class ParserBailErrorStrategy extends ParseErrorStrategy {
    /**
     * Instead of recovering from exception e, re-throw it wrapped in a
     * {@link ParseCancellationException} so it is not caught by the rule function catches. Use
     * {@link Exception#getCause} to get the original {@link RecognitionException}.
     */
    @Override
    public void recover(Parser recognizer, RecognitionException e) {
        ParserRuleContext context = recognizer.getContext();
        while (context != null) {
            context.exception = e;
            context = context.getParent();
        }
        throw new ParseCancellationException();
    }

    /**
     * Make sure we don't attempt to recover inline; if the parser successfully recovers, it won't
     * throw an exception.
     */
    @Override
    public Token recoverInline(Parser recognizer) throws RecognitionException {
        InputMismatchException e = new InputMismatchException(recognizer);
        ParserRuleContext context = recognizer.getContext();
        while (context != null) {
            context.exception = e;
            context = context.getParent();
        }
        throw new ParseCancellationException(e);
    }

    /** Make sure we don't attempt to recover from problems in subrules. */
    @Override
    public void sync(Parser recognizer) throws RecognitionException {

    }
}