presto-parser/src/main/java/io/prestosql/sql/parser/ErrorHandler.java/Analyzer/process
class Analyzer:        public Result process(ATNState currentState, int tokenIndex, RuleContext context)
        {
            RuleStartState startState = atn.ruleToStartState[currentState.ruleIndex];

            if (isReachable(currentState, startState)) {
                // We've been dropped inside a rule in a state that's reachable via epsilon transitions. This is,
                // effectively, equivalent to starting at the beginning (or immediately outside) the rule.
                // In that case, backtrack to the beginning to be able to take advantage of logic that remaps
                // some rules to well-known names for reporting purposes
                currentState = startState;
            }

            Set<Integer> endTokens = process(new ParsingState(currentState, tokenIndex, false, parser), 0);
            Set<Integer> nextTokens = new HashSet<>();
            while (!endTokens.isEmpty() && context.invokingState != -1) {
                for (int endToken : endTokens) {
                    ATNState nextState = ((RuleTransition) atn.states.get(context.invokingState).transition(0)).followState;
                    nextTokens.addAll(process(new ParsingState(nextState, endToken, false, parser), 0));
                }
                context = context.parent;
                endTokens = nextTokens;
            }

            return new Result(furthestTokenIndex, candidates);
        }