import { Production, NonTerminal, Symbol, Terminal } from "../../Definition";
import { ItemSet, State, Item, AugmentedGrammar, AutomataTools } from "../Definition";
import { IFunction } from "@light0x00/shim";
export declare type FirstSetGetter = IFunction<Symbol, Set<Terminal>>;
export declare class LRAutomataTools implements AutomataTools {
    getFirstSet: FirstSetGetter;
    constructor(firstSetCalculator: FirstSetGetter);
    GOTO(I: ItemSet, inputSymbol: Symbol): ItemSet;
    closure(itemSet: ItemSet): ItemSet;
    /**
    ========展开符包含左递归产生式的处理========

    文法:
    S->A
    A->A𝜶 | A𝜷 | 𝝲

    状态:
    S->·A ,$
    A->·A𝜶,$
    A->·A𝜷,$
    A->·𝝲, ?

    如何求「 A->𝝲 」的展望集?

    若𝜶,𝜷不能推出𝝴,则 lookSet(A->·𝝲) = {𝜶,𝜷}
    否则 lookSet(A->·𝝲) ={𝜶,𝜷,$}

    形式化:
    加入在A中的每一个左递归产生式中的「第一非A的符号的First集」,记为First(!A), 如果该集内存在𝝴,则一路向后直到末尾,如果仍存在𝝴,则加入 Look(A)

    伪代码:
    for each lr-prod in A
        for each sym in lr-prod
            if sym != A
                add First(sym)
                if 𝝴 ∉ First(sym)
                    break
                else if sym is rightmost
                    add lookSet(S)

    注: Look(S) 表示S的lookeheadSet
    * @param curItem
    */
    determineLeftRecursionLookSet(curItem: Item): Set<Terminal>;
    /**
    ========展开符不包含左递归产生式的处理========

    约定
    - 将闭包项记为 closureItem ,例如S->·As
    - 将展开项计为 expandItem , 例如由展开符A得到的项 A->·a

    形式化计算规则如下:
    展开符位于item末端,形如A->·B
        lookSet(expandItem)=lookSet(prevItem)
    next非末端,形如A->·B𝜶𝜷
        lookSet(expandItem)=First(𝜶) ,
            如果𝜶可推出𝝴,则继续向后寻找𝜷,重复这个过程,
            如果𝜷为最末尾符号,且𝜷仍可推出𝝴,那么将lookSet(prevItem)放入lookSet(next)
    * @param prevItem
    */
    determineNonLeftRecursionLookSet(prevItem: Item): Set<Terminal>;
    getLeftRecursiveProds(non_terminal: NonTerminal): Production[];
    getStartState(grammar: AugmentedGrammar): State;
}
export declare function getStateSet_LR(grammar: AugmentedGrammar, getFirstSet: FirstSetGetter): import("../Definition").StateSet;
