antlr-ng
Version:
Next generation ANTLR Tool
161 lines (160 loc) • 6.08 kB
TypeScript
import { ATN, ATNState } from "antlr4ng";
import type { Constructor } from "../misc/Utils.js";
import { ActionAST } from "../tool/ast/ActionAST.js";
import { BlockAST } from "../tool/ast/BlockAST.js";
import { GrammarAST } from "../tool/ast/GrammarAST.js";
import { PredAST } from "../tool/ast/PredAST.js";
import { TerminalAST } from "../tool/ast/TerminalAST.js";
import { Rule } from "../tool/Rule.js";
import type { IGrammar, IParserATNFactory } from "../types.js";
import { IATNFactory, type IStatePair } from "./IATNFactory.js";
/**
* ATN construction routines triggered by ATNBuilder.g.
*
* No side-effects. It builds an {@link ATN} object and returns it.
*/
export declare class ParserATNFactory implements IParserATNFactory, IATNFactory {
currentRule?: Rule;
currentOuterAlt: number;
protected readonly g: IGrammar;
protected readonly atn: ATN;
private readonly preventEpsilonClosureBlocks;
private readonly preventEpsilonOptionalBlocks;
constructor(g: IGrammar);
/**
* `(BLOCK (ALT .))` or `(BLOCK (ALT 'a') (ALT .))`.
*/
private static blockHasWildcardAlt;
createATN(): ATN;
setCurrentRuleName(name: string): void;
/** From label `A` build graph `o-A->o`. */
tokenRef(node: TerminalAST): IStatePair | null;
/**
* From set build single edge graph `o->o-set->o`. To conform to what an alt block looks like, must have extra
* state on left. This also handles `~A`, converted to `~{A}` set.
*/
set(associatedAST: GrammarAST, terminals: GrammarAST[], invert: boolean): IStatePair;
/** Not valid for non-lexers. */
range(a: GrammarAST, b: GrammarAST): IStatePair | null;
/** For a non-lexer, just build a simple token reference atom. */
stringLiteral(stringLiteralAST: TerminalAST): IStatePair | null;
/** `[Aa]` char sets not allowed in parser */
charSetLiteral(charSetAST: GrammarAST): IStatePair | null;
/**
* For reference to rule `r`, build
*
* ```
* o->(r) o
* ```
*
* where `(r)` is the start of rule `r` and the trailing `o` is not linked to from rule ref state directly (uses
* {@see RuleTransition.followState}).
*/
ruleRef(node: GrammarAST): IStatePair | null;
/** From an empty alternative build `o-e->o`. */
epsilon(node: GrammarAST): IStatePair;
epsilon(a: ATNState | null, b: ATNState, prepend?: boolean): void;
/**
* Build what amounts to an epsilon transition with a semantic predicate action. The `pred` is a pointer
* into the AST of the {@link ANTLRParser#SEMPRED} token.
*/
sempred(pred: PredAST): IStatePair;
/**
* Build what amounts to an epsilon transition with an action.
* The action goes into ATN though it is ignored during prediction
* if {@see ActionTransition.actionIndex actionIndex} `< 0`.
*/
action(astOrString: ActionAST | string): IStatePair;
/**
* From `A|B|..|Z` alternative block build
*
* ```
* o->o-A->o->o (last ATNState is BlockEndState pointed to by all alts)
* | ^
* |->o-B->o--|
* | |
* ... |
* | |
* |->o-Z->o--|
* ```
*
* So start node points at every alternative with epsilon transition and
* every alt right side points at a block end ATNState.
*
* Special case: only one alternative: don't make a block with alt
* begin/end.
*
* Special case: if just a list of tokens/chars/sets, then collapse to a
* single edged o-set->o graph.
*
* TODO: Set alt number (1..n) in the states?
*/
block(blkAST: BlockAST, ebnfRoot: GrammarAST | null, alts: IStatePair[]): IStatePair | undefined;
alt(els: IStatePair[]): IStatePair;
/** Build an atom with all possible values in its label. */
wildcard(node: GrammarAST): IStatePair;
label(t: IStatePair): IStatePair;
listLabel(t: IStatePair): IStatePair;
lexerAltCommands(alt: IStatePair, commands: IStatePair): IStatePair;
lexerCallCommand(_id: GrammarAST, arg: GrammarAST): IStatePair;
lexerCommand(id: GrammarAST): IStatePair;
/** start-> rule - block -> end */
protected rule(ruleAST: GrammarAST, name: string, blk: IStatePair): IStatePair;
protected _ruleRef(node: GrammarAST): IStatePair | null;
protected newState<T extends ATNState>(nodeType: Constructor<T>): T;
protected checkEpsilonClosure(): void;
protected doCreateATN(rules: Rule[]): void;
private addFollowLink;
private elemList;
/**
* From `(A)?` build either:
*
* ```
* o--A->o
* | ^
* o---->|
* ```
*
* or, if `A` is a block, just add an empty alt to the end of the block.
*/
private optional;
/**
* From `(blk)+` build
*
* ```
* |---------|
* v |
* [o-blk-o]->o->o
* ```
*
* We add a decision for loop back node to the existing one at `blk` start.
*/
private plus;
/**
* From `(blk)*` build `( blk+ )?` with *two* decisions, one for entry and one for choosing alts of `blk`.
*
* ```
* |-------------|
* v |
* o--[o-blk-o]->o o
* | ^
* -----------------|
* ```
*
* Note that the optional bypass must jump outside the loop as `(A|B)*` is not the same thing as `(A|B|)+`.
*/
private star;
private addRuleFollowLinks;
/**
* Add an EOF transition to any rule end ATNState that points to nothing (i.e., for all those rules not invoked
* by another rule). These are start symbols then.
*
* Return the number of grammar entry points; i.e., how many rules are not invoked by another rule (they can
* only be invoked from outside). These are the start rules.
*/
private addEOFTransitionToStartRules;
private expectNonGreedy;
private makeBlock;
/** Define all the rule begin/end ATNStates to solve forward reference issues. */
private createRuleStartAndStopATNStates;
}