import { ATN, ATNState } from "antlr4ng";
import type { Grammar } from "../tool/Grammar.js";
import type { Rule } from "../tool/Rule.js";
export declare class LeftRecursionDetector {
    /** Holds a list of cycles (sets of rule names). */
    listOfRecursiveCycles: Rule[][];
    /** Which rule start states have we visited while looking for a single left-recursion check? */
    private rulesVisitedPerRuleCheck;
    private g;
    private atn;
    constructor(g: Grammar, atn: ATN);
    check(): void;
    /**
     * From state s, look for any transition to a rule that is currently
     *  being traced.  When tracing r, visitedPerRuleCheck has r
     *  initially.  If you reach a rule stop state, return but notify the
     *  invoking rule that the called rule is nullable. This implies that
     *  invoking rule must look at follow transition for that invoking state.
     *
     *  The visitedStates tracks visited states within a single rule so
     *  we can avoid epsilon-loop-induced infinite recursion here.  Keep
     *  filling the cycles in listOfRecursiveCycles and also, as a
     *  side-effect, set leftRecursiveRules.
     */
    check(enclosingRule: Rule, s: ATNState, visitedStates: Set<ATNState>): boolean;
    /**
     * enclosingRule calls targetRule. Find the cycle containing the target and add the caller. Find the cycle
     * containing the caller and add the target.  If no cycles contain either, then create a new cycle.
     */
    protected addRulesToCycle(enclosingRule: Rule, targetRule: Rule): void;
    private leftRecursionCycles;
}
