This commit is contained in:
nik
2025-10-03 22:27:28 +03:00
parent 829fad0e17
commit 871cf7e792
16520 changed files with 2967597 additions and 3 deletions

16
node_modules/chevrotain-allstar/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,16 @@
Copyright 2022 TypeFox GmbH
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

22
node_modules/chevrotain-allstar/README.md generated vendored Normal file
View File

@@ -0,0 +1,22 @@
# Chevrotain Allstar
This is a lookahead plugin package for the [Chevrotain parser library](https://chevrotain.io/).
It implements the [ALL(*) lookahead algorithm](https://www.antlr.org/papers/allstar-techreport.pdf) introduced for ANTLR4.
The algorithm features unbounded lookahead, compared to the normal LL(*k*) behavior of Chevrotain.
## Usage
When creating your parser, pass an instance of the `LLStarLookaheadStrategy` to the `lookaheadStrategy` property of the base parser constructor options.
```ts
import { LLStarLookaheadStrategy } from "chevrotain-allstar";
class Parser extends EmbeddedActionsParser {
constructor() {
super(tokens, {
lookaheadStrategy: new LLStarLookaheadStrategy()
});
this.performSelfAnalysis()
}
}
```

View File

@@ -0,0 +1,36 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { Rule, BaseParser, LLkLookaheadStrategy, ILookaheadValidationError, IOrAlt, OptionalProductionType } from "chevrotain";
export type AmbiguityReport = (message: string) => void;
export interface LLStarLookaheadOptions {
logging?: AmbiguityReport;
}
export declare class LLStarLookaheadStrategy extends LLkLookaheadStrategy {
private atn;
private dfas;
private logging;
constructor(options?: LLStarLookaheadOptions);
initialize(options: {
rules: Rule[];
}): void;
validateAmbiguousAlternationAlternatives(): ILookaheadValidationError[];
validateEmptyOrAlternatives(): ILookaheadValidationError[];
buildLookaheadForAlternation(options: {
prodOccurrence: number;
rule: Rule;
maxLookahead: number;
hasPredicates: boolean;
dynamicTokensEnabled: boolean;
}): (this: BaseParser, orAlts?: IOrAlt<any>[] | undefined) => number | undefined;
buildLookaheadForOptional(options: {
prodOccurrence: number;
prodType: OptionalProductionType;
rule: Rule;
maxLookahead: number;
dynamicTokensEnabled: boolean;
}): (this: BaseParser) => boolean;
}
//# sourceMappingURL=all-star-lookahead.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"all-star-lookahead.d.ts","sourceRoot":"","sources":["../src/all-star-lookahead.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,EAKH,IAAI,EAUJ,UAAU,EACV,oBAAoB,EACpB,yBAAyB,EACzB,MAAM,EAEN,sBAAsB,EACzB,MAAM,YAAY,CAAC;AAgCpB,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;AAkDxD,MAAM,WAAW,sBAAsB;IACnC,OAAO,CAAC,EAAE,eAAe,CAAA;CAC5B;AAED,qBAAa,uBAAwB,SAAQ,oBAAoB;IAE7D,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,OAAO,CAAkB;gBAErB,OAAO,CAAC,EAAE,sBAAsB;IAKnC,UAAU,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,IAAI,EAAE,CAAA;KAAE,GAAG,IAAI;IAK5C,wCAAwC,IAAI,yBAAyB,EAAE;IAIvE,2BAA2B,IAAI,yBAAyB,EAAE;IAI1D,4BAA4B,CAAC,OAAO,EAAE;QAC3C,cAAc,EAAE,MAAM,CAAC;QACvB,IAAI,EAAE,IAAI,CAAC;QACX,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,OAAO,CAAC;QACvB,oBAAoB,EAAE,OAAO,CAAA;KAChC,GAAG,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,GAAG,SAAS,KAAK,MAAM,GAAG,SAAS;IAuEvE,yBAAyB,CAAC,OAAO,EAAE;QACxC,cAAc,EAAE,MAAM,CAAC;QACvB,QAAQ,EAAE,sBAAsB,CAAC;QACjC,IAAI,EAAE,IAAI,CAAC;QACX,YAAY,EAAE,MAAM,CAAC;QACrB,oBAAoB,EAAE,OAAO,CAAA;KAChC,GAAG,CAAC,IAAI,EAAE,UAAU,KAAK,OAAO;CA4DpC"}

View File

@@ -0,0 +1,556 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { tokenMatcher, tokenLabel, NonTerminal, Alternation, Option, RepetitionMandatory, RepetitionMandatoryWithSeparator, RepetitionWithSeparator, Repetition, Terminal, LLkLookaheadStrategy, getLookaheadPaths } from "chevrotain";
import { ATN_RULE_STOP, AtomTransition, buildATNKey, createATN, EpsilonTransition, RuleTransition } from "./atn.js";
import { ATNConfigSet, DFA_ERROR, getATNConfigKey } from "./dfa.js";
import min from "lodash-es/min.js";
import flatMap from "lodash-es/flatMap.js";
import uniqBy from "lodash-es/uniqBy.js";
import map from "lodash-es/map.js";
import flatten from "lodash-es/flatten.js";
import forEach from "lodash-es/forEach.js";
import isEmpty from "lodash-es/isEmpty.js";
import reduce from "lodash-es/reduce.js";
function createDFACache(startState, decision) {
const map = {};
return (predicateSet) => {
const key = predicateSet.toString();
let existing = map[key];
if (existing !== undefined) {
return existing;
}
else {
existing = {
atnStartState: startState,
decision,
states: {}
};
map[key] = existing;
return existing;
}
};
}
class PredicateSet {
constructor() {
this.predicates = [];
}
is(index) {
return index >= this.predicates.length || this.predicates[index];
}
set(index, value) {
this.predicates[index] = value;
}
toString() {
let value = "";
const size = this.predicates.length;
for (let i = 0; i < size; i++) {
value += this.predicates[i] === true ? "1" : "0";
}
return value;
}
}
const EMPTY_PREDICATES = new PredicateSet();
export class LLStarLookaheadStrategy extends LLkLookaheadStrategy {
constructor(options) {
var _a;
super();
this.logging = (_a = options === null || options === void 0 ? void 0 : options.logging) !== null && _a !== void 0 ? _a : ((message) => console.log(message));
}
initialize(options) {
this.atn = createATN(options.rules);
this.dfas = initATNSimulator(this.atn);
}
validateAmbiguousAlternationAlternatives() {
return [];
}
validateEmptyOrAlternatives() {
return [];
}
buildLookaheadForAlternation(options) {
const { prodOccurrence, rule, hasPredicates, dynamicTokensEnabled } = options;
const dfas = this.dfas;
const logging = this.logging;
const key = buildATNKey(rule, 'Alternation', prodOccurrence);
const decisionState = this.atn.decisionMap[key];
const decisionIndex = decisionState.decision;
const partialAlts = map(getLookaheadPaths({
maxLookahead: 1,
occurrence: prodOccurrence,
prodType: "Alternation",
rule: rule
}), (currAlt) => map(currAlt, (path) => path[0]));
if (isLL1Sequence(partialAlts, false) && !dynamicTokensEnabled) {
const choiceToAlt = reduce(partialAlts, (result, currAlt, idx) => {
forEach(currAlt, (currTokType) => {
if (currTokType) {
result[currTokType.tokenTypeIdx] = idx;
forEach(currTokType.categoryMatches, (currExtendingType) => {
result[currExtendingType] = idx;
});
}
});
return result;
}, {});
if (hasPredicates) {
return function (orAlts) {
var _a;
const nextToken = this.LA(1);
const prediction = choiceToAlt[nextToken.tokenTypeIdx];
if (orAlts !== undefined && prediction !== undefined) {
const gate = (_a = orAlts[prediction]) === null || _a === void 0 ? void 0 : _a.GATE;
if (gate !== undefined && gate.call(this) === false) {
return undefined;
}
}
return prediction;
};
}
else {
return function () {
const nextToken = this.LA(1);
return choiceToAlt[nextToken.tokenTypeIdx];
};
}
}
else if (hasPredicates) {
return function (orAlts) {
const predicates = new PredicateSet();
const length = orAlts === undefined ? 0 : orAlts.length;
for (let i = 0; i < length; i++) {
const gate = orAlts === null || orAlts === void 0 ? void 0 : orAlts[i].GATE;
predicates.set(i, gate === undefined || gate.call(this));
}
const result = adaptivePredict.call(this, dfas, decisionIndex, predicates, logging);
return typeof result === 'number' ? result : undefined;
};
}
else {
return function () {
const result = adaptivePredict.call(this, dfas, decisionIndex, EMPTY_PREDICATES, logging);
return typeof result === 'number' ? result : undefined;
};
}
}
buildLookaheadForOptional(options) {
const { prodOccurrence, rule, prodType, dynamicTokensEnabled } = options;
const dfas = this.dfas;
const logging = this.logging;
const key = buildATNKey(rule, prodType, prodOccurrence);
const decisionState = this.atn.decisionMap[key];
const decisionIndex = decisionState.decision;
const alts = map(getLookaheadPaths({
maxLookahead: 1,
occurrence: prodOccurrence,
prodType,
rule
}), (e) => {
return map(e, (g) => g[0]);
});
if (isLL1Sequence(alts) && alts[0][0] && !dynamicTokensEnabled) {
const alt = alts[0];
const singleTokensTypes = flatten(alt);
if (singleTokensTypes.length === 1 &&
isEmpty(singleTokensTypes[0].categoryMatches)) {
const expectedTokenType = singleTokensTypes[0];
const expectedTokenUniqueKey = expectedTokenType.tokenTypeIdx;
return function () {
return this.LA(1).tokenTypeIdx === expectedTokenUniqueKey;
};
}
else {
const choiceToAlt = reduce(singleTokensTypes, (result, currTokType) => {
if (currTokType !== undefined) {
result[currTokType.tokenTypeIdx] = true;
forEach(currTokType.categoryMatches, (currExtendingType) => {
result[currExtendingType] = true;
});
}
return result;
}, {});
return function () {
const nextToken = this.LA(1);
return choiceToAlt[nextToken.tokenTypeIdx] === true;
};
}
}
return function () {
const result = adaptivePredict.call(this, dfas, decisionIndex, EMPTY_PREDICATES, logging);
return typeof result === "object" ? false : result === 0;
};
}
}
function isLL1Sequence(sequences, allowEmpty = true) {
const fullSet = new Set();
for (const alt of sequences) {
const altSet = new Set();
for (const tokType of alt) {
if (tokType === undefined) {
if (allowEmpty) {
// Epsilon production encountered
break;
}
else {
return false;
}
}
const indices = [tokType.tokenTypeIdx].concat(tokType.categoryMatches);
for (const index of indices) {
if (fullSet.has(index)) {
if (!altSet.has(index)) {
return false;
}
}
else {
fullSet.add(index);
altSet.add(index);
}
}
}
}
return true;
}
function initATNSimulator(atn) {
const decisionLength = atn.decisionStates.length;
const decisionToDFA = Array(decisionLength);
for (let i = 0; i < decisionLength; i++) {
decisionToDFA[i] = createDFACache(atn.decisionStates[i], i);
}
return decisionToDFA;
}
function adaptivePredict(dfaCaches, decision, predicateSet, logging) {
const dfa = dfaCaches[decision](predicateSet);
let start = dfa.start;
if (start === undefined) {
const closure = computeStartState(dfa.atnStartState);
start = addDFAState(dfa, newDFAState(closure));
dfa.start = start;
}
const alt = performLookahead.apply(this, [dfa, start, predicateSet, logging]);
return alt;
}
function performLookahead(dfa, s0, predicateSet, logging) {
let previousD = s0;
let i = 1;
const path = [];
let t = this.LA(i++);
while (true) {
let d = getExistingTargetState(previousD, t);
if (d === undefined) {
d = computeLookaheadTarget.apply(this, [dfa, previousD, t, i, predicateSet, logging]);
}
if (d === DFA_ERROR) {
return buildAdaptivePredictError(path, previousD, t);
}
if (d.isAcceptState === true) {
return d.prediction;
}
previousD = d;
path.push(t);
t = this.LA(i++);
}
}
function computeLookaheadTarget(dfa, previousD, token, lookahead, predicateSet, logging) {
const reach = computeReachSet(previousD.configs, token, predicateSet);
if (reach.size === 0) {
addDFAEdge(dfa, previousD, token, DFA_ERROR);
return DFA_ERROR;
}
let newState = newDFAState(reach);
const predictedAlt = getUniqueAlt(reach, predicateSet);
if (predictedAlt !== undefined) {
newState.isAcceptState = true;
newState.prediction = predictedAlt;
newState.configs.uniqueAlt = predictedAlt;
}
else if (hasConflictTerminatingPrediction(reach)) {
const prediction = min(reach.alts);
newState.isAcceptState = true;
newState.prediction = prediction;
newState.configs.uniqueAlt = prediction;
reportLookaheadAmbiguity.apply(this, [dfa, lookahead, reach.alts, logging]);
}
newState = addDFAEdge(dfa, previousD, token, newState);
return newState;
}
function reportLookaheadAmbiguity(dfa, lookahead, ambiguityIndices, logging) {
const prefixPath = [];
for (let i = 1; i <= lookahead; i++) {
prefixPath.push(this.LA(i).tokenType);
}
const atnState = dfa.atnStartState;
const topLevelRule = atnState.rule;
const production = atnState.production;
const message = buildAmbiguityError({
topLevelRule,
ambiguityIndices,
production,
prefixPath
});
logging(message);
}
function buildAmbiguityError(options) {
const pathMsg = map(options.prefixPath, (currtok) => tokenLabel(currtok)).join(", ");
const occurrence = options.production.idx === 0 ? "" : options.production.idx;
let currMessage = `Ambiguous Alternatives Detected: <${options.ambiguityIndices.join(", ")}> in <${getProductionDslName(options.production)}${occurrence}>` +
` inside <${options.topLevelRule.name}> Rule,\n` +
`<${pathMsg}> may appears as a prefix path in all these alternatives.\n`;
currMessage =
currMessage +
`See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#AMBIGUOUS_ALTERNATIVES\n` +
`For Further details.`;
return currMessage;
}
function getProductionDslName(prod) {
if (prod instanceof NonTerminal) {
return "SUBRULE";
}
else if (prod instanceof Option) {
return "OPTION";
}
else if (prod instanceof Alternation) {
return "OR";
}
else if (prod instanceof RepetitionMandatory) {
return "AT_LEAST_ONE";
}
else if (prod instanceof RepetitionMandatoryWithSeparator) {
return "AT_LEAST_ONE_SEP";
}
else if (prod instanceof RepetitionWithSeparator) {
return "MANY_SEP";
}
else if (prod instanceof Repetition) {
return "MANY";
}
else if (prod instanceof Terminal) {
return "CONSUME";
}
else {
throw Error("non exhaustive match");
}
}
function buildAdaptivePredictError(path, previous, current) {
const nextTransitions = flatMap(previous.configs.elements, (e) => e.state.transitions);
const nextTokenTypes = uniqBy(nextTransitions
.filter((e) => e instanceof AtomTransition)
.map((e) => e.tokenType), (e) => e.tokenTypeIdx);
return {
actualToken: current,
possibleTokenTypes: nextTokenTypes,
tokenPath: path
};
}
function getExistingTargetState(state, token) {
return state.edges[token.tokenTypeIdx];
}
function computeReachSet(configs, token, predicateSet) {
const intermediate = new ATNConfigSet();
const skippedStopStates = [];
for (const c of configs.elements) {
if (predicateSet.is(c.alt) === false) {
continue;
}
if (c.state.type === ATN_RULE_STOP) {
skippedStopStates.push(c);
continue;
}
const transitionLength = c.state.transitions.length;
for (let i = 0; i < transitionLength; i++) {
const transition = c.state.transitions[i];
const target = getReachableTarget(transition, token);
if (target !== undefined) {
intermediate.add({
state: target,
alt: c.alt,
stack: c.stack
});
}
}
}
let reach;
if (skippedStopStates.length === 0 && intermediate.size === 1) {
reach = intermediate;
}
if (reach === undefined) {
reach = new ATNConfigSet();
for (const c of intermediate.elements) {
closure(c, reach);
}
}
if (skippedStopStates.length > 0 && !hasConfigInRuleStopState(reach)) {
for (const c of skippedStopStates) {
reach.add(c);
}
}
return reach;
}
function getReachableTarget(transition, token) {
if (transition instanceof AtomTransition &&
tokenMatcher(token, transition.tokenType)) {
return transition.target;
}
return undefined;
}
function getUniqueAlt(configs, predicateSet) {
let alt;
for (const c of configs.elements) {
if (predicateSet.is(c.alt) === true) {
if (alt === undefined) {
alt = c.alt;
}
else if (alt !== c.alt) {
return undefined;
}
}
}
return alt;
}
function newDFAState(closure) {
return {
configs: closure,
edges: {},
isAcceptState: false,
prediction: -1
};
}
function addDFAEdge(dfa, from, token, to) {
to = addDFAState(dfa, to);
from.edges[token.tokenTypeIdx] = to;
return to;
}
function addDFAState(dfa, state) {
if (state === DFA_ERROR) {
return state;
}
// Repetitions have the same config set
// Therefore, storing the key of the config in a map allows us to create a loop in our DFA
const mapKey = state.configs.key;
const existing = dfa.states[mapKey];
if (existing !== undefined) {
return existing;
}
state.configs.finalize();
dfa.states[mapKey] = state;
return state;
}
function computeStartState(atnState) {
const configs = new ATNConfigSet();
const numberOfTransitions = atnState.transitions.length;
for (let i = 0; i < numberOfTransitions; i++) {
const target = atnState.transitions[i].target;
const config = {
state: target,
alt: i,
stack: []
};
closure(config, configs);
}
return configs;
}
function closure(config, configs) {
const p = config.state;
if (p.type === ATN_RULE_STOP) {
if (config.stack.length > 0) {
const atnStack = [...config.stack];
const followState = atnStack.pop();
const followConfig = {
state: followState,
alt: config.alt,
stack: atnStack
};
closure(followConfig, configs);
}
else {
// Dipping into outer context, simply add the config
// This will stop computation once every config is at the rule stop state
configs.add(config);
}
return;
}
if (!p.epsilonOnlyTransitions) {
configs.add(config);
}
const transitionLength = p.transitions.length;
for (let i = 0; i < transitionLength; i++) {
const transition = p.transitions[i];
const c = getEpsilonTarget(config, transition);
if (c !== undefined) {
closure(c, configs);
}
}
}
function getEpsilonTarget(config, transition) {
if (transition instanceof EpsilonTransition) {
return {
state: transition.target,
alt: config.alt,
stack: config.stack
};
}
else if (transition instanceof RuleTransition) {
const stack = [...config.stack, transition.followState];
return {
state: transition.target,
alt: config.alt,
stack
};
}
return undefined;
}
function hasConfigInRuleStopState(configs) {
for (const c of configs.elements) {
if (c.state.type === ATN_RULE_STOP) {
return true;
}
}
return false;
}
function allConfigsInRuleStopStates(configs) {
for (const c of configs.elements) {
if (c.state.type !== ATN_RULE_STOP) {
return false;
}
}
return true;
}
function hasConflictTerminatingPrediction(configs) {
if (allConfigsInRuleStopStates(configs)) {
return true;
}
const altSets = getConflictingAltSets(configs.elements);
const heuristic = hasConflictingAltSet(altSets) && !hasStateAssociatedWithOneAlt(altSets);
return heuristic;
}
function getConflictingAltSets(configs) {
const configToAlts = new Map();
for (const c of configs) {
const key = getATNConfigKey(c, false);
let alts = configToAlts.get(key);
if (alts === undefined) {
alts = {};
configToAlts.set(key, alts);
}
alts[c.alt] = true;
}
return configToAlts;
}
function hasConflictingAltSet(altSets) {
for (const value of Array.from(altSets.values())) {
if (Object.keys(value).length > 1) {
return true;
}
}
return false;
}
function hasStateAssociatedWithOneAlt(altSets) {
for (const value of Array.from(altSets.values())) {
if (Object.keys(value).length === 1) {
return true;
}
}
return false;
}
//# sourceMappingURL=all-star-lookahead.js.map

File diff suppressed because one or more lines are too long

105
node_modules/chevrotain-allstar/lib/atn.d.ts generated vendored Normal file
View File

@@ -0,0 +1,105 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { IProductionWithOccurrence, TokenType, Rule, LookaheadProductionType } from "chevrotain";
export declare function buildATNKey(rule: Rule, type: LookaheadProductionType, occurrence: number): string;
export interface ATN {
decisionMap: Record<string, DecisionState>;
states: ATNState[];
decisionStates: DecisionState[];
ruleToStartState: Map<Rule, RuleStartState>;
ruleToStopState: Map<Rule, RuleStopState>;
}
export declare const ATN_INVALID_TYPE = 0;
export declare const ATN_BASIC = 1;
export declare const ATN_RULE_START = 2;
export declare const ATN_PLUS_BLOCK_START = 4;
export declare const ATN_STAR_BLOCK_START = 5;
export declare const ATN_TOKEN_START = 6;
export declare const ATN_RULE_STOP = 7;
export declare const ATN_BLOCK_END = 8;
export declare const ATN_STAR_LOOP_BACK = 9;
export declare const ATN_STAR_LOOP_ENTRY = 10;
export declare const ATN_PLUS_LOOP_BACK = 11;
export declare const ATN_LOOP_END = 12;
export type ATNState = BasicState | BasicBlockStartState | PlusBlockStartState | PlusLoopbackState | StarBlockStartState | StarLoopbackState | StarLoopEntryState | BlockEndState | RuleStartState | RuleStopState | LoopEndState;
export interface ATNBaseState {
atn: ATN;
production: IProductionWithOccurrence;
stateNumber: number;
rule: Rule;
epsilonOnlyTransitions: boolean;
transitions: Transition[];
nextTokenWithinRule: number[];
}
export interface BasicState extends ATNBaseState {
type: typeof ATN_BASIC;
}
export interface BlockStartState extends DecisionState {
end: BlockEndState;
}
export interface BasicBlockStartState extends BlockStartState {
type: typeof ATN_BASIC;
}
export interface PlusBlockStartState extends BlockStartState {
loopback: PlusLoopbackState;
type: typeof ATN_PLUS_BLOCK_START;
}
export interface PlusLoopbackState extends DecisionState {
type: typeof ATN_PLUS_LOOP_BACK;
}
export interface StarBlockStartState extends BlockStartState {
type: typeof ATN_STAR_BLOCK_START;
}
export interface StarLoopbackState extends ATNBaseState {
type: typeof ATN_STAR_LOOP_BACK;
}
export interface StarLoopEntryState extends DecisionState {
loopback: StarLoopbackState;
type: typeof ATN_STAR_LOOP_ENTRY;
}
export interface BlockEndState extends ATNBaseState {
start: BlockStartState;
type: typeof ATN_BLOCK_END;
}
export interface DecisionState extends ATNBaseState {
decision: number;
}
export interface LoopEndState extends ATNBaseState {
loopback: ATNState;
type: typeof ATN_LOOP_END;
}
export interface RuleStartState extends ATNBaseState {
stop: RuleStopState;
type: typeof ATN_RULE_START;
}
export interface RuleStopState extends ATNBaseState {
type: typeof ATN_RULE_STOP;
}
export interface Transition {
target: ATNState;
isEpsilon(): boolean;
}
export declare abstract class AbstractTransition implements Transition {
target: ATNState;
constructor(target: ATNState);
isEpsilon(): boolean;
}
export declare class AtomTransition extends AbstractTransition {
tokenType: TokenType;
constructor(target: ATNState, tokenType: TokenType);
}
export declare class EpsilonTransition extends AbstractTransition {
constructor(target: ATNState);
isEpsilon(): boolean;
}
export declare class RuleTransition extends AbstractTransition {
rule: Rule;
followState: ATNState;
constructor(ruleStart: RuleStartState, rule: Rule, followState: ATNState);
isEpsilon(): boolean;
}
export declare function createATN(rules: Rule[]): ATN;
//# sourceMappingURL=atn.d.ts.map

1
node_modules/chevrotain-allstar/lib/atn.d.ts.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"atn.d.ts","sourceRoot":"","sources":["../src/atn.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAIhF,OAAO,EAEH,yBAAyB,EACzB,SAAS,EAGT,IAAI,EAQJ,uBAAuB,EAC1B,MAAM,YAAY,CAAA;AAEnB,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,uBAAuB,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAEjG;AAED,MAAM,WAAW,GAAG;IAChB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;IAC1C,MAAM,EAAE,QAAQ,EAAE,CAAA;IAClB,cAAc,EAAE,aAAa,EAAE,CAAA;IAC/B,gBAAgB,EAAE,GAAG,CAAC,IAAI,EAAE,cAAc,CAAC,CAAA;IAC3C,eAAe,EAAE,GAAG,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;CAC5C;AAED,eAAO,MAAM,gBAAgB,IAAI,CAAA;AACjC,eAAO,MAAM,SAAS,IAAI,CAAA;AAC1B,eAAO,MAAM,cAAc,IAAI,CAAA;AAC/B,eAAO,MAAM,oBAAoB,IAAI,CAAA;AACrC,eAAO,MAAM,oBAAoB,IAAI,CAAA;AAErC,eAAO,MAAM,eAAe,IAAI,CAAA;AAChC,eAAO,MAAM,aAAa,IAAI,CAAA;AAC9B,eAAO,MAAM,aAAa,IAAI,CAAA;AAC9B,eAAO,MAAM,kBAAkB,IAAI,CAAA;AACnC,eAAO,MAAM,mBAAmB,KAAK,CAAA;AACrC,eAAO,MAAM,kBAAkB,KAAK,CAAA;AACpC,eAAO,MAAM,YAAY,KAAK,CAAA;AAE9B,MAAM,MAAM,QAAQ,GACd,UAAU,GACV,oBAAoB,GACpB,mBAAmB,GACnB,iBAAiB,GACjB,mBAAmB,GACnB,iBAAiB,GACjB,kBAAkB,GAClB,aAAa,GACb,cAAc,GACd,aAAa,GACb,YAAY,CAAA;AAElB,MAAM,WAAW,YAAY;IACzB,GAAG,EAAE,GAAG,CAAA;IACR,UAAU,EAAE,yBAAyB,CAAA;IACrC,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,IAAI,CAAA;IACV,sBAAsB,EAAE,OAAO,CAAA;IAC/B,WAAW,EAAE,UAAU,EAAE,CAAA;IACzB,mBAAmB,EAAE,MAAM,EAAE,CAAA;CAChC;AAED,MAAM,WAAW,UAAW,SAAQ,YAAY;IAC5C,IAAI,EAAE,OAAO,SAAS,CAAA;CACzB;AAED,MAAM,WAAW,eAAgB,SAAQ,aAAa;IAClD,GAAG,EAAE,aAAa,CAAA;CACrB;AAED,MAAM,WAAW,oBAAqB,SAAQ,eAAe;IACzD,IAAI,EAAE,OAAO,SAAS,CAAA;CACzB;AAED,MAAM,WAAW,mBAAoB,SAAQ,eAAe;IACxD,QAAQ,EAAE,iBAAiB,CAAA;IAC3B,IAAI,EAAE,OAAO,oBAAoB,CAAA;CACpC;AAED,MAAM,WAAW,iBAAkB,SAAQ,aAAa;IACpD,IAAI,EAAE,OAAO,kBAAkB,CAAA;CAClC;AAED,MAAM,WAAW,mBAAoB,SAAQ,eAAe;IACxD,IAAI,EAAE,OAAO,oBAAoB,CAAA;CACpC;AAED,MAAM,WAAW,iBAAkB,SAAQ,YAAY;IACnD,IAAI,EAAE,OAAO,kBAAkB,CAAA;CAClC;AAED,MAAM,WAAW,kBAAmB,SAAQ,aAAa;IACrD,QAAQ,EAAE,iBAAiB,CAAA;IAC3B,IAAI,EAAE,OAAO,mBAAmB,CAAA;CACnC;AAED,MAAM,WAAW,aAAc,SAAQ,YAAY;IAC/C,KAAK,EAAE,eAAe,CAAA;IACtB,IAAI,EAAE,OAAO,aAAa,CAAA;CAC7B;AAED,MAAM,WAAW,aAAc,SAAQ,YAAY;IAC/C,QAAQ,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,YAAa,SAAQ,YAAY;IAC9C,QAAQ,EAAE,QAAQ,CAAA;IAClB,IAAI,EAAE,OAAO,YAAY,CAAA;CAC5B;AAED,MAAM,WAAW,cAAe,SAAQ,YAAY;IAChD,IAAI,EAAE,aAAa,CAAA;IACnB,IAAI,EAAE,OAAO,cAAc,CAAA;CAC9B;AAED,MAAM,WAAW,aAAc,SAAQ,YAAY;IAC/C,IAAI,EAAE,OAAO,aAAa,CAAA;CAC7B;AAED,MAAM,WAAW,UAAU;IACvB,MAAM,EAAE,QAAQ,CAAA;IAChB,SAAS,IAAI,OAAO,CAAA;CACvB;AAED,8BAAsB,kBAAmB,YAAW,UAAU;IAC1D,MAAM,EAAE,QAAQ,CAAA;gBAEJ,MAAM,EAAE,QAAQ;IAI5B,SAAS;CAGZ;AAED,qBAAa,cAAe,SAAQ,kBAAkB;IAClD,SAAS,EAAE,SAAS,CAAA;gBAER,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS;CAIrD;AAED,qBAAa,iBAAkB,SAAQ,kBAAkB;gBACzC,MAAM,EAAE,QAAQ;IAI5B,SAAS;CAGZ;AAED,qBAAa,cAAe,SAAQ,kBAAkB;IAClD,IAAI,EAAE,IAAI,CAAA;IACV,WAAW,EAAE,QAAQ,CAAA;gBAET,SAAS,EAAE,cAAc,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ;IAMxE,SAAS;CAGZ;AAOD,wBAAgB,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,GAAG,CAmB5C"}

404
node_modules/chevrotain-allstar/lib/atn.js generated vendored Normal file
View File

@@ -0,0 +1,404 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import map from "lodash-es/map.js";
import filter from "lodash-es/filter.js";
import { Alternation, NonTerminal, Option, RepetitionMandatory, Repetition, Terminal, RepetitionWithSeparator, RepetitionMandatoryWithSeparator } from "chevrotain";
export function buildATNKey(rule, type, occurrence) {
return `${rule.name}_${type}_${occurrence}`;
}
export const ATN_INVALID_TYPE = 0;
export const ATN_BASIC = 1;
export const ATN_RULE_START = 2;
export const ATN_PLUS_BLOCK_START = 4;
export const ATN_STAR_BLOCK_START = 5;
// Currently unused as the ATN is not used for lexing
export const ATN_TOKEN_START = 6;
export const ATN_RULE_STOP = 7;
export const ATN_BLOCK_END = 8;
export const ATN_STAR_LOOP_BACK = 9;
export const ATN_STAR_LOOP_ENTRY = 10;
export const ATN_PLUS_LOOP_BACK = 11;
export const ATN_LOOP_END = 12;
export class AbstractTransition {
constructor(target) {
this.target = target;
}
isEpsilon() {
return false;
}
}
export class AtomTransition extends AbstractTransition {
constructor(target, tokenType) {
super(target);
this.tokenType = tokenType;
}
}
export class EpsilonTransition extends AbstractTransition {
constructor(target) {
super(target);
}
isEpsilon() {
return true;
}
}
export class RuleTransition extends AbstractTransition {
constructor(ruleStart, rule, followState) {
super(ruleStart);
this.rule = rule;
this.followState = followState;
}
isEpsilon() {
return true;
}
}
export function createATN(rules) {
const atn = {
decisionMap: {},
decisionStates: [],
ruleToStartState: new Map(),
ruleToStopState: new Map(),
states: []
};
createRuleStartAndStopATNStates(atn, rules);
const ruleLength = rules.length;
for (let i = 0; i < ruleLength; i++) {
const rule = rules[i];
const ruleBlock = block(atn, rule, rule);
if (ruleBlock === undefined) {
continue;
}
buildRuleHandle(atn, rule, ruleBlock);
}
return atn;
}
function createRuleStartAndStopATNStates(atn, rules) {
const ruleLength = rules.length;
for (let i = 0; i < ruleLength; i++) {
const rule = rules[i];
const start = newState(atn, rule, undefined, {
type: ATN_RULE_START
});
const stop = newState(atn, rule, undefined, {
type: ATN_RULE_STOP
});
start.stop = stop;
atn.ruleToStartState.set(rule, start);
atn.ruleToStopState.set(rule, stop);
}
}
function atom(atn, rule, production) {
if (production instanceof Terminal) {
return tokenRef(atn, rule, production.terminalType, production);
}
else if (production instanceof NonTerminal) {
return ruleRef(atn, rule, production);
}
else if (production instanceof Alternation) {
return alternation(atn, rule, production);
}
else if (production instanceof Option) {
return option(atn, rule, production);
}
else if (production instanceof Repetition) {
return repetition(atn, rule, production);
}
else if (production instanceof RepetitionWithSeparator) {
return repetitionSep(atn, rule, production);
}
else if (production instanceof RepetitionMandatory) {
return repetitionMandatory(atn, rule, production);
}
else if (production instanceof RepetitionMandatoryWithSeparator) {
return repetitionMandatorySep(atn, rule, production);
}
else {
return block(atn, rule, production);
}
}
function repetition(atn, rule, repetition) {
const starState = newState(atn, rule, repetition, {
type: ATN_STAR_BLOCK_START
});
defineDecisionState(atn, starState);
const handle = makeAlts(atn, rule, starState, repetition, block(atn, rule, repetition));
return star(atn, rule, repetition, handle);
}
function repetitionSep(atn, rule, repetition) {
const starState = newState(atn, rule, repetition, {
type: ATN_STAR_BLOCK_START
});
defineDecisionState(atn, starState);
const handle = makeAlts(atn, rule, starState, repetition, block(atn, rule, repetition));
const sep = tokenRef(atn, rule, repetition.separator, repetition);
return star(atn, rule, repetition, handle, sep);
}
function repetitionMandatory(atn, rule, repetition) {
const plusState = newState(atn, rule, repetition, {
type: ATN_PLUS_BLOCK_START
});
defineDecisionState(atn, plusState);
const handle = makeAlts(atn, rule, plusState, repetition, block(atn, rule, repetition));
return plus(atn, rule, repetition, handle);
}
function repetitionMandatorySep(atn, rule, repetition) {
const plusState = newState(atn, rule, repetition, {
type: ATN_PLUS_BLOCK_START
});
defineDecisionState(atn, plusState);
const handle = makeAlts(atn, rule, plusState, repetition, block(atn, rule, repetition));
const sep = tokenRef(atn, rule, repetition.separator, repetition);
return plus(atn, rule, repetition, handle, sep);
}
function alternation(atn, rule, alternation) {
const start = newState(atn, rule, alternation, {
type: ATN_BASIC
});
defineDecisionState(atn, start);
const alts = map(alternation.definition, (e) => atom(atn, rule, e));
const handle = makeAlts(atn, rule, start, alternation, ...alts);
return handle;
}
function option(atn, rule, option) {
const start = newState(atn, rule, option, {
type: ATN_BASIC
});
defineDecisionState(atn, start);
const handle = makeAlts(atn, rule, start, option, block(atn, rule, option));
return optional(atn, rule, option, handle);
}
function block(atn, rule, block) {
const handles = filter(map(block.definition, (e) => atom(atn, rule, e)), (e) => e !== undefined);
if (handles.length === 1) {
return handles[0];
}
else if (handles.length === 0) {
return undefined;
}
else {
return makeBlock(atn, handles);
}
}
function plus(atn, rule, plus, handle, sep) {
const blkStart = handle.left;
const blkEnd = handle.right;
const loop = newState(atn, rule, plus, {
type: ATN_PLUS_LOOP_BACK
});
defineDecisionState(atn, loop);
const end = newState(atn, rule, plus, {
type: ATN_LOOP_END
});
blkStart.loopback = loop;
end.loopback = loop;
atn.decisionMap[buildATNKey(rule, sep ? 'RepetitionMandatoryWithSeparator' : 'RepetitionMandatory', plus.idx)] = loop;
epsilon(blkEnd, loop); // block can see loop back
// Depending on whether we have a separator we put the exit transition at index 1 or 0
// This influences the chosen option in the lookahead DFA
if (sep === undefined) {
epsilon(loop, blkStart); // loop back to start
epsilon(loop, end); // exit
}
else {
epsilon(loop, end); // exit
// loop back to start with separator
epsilon(loop, sep.left);
epsilon(sep.right, blkStart);
}
return {
left: blkStart,
right: end
};
}
function star(atn, rule, star, handle, sep) {
const start = handle.left;
const end = handle.right;
const entry = newState(atn, rule, star, {
type: ATN_STAR_LOOP_ENTRY
});
defineDecisionState(atn, entry);
const loopEnd = newState(atn, rule, star, {
type: ATN_LOOP_END
});
const loop = newState(atn, rule, star, {
type: ATN_STAR_LOOP_BACK
});
entry.loopback = loop;
loopEnd.loopback = loop;
epsilon(entry, start); // loop enter edge (alt 2)
epsilon(entry, loopEnd); // bypass loop edge (alt 1)
epsilon(end, loop); // block end hits loop back
if (sep !== undefined) {
epsilon(loop, loopEnd); // end loop
// loop back to start of handle using separator
epsilon(loop, sep.left);
epsilon(sep.right, start);
}
else {
epsilon(loop, entry); // loop back to entry/exit decision
}
atn.decisionMap[buildATNKey(rule, sep ? 'RepetitionWithSeparator' : 'Repetition', star.idx)] = entry;
return {
left: entry,
right: loopEnd
};
}
function optional(atn, rule, optional, handle) {
const start = handle.left;
const end = handle.right;
epsilon(start, end);
atn.decisionMap[buildATNKey(rule, 'Option', optional.idx)] = start;
return handle;
}
function defineDecisionState(atn, state) {
atn.decisionStates.push(state);
state.decision = atn.decisionStates.length - 1;
return state.decision;
}
function makeAlts(atn, rule, start, production, ...alts) {
const end = newState(atn, rule, production, {
type: ATN_BLOCK_END,
start
});
start.end = end;
for (const alt of alts) {
if (alt !== undefined) {
// hook alts up to decision block
epsilon(start, alt.left);
epsilon(alt.right, end);
}
else {
epsilon(start, end);
}
}
const handle = {
left: start,
right: end
};
atn.decisionMap[buildATNKey(rule, getProdType(production), production.idx)] = start;
return handle;
}
function getProdType(production) {
if (production instanceof Alternation) {
return 'Alternation';
}
else if (production instanceof Option) {
return 'Option';
}
else if (production instanceof Repetition) {
return 'Repetition';
}
else if (production instanceof RepetitionWithSeparator) {
return 'RepetitionWithSeparator';
}
else if (production instanceof RepetitionMandatory) {
return 'RepetitionMandatory';
}
else if (production instanceof RepetitionMandatoryWithSeparator) {
return 'RepetitionMandatoryWithSeparator';
}
else {
throw new Error('Invalid production type encountered');
}
}
function makeBlock(atn, alts) {
const altsLength = alts.length;
for (let i = 0; i < altsLength - 1; i++) {
const handle = alts[i];
let transition;
if (handle.left.transitions.length === 1) {
transition = handle.left.transitions[0];
}
const isRuleTransition = transition instanceof RuleTransition;
const ruleTransition = transition;
const next = alts[i + 1].left;
if (handle.left.type === ATN_BASIC &&
handle.right.type === ATN_BASIC &&
transition !== undefined &&
((isRuleTransition && ruleTransition.followState === handle.right) ||
transition.target === handle.right)) {
// we can avoid epsilon edge to next element
if (isRuleTransition) {
ruleTransition.followState = next;
}
else {
transition.target = next;
}
removeState(atn, handle.right); // we skipped over this state
}
else {
// need epsilon if previous block's right end node is complex
epsilon(handle.right, next);
}
}
const first = alts[0];
const last = alts[altsLength - 1];
return {
left: first.left,
right: last.right
};
}
function tokenRef(atn, rule, tokenType, production) {
const left = newState(atn, rule, production, {
type: ATN_BASIC
});
const right = newState(atn, rule, production, {
type: ATN_BASIC
});
addTransition(left, new AtomTransition(right, tokenType));
return {
left,
right
};
}
function ruleRef(atn, currentRule, nonTerminal) {
const rule = nonTerminal.referencedRule;
const start = atn.ruleToStartState.get(rule);
const left = newState(atn, currentRule, nonTerminal, {
type: ATN_BASIC
});
const right = newState(atn, currentRule, nonTerminal, {
type: ATN_BASIC
});
const call = new RuleTransition(start, rule, right);
addTransition(left, call);
return {
left,
right
};
}
function buildRuleHandle(atn, rule, block) {
const start = atn.ruleToStartState.get(rule);
epsilon(start, block.left);
const stop = atn.ruleToStopState.get(rule);
epsilon(block.right, stop);
const handle = {
left: start,
right: stop
};
return handle;
}
function epsilon(a, b) {
const transition = new EpsilonTransition(b);
addTransition(a, transition);
}
function newState(atn, rule, production, partial) {
const t = Object.assign({ atn,
production, epsilonOnlyTransitions: false, rule, transitions: [], nextTokenWithinRule: [], stateNumber: atn.states.length }, partial);
atn.states.push(t);
return t;
}
function addTransition(state, transition) {
// A single ATN state can only contain epsilon transitions or non-epsilon transitions
// Because they are never mixed, only setting the property for the first transition is fine
if (state.transitions.length === 0) {
state.epsilonOnlyTransitions = transition.isEpsilon();
}
state.transitions.push(transition);
}
function removeState(atn, state) {
atn.states.splice(atn.states.indexOf(state), 1);
}
//# sourceMappingURL=atn.js.map

1
node_modules/chevrotain-allstar/lib/atn.js.map generated vendored Normal file

File diff suppressed because one or more lines are too long

37
node_modules/chevrotain-allstar/lib/dfa.d.ts generated vendored Normal file
View File

@@ -0,0 +1,37 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { ATNState, DecisionState } from "./atn.js";
export interface DFA {
start?: DFAState;
states: Record<string, DFAState>;
decision: number;
atnStartState: DecisionState;
}
export interface DFAState {
configs: ATNConfigSet;
edges: Record<number, DFAState>;
isAcceptState: boolean;
prediction: number;
}
export declare const DFA_ERROR: DFAState;
export interface ATNConfig {
state: ATNState;
alt: number;
stack: ATNState[];
}
export declare class ATNConfigSet {
private map;
private configs;
uniqueAlt: number | undefined;
get size(): number;
finalize(): void;
add(config: ATNConfig): void;
get elements(): readonly ATNConfig[];
get alts(): number[];
get key(): string;
}
export declare function getATNConfigKey(config: ATNConfig, alt?: boolean): string;
//# sourceMappingURL=dfa.d.ts.map

1
node_modules/chevrotain-allstar/lib/dfa.d.ts.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"dfa.d.ts","sourceRoot":"","sources":["../src/dfa.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAGhF,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAElD,MAAM,WAAW,GAAG;IAClB,KAAK,CAAC,EAAE,QAAQ,CAAA;IAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;IAChC,QAAQ,EAAE,MAAM,CAAA;IAChB,aAAa,EAAE,aAAa,CAAA;CAC7B;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,YAAY,CAAA;IACrB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;IAC/B,aAAa,EAAE,OAAO,CAAA;IACtB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,eAAO,MAAM,SAAS,UAAiB,CAAA;AAEvC,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,QAAQ,CAAA;IACf,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,QAAQ,EAAE,CAAA;CAClB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,GAAG,CAA6B;IACxC,OAAO,CAAC,OAAO,CAAkB;IAEjC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;IAE7B,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,QAAQ,IAAI,IAAI;IAKhB,GAAG,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IAU5B,IAAI,QAAQ,IAAI,SAAS,SAAS,EAAE,CAEnC;IAED,IAAI,IAAI,IAAI,MAAM,EAAE,CAEnB;IAED,IAAI,GAAG,IAAI,MAAM,CAMhB;CACF;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,UAAO,UAI5D"}

46
node_modules/chevrotain-allstar/lib/dfa.js generated vendored Normal file
View File

@@ -0,0 +1,46 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import map from "lodash-es/map.js";
export const DFA_ERROR = {};
export class ATNConfigSet {
constructor() {
this.map = {};
this.configs = [];
}
get size() {
return this.configs.length;
}
finalize() {
// Empties the map to free up memory
this.map = {};
}
add(config) {
const key = getATNConfigKey(config);
// Only add configs which don't exist in our map already
// While this does not influence the actual algorithm, adding them anyway would massively increase memory consumption
if (!(key in this.map)) {
this.map[key] = this.configs.length;
this.configs.push(config);
}
}
get elements() {
return this.configs;
}
get alts() {
return map(this.configs, (e) => e.alt);
}
get key() {
let value = "";
for (const k in this.map) {
value += k + ":";
}
return value;
}
}
export function getATNConfigKey(config, alt = true) {
return `${alt ? `a${config.alt}` : ""}s${config.state.stateNumber}:${config.stack.map((e) => e.stateNumber.toString()).join("_")}`;
}
//# sourceMappingURL=dfa.js.map

1
node_modules/chevrotain-allstar/lib/dfa.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"dfa.js","sourceRoot":"","sources":["../src/dfa.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,GAAG,MAAM,kBAAkB,CAAA;AAiBlC,MAAM,CAAC,MAAM,SAAS,GAAG,EAAc,CAAA;AAQvC,MAAM,OAAO,YAAY;IAAzB;QACU,QAAG,GAA2B,EAAE,CAAA;QAChC,YAAO,GAAgB,EAAE,CAAA;IAsCnC,CAAC;IAlCC,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAA;IAC5B,CAAC;IAED,QAAQ;QACN,oCAAoC;QACpC,IAAI,CAAC,GAAG,GAAG,EAAE,CAAA;IACf,CAAC;IAED,GAAG,CAAC,MAAiB;QACnB,MAAM,GAAG,GAAG,eAAe,CAAC,MAAM,CAAC,CAAA;QACnC,wDAAwD;QACxD,qHAAqH;QACrH,IAAI,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE;YACtB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAA;YACnC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;SAC1B;IACH,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,OAAO,CAAA;IACrB,CAAC;IAED,IAAI,IAAI;QACN,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;IACxC,CAAC;IAED,IAAI,GAAG;QACL,IAAI,KAAK,GAAG,EAAE,CAAA;QACd,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE;YACxB,KAAK,IAAI,CAAC,GAAG,GAAG,CAAA;SACjB;QACD,OAAO,KAAK,CAAA;IACd,CAAC;CACF;AAED,MAAM,UAAU,eAAe,CAAC,MAAiB,EAAE,GAAG,GAAG,IAAI;IAC3D,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,IACnC,MAAM,CAAC,KAAK,CAAC,WACf,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAA;AACnE,CAAC"}

7
node_modules/chevrotain-allstar/lib/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,7 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
export { AmbiguityReport, LLStarLookaheadOptions, LLStarLookaheadStrategy } from './all-star-lookahead.js';
//# sourceMappingURL=index.d.ts.map

1
node_modules/chevrotain-allstar/lib/index.d.ts.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,EACH,eAAe,EACf,sBAAsB,EACtB,uBAAuB,EAC1B,MAAM,yBAAyB,CAAC"}

7
node_modules/chevrotain-allstar/lib/index.js generated vendored Normal file
View File

@@ -0,0 +1,7 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
export { LLStarLookaheadStrategy } from './all-star-lookahead.js';
//# sourceMappingURL=index.js.map

1
node_modules/chevrotain-allstar/lib/index.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,EAGH,uBAAuB,EAC1B,MAAM,yBAAyB,CAAC"}

52
node_modules/chevrotain-allstar/package.json generated vendored Normal file
View File

@@ -0,0 +1,52 @@
{
"name": "chevrotain-allstar",
"version": "0.3.1",
"description": "LL(*) lookahead strategy for the Chevrotain parser library",
"keywords": [
"parser",
"lookahead",
"chevrotain",
"langium"
],
"license": "MIT",
"type": "module",
"types": "./lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"default": "./lib/index.js"
}
},
"scripts": {
"test": "vitest",
"build": "tsc",
"watch": "tsc -w",
"clean": "shx rm -rf lib tsconfig.tsbuildinfo"
},
"files": [
"src",
"lib"
],
"dependencies": {
"lodash-es": "^4.17.21"
},
"peerDependencies": {
"chevrotain": "^11.0.0"
},
"devDependencies": {
"@types/jest": "^29.2.1",
"@types/lodash-es": "^4.17.8",
"shx": "^0.3.4",
"typescript": "^5.1.6",
"vitest": "^0.33.0"
},
"repository": {
"type": "git",
"url": "https://github.com/langium/chevrotain-allstar"
},
"bugs": "https://github.com/langium/chevrotain-allstar/issues",
"author": {
"name": "TypeFox",
"url": "https://www.typefox.io"
}
}

View File

@@ -0,0 +1,763 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import {
IToken,
TokenType,
tokenMatcher,
tokenLabel,
Rule,
IProductionWithOccurrence,
NonTerminal,
Alternation,
Option,
RepetitionMandatory,
RepetitionMandatoryWithSeparator,
RepetitionWithSeparator,
Repetition,
Terminal,
BaseParser,
LLkLookaheadStrategy,
ILookaheadValidationError,
IOrAlt,
getLookaheadPaths,
OptionalProductionType
} from "chevrotain";
import {
ATN,
ATNState,
ATN_RULE_STOP,
AtomTransition,
buildATNKey,
createATN,
DecisionState,
EpsilonTransition,
RuleTransition,
Transition
} from "./atn.js";
import {
ATNConfig,
ATNConfigSet,
DFA,
DFAState,
DFA_ERROR,
getATNConfigKey
} from "./dfa.js";
import min from "lodash-es/min.js";
import flatMap from "lodash-es/flatMap.js";
import uniqBy from "lodash-es/uniqBy.js";
import map from "lodash-es/map.js";
import flatten from "lodash-es/flatten.js";
import forEach from "lodash-es/forEach.js";
import isEmpty from "lodash-es/isEmpty.js";
import reduce from "lodash-es/reduce.js";
type DFACache = (predicateSet: PredicateSet) => DFA
export type AmbiguityReport = (message: string) => void;
function createDFACache(startState: DecisionState, decision: number): DFACache {
const map: Record<string, DFA | undefined> = {}
return (predicateSet) => {
const key = predicateSet.toString()
let existing = map[key]
if (existing !== undefined) {
return existing
} else {
existing = {
atnStartState: startState,
decision,
states: {}
}
map[key] = existing
return existing
}
}
}
class PredicateSet {
private predicates: boolean[] = []
is(index: number): boolean {
return index >= this.predicates.length || this.predicates[index]
}
set(index: number, value: boolean) {
this.predicates[index] = value
}
toString(): string {
let value = ""
const size = this.predicates.length
for (let i = 0; i < size; i++) {
value += this.predicates[i] === true ? "1" : "0"
}
return value
}
}
interface AdaptivePredictError {
tokenPath: IToken[]
possibleTokenTypes: TokenType[]
actualToken: IToken
}
const EMPTY_PREDICATES = new PredicateSet()
export interface LLStarLookaheadOptions {
logging?: AmbiguityReport
}
export class LLStarLookaheadStrategy extends LLkLookaheadStrategy {
private atn: ATN;
private dfas: DFACache[];
private logging: AmbiguityReport;
constructor(options?: LLStarLookaheadOptions) {
super();
this.logging = options?.logging ?? ((message) => console.log(message));
}
override initialize(options: { rules: Rule[] }): void {
this.atn = createATN(options.rules);
this.dfas = initATNSimulator(this.atn);
}
override validateAmbiguousAlternationAlternatives(): ILookaheadValidationError[] {
return [];
}
override validateEmptyOrAlternatives(): ILookaheadValidationError[] {
return [];
}
override buildLookaheadForAlternation(options: {
prodOccurrence: number;
rule: Rule;
maxLookahead: number;
hasPredicates: boolean;
dynamicTokensEnabled: boolean
}): (this: BaseParser, orAlts?: IOrAlt<any>[] | undefined) => number | undefined {
const { prodOccurrence, rule, hasPredicates, dynamicTokensEnabled } = options;
const dfas = this.dfas;
const logging = this.logging;
const key = buildATNKey(rule, 'Alternation', prodOccurrence);
const decisionState = this.atn.decisionMap[key];
const decisionIndex = decisionState.decision;
const partialAlts: (TokenType | undefined)[][] = map(
getLookaheadPaths({
maxLookahead: 1,
occurrence: prodOccurrence,
prodType: "Alternation",
rule: rule
}),
(currAlt) => map(currAlt, (path) => path[0])
)
if (isLL1Sequence(partialAlts, false) && !dynamicTokensEnabled) {
const choiceToAlt = reduce(
partialAlts,
(result, currAlt, idx) => {
forEach(currAlt, (currTokType) => {
if (currTokType) {
result[currTokType.tokenTypeIdx!] = idx
forEach(currTokType.categoryMatches!, (currExtendingType) => {
result[currExtendingType] = idx
})
}
})
return result
},
{} as Record<number, number>
)
if (hasPredicates) {
return function (this: BaseParser, orAlts) {
const nextToken = this.LA(1)
const prediction: number | undefined = choiceToAlt[nextToken.tokenTypeIdx]
if (orAlts !== undefined && prediction !== undefined) {
const gate = orAlts[prediction]?.GATE
if (gate !== undefined && gate.call(this) === false) {
return undefined;
}
}
return prediction
}
} else {
return function (this: BaseParser): number | undefined {
const nextToken = this.LA(1)
return choiceToAlt[nextToken.tokenTypeIdx];
}
}
} else if (hasPredicates) {
return function (this: BaseParser, orAlts) {
const predicates = new PredicateSet()
const length = orAlts === undefined ? 0 : orAlts.length
for (let i = 0; i < length; i++) {
const gate = orAlts?.[i].GATE
predicates.set(i, gate === undefined || gate.call(this))
}
const result = adaptivePredict.call(this, dfas, decisionIndex, predicates, logging);
return typeof result === 'number' ? result : undefined;
}
} else {
return function (this: BaseParser) {
const result = adaptivePredict.call(this, dfas, decisionIndex, EMPTY_PREDICATES, logging);
return typeof result === 'number' ? result : undefined;
}
}
}
override buildLookaheadForOptional(options: {
prodOccurrence: number;
prodType: OptionalProductionType;
rule: Rule;
maxLookahead: number;
dynamicTokensEnabled: boolean
}): (this: BaseParser) => boolean {
const { prodOccurrence, rule, prodType, dynamicTokensEnabled } = options;
const dfas = this.dfas;
const logging = this.logging;
const key = buildATNKey(rule, prodType, prodOccurrence);
const decisionState = this.atn.decisionMap[key];
const decisionIndex = decisionState.decision;
const alts = map(
getLookaheadPaths({
maxLookahead: 1,
occurrence: prodOccurrence,
prodType,
rule
}),
(e) => {
return map(e, (g) => g[0])
}
)
if (isLL1Sequence(alts) && alts[0][0] && !dynamicTokensEnabled) {
const alt = alts[0]
const singleTokensTypes = flatten(alt)
if (
singleTokensTypes.length === 1 &&
isEmpty(singleTokensTypes[0].categoryMatches)
) {
const expectedTokenType = singleTokensTypes[0]
const expectedTokenUniqueKey = expectedTokenType.tokenTypeIdx
return function (this: BaseParser): boolean {
return this.LA(1).tokenTypeIdx === expectedTokenUniqueKey
}
} else {
const choiceToAlt = reduce(
singleTokensTypes,
(result, currTokType) => {
if (currTokType !== undefined) {
result[currTokType.tokenTypeIdx!] = true
forEach(currTokType.categoryMatches, (currExtendingType) => {
result[currExtendingType] = true
})
}
return result
},
{} as Record<number, boolean>
)
return function (this: BaseParser): boolean {
const nextToken = this.LA(1)
return choiceToAlt[nextToken.tokenTypeIdx] === true
}
}
}
return function (this: BaseParser) {
const result = adaptivePredict.call(this, dfas, decisionIndex, EMPTY_PREDICATES, logging)
return typeof result === "object" ? false : result === 0;
}
}
}
function isLL1Sequence(sequences: (TokenType | undefined)[][], allowEmpty = true): boolean {
const fullSet = new Set<number>()
for (const alt of sequences) {
const altSet = new Set<number>()
for (const tokType of alt) {
if (tokType === undefined) {
if (allowEmpty) {
// Epsilon production encountered
break
} else {
return false;
}
}
const indices = [tokType.tokenTypeIdx!].concat(tokType.categoryMatches!)
for (const index of indices) {
if (fullSet.has(index)) {
if (!altSet.has(index)) {
return false
}
} else {
fullSet.add(index)
altSet.add(index)
}
}
}
}
return true
}
function initATNSimulator(atn: ATN): DFACache[] {
const decisionLength = atn.decisionStates.length
const decisionToDFA: DFACache[] = Array(decisionLength)
for (let i = 0; i < decisionLength; i++) {
decisionToDFA[i] = createDFACache(atn.decisionStates[i], i)
}
return decisionToDFA;
}
function adaptivePredict(
this: BaseParser,
dfaCaches: DFACache[],
decision: number,
predicateSet: PredicateSet,
logging: AmbiguityReport
): number | AdaptivePredictError {
const dfa = dfaCaches[decision](predicateSet)
let start = dfa.start
if (start === undefined) {
const closure = computeStartState(dfa.atnStartState as ATNState)
start = addDFAState(dfa, newDFAState(closure))
dfa.start = start
}
const alt = performLookahead.apply(this, [dfa, start, predicateSet, logging])
return alt
}
function performLookahead(
this: BaseParser,
dfa: DFA,
s0: DFAState,
predicateSet: PredicateSet,
logging: AmbiguityReport
): number | AdaptivePredictError {
let previousD = s0
let i = 1
const path: IToken[] = []
let t = this.LA(i++)
while (true) {
let d = getExistingTargetState(previousD, t)
if (d === undefined) {
d = computeLookaheadTarget.apply(this, [dfa, previousD, t, i, predicateSet, logging])
}
if (d === DFA_ERROR) {
return buildAdaptivePredictError(path, previousD, t)
}
if (d.isAcceptState === true) {
return d.prediction
}
previousD = d
path.push(t)
t = this.LA(i++)
}
}
function computeLookaheadTarget(
this: BaseParser,
dfa: DFA,
previousD: DFAState,
token: IToken,
lookahead: number,
predicateSet: PredicateSet,
logging: AmbiguityReport
): DFAState {
const reach = computeReachSet(previousD.configs, token, predicateSet)
if (reach.size === 0) {
addDFAEdge(dfa, previousD, token, DFA_ERROR)
return DFA_ERROR
}
let newState = newDFAState(reach)
const predictedAlt = getUniqueAlt(reach, predicateSet)
if (predictedAlt !== undefined) {
newState.isAcceptState = true
newState.prediction = predictedAlt
newState.configs.uniqueAlt = predictedAlt
} else if (hasConflictTerminatingPrediction(reach)) {
const prediction = min(reach.alts)!
newState.isAcceptState = true
newState.prediction = prediction
newState.configs.uniqueAlt = prediction
reportLookaheadAmbiguity.apply(this, [dfa, lookahead, reach.alts, logging])
}
newState = addDFAEdge(dfa, previousD, token, newState)
return newState
}
function reportLookaheadAmbiguity(
this: BaseParser,
dfa: DFA,
lookahead: number,
ambiguityIndices: number[],
logging: AmbiguityReport
) {
const prefixPath: TokenType[] = []
for (let i = 1; i <= lookahead; i++) {
prefixPath.push(this.LA(i).tokenType)
}
const atnState = dfa.atnStartState
const topLevelRule = atnState.rule
const production = atnState.production
const message = buildAmbiguityError({
topLevelRule,
ambiguityIndices,
production,
prefixPath
})
logging(message)
}
function buildAmbiguityError(options: {
topLevelRule: Rule
prefixPath: TokenType[]
ambiguityIndices: number[]
production: IProductionWithOccurrence
}): string {
const pathMsg = map(options.prefixPath, (currtok) =>
tokenLabel(currtok)
).join(", ")
const occurrence =
options.production.idx === 0 ? "" : options.production.idx
let currMessage =
`Ambiguous Alternatives Detected: <${options.ambiguityIndices.join(
", "
)}> in <${getProductionDslName(options.production)}${occurrence}>` +
` inside <${options.topLevelRule.name}> Rule,\n` +
`<${pathMsg}> may appears as a prefix path in all these alternatives.\n`
currMessage =
currMessage +
`See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#AMBIGUOUS_ALTERNATIVES\n` +
`For Further details.`
return currMessage
}
function getProductionDslName(prod: IProductionWithOccurrence): string {
if (prod instanceof NonTerminal) {
return "SUBRULE"
} else if (prod instanceof Option) {
return "OPTION"
} else if (prod instanceof Alternation) {
return "OR"
} else if (prod instanceof RepetitionMandatory) {
return "AT_LEAST_ONE"
} else if (prod instanceof RepetitionMandatoryWithSeparator) {
return "AT_LEAST_ONE_SEP"
} else if (prod instanceof RepetitionWithSeparator) {
return "MANY_SEP"
} else if (prod instanceof Repetition) {
return "MANY"
} else if (prod instanceof Terminal) {
return "CONSUME"
} else {
throw Error("non exhaustive match")
}
}
function buildAdaptivePredictError(
path: IToken[],
previous: DFAState,
current: IToken
): AdaptivePredictError {
const nextTransitions = flatMap(
previous.configs.elements,
(e) => e.state.transitions
)
const nextTokenTypes = uniqBy(
nextTransitions
.filter((e): e is AtomTransition => e instanceof AtomTransition)
.map((e) => e.tokenType),
(e) => e.tokenTypeIdx
)
return {
actualToken: current,
possibleTokenTypes: nextTokenTypes,
tokenPath: path
}
}
function getExistingTargetState(
state: DFAState,
token: IToken
): DFAState | undefined {
return state.edges[token.tokenTypeIdx]
}
function computeReachSet(
configs: ATNConfigSet,
token: IToken,
predicateSet: PredicateSet
): ATNConfigSet {
const intermediate = new ATNConfigSet()
const skippedStopStates: ATNConfig[] = []
for (const c of configs.elements) {
if (predicateSet.is(c.alt) === false) {
continue
}
if (c.state.type === ATN_RULE_STOP) {
skippedStopStates.push(c)
continue
}
const transitionLength = c.state.transitions.length
for (let i = 0; i < transitionLength; i++) {
const transition = c.state.transitions[i]
const target = getReachableTarget(transition, token)
if (target !== undefined) {
intermediate.add({
state: target,
alt: c.alt,
stack: c.stack
})
}
}
}
let reach: ATNConfigSet | undefined
if (skippedStopStates.length === 0 && intermediate.size === 1) {
reach = intermediate
}
if (reach === undefined) {
reach = new ATNConfigSet()
for (const c of intermediate.elements) {
closure(c, reach)
}
}
if (skippedStopStates.length > 0 && !hasConfigInRuleStopState(reach)) {
for (const c of skippedStopStates) {
reach.add(c)
}
}
return reach
}
function getReachableTarget(
transition: Transition,
token: IToken
): ATNState | undefined {
if (
transition instanceof AtomTransition &&
tokenMatcher(token, transition.tokenType)
) {
return transition.target
}
return undefined
}
function getUniqueAlt(
configs: ATNConfigSet,
predicateSet: PredicateSet
): number | undefined {
let alt: number | undefined
for (const c of configs.elements) {
if (predicateSet.is(c.alt) === true) {
if (alt === undefined) {
alt = c.alt
} else if (alt !== c.alt) {
return undefined
}
}
}
return alt
}
function newDFAState(closure: ATNConfigSet): DFAState {
return {
configs: closure,
edges: {},
isAcceptState: false,
prediction: -1
}
}
function addDFAEdge(
dfa: DFA,
from: DFAState,
token: IToken,
to: DFAState
): DFAState {
to = addDFAState(dfa, to)
from.edges[token.tokenTypeIdx] = to
return to
}
function addDFAState(dfa: DFA, state: DFAState): DFAState {
if (state === DFA_ERROR) {
return state
}
// Repetitions have the same config set
// Therefore, storing the key of the config in a map allows us to create a loop in our DFA
const mapKey = state.configs.key
const existing = dfa.states[mapKey]
if (existing !== undefined) {
return existing
}
state.configs.finalize()
dfa.states[mapKey] = state
return state
}
function computeStartState(atnState: ATNState): ATNConfigSet {
const configs = new ATNConfigSet()
const numberOfTransitions = atnState.transitions.length
for (let i = 0; i < numberOfTransitions; i++) {
const target = atnState.transitions[i].target
const config: ATNConfig = {
state: target,
alt: i,
stack: []
}
closure(config, configs)
}
return configs
}
function closure(config: ATNConfig, configs: ATNConfigSet): void {
const p = config.state
if (p.type === ATN_RULE_STOP) {
if (config.stack.length > 0) {
const atnStack = [...config.stack]
const followState = atnStack.pop()!
const followConfig: ATNConfig = {
state: followState,
alt: config.alt,
stack: atnStack
}
closure(followConfig, configs)
} else {
// Dipping into outer context, simply add the config
// This will stop computation once every config is at the rule stop state
configs.add(config)
}
return
}
if (!p.epsilonOnlyTransitions) {
configs.add(config)
}
const transitionLength = p.transitions.length
for (let i = 0; i < transitionLength; i++) {
const transition = p.transitions[i]
const c = getEpsilonTarget(config, transition)
if (c !== undefined) {
closure(c, configs)
}
}
}
function getEpsilonTarget(
config: ATNConfig,
transition: Transition
): ATNConfig | undefined {
if (transition instanceof EpsilonTransition) {
return {
state: transition.target,
alt: config.alt,
stack: config.stack
}
} else if (transition instanceof RuleTransition) {
const stack = [...config.stack, transition.followState]
return {
state: transition.target,
alt: config.alt,
stack
}
}
return undefined
}
function hasConfigInRuleStopState(configs: ATNConfigSet): boolean {
for (const c of configs.elements) {
if (c.state.type === ATN_RULE_STOP) {
return true
}
}
return false
}
function allConfigsInRuleStopStates(configs: ATNConfigSet): boolean {
for (const c of configs.elements) {
if (c.state.type !== ATN_RULE_STOP) {
return false
}
}
return true
}
function hasConflictTerminatingPrediction(configs: ATNConfigSet): boolean {
if (allConfigsInRuleStopStates(configs)) {
return true
}
const altSets = getConflictingAltSets(configs.elements)
const heuristic =
hasConflictingAltSet(altSets) && !hasStateAssociatedWithOneAlt(altSets)
return heuristic
}
function getConflictingAltSets(
configs: readonly ATNConfig[]
): Map<string, Record<number, boolean>> {
const configToAlts = new Map<string, Record<number, boolean>>()
for (const c of configs) {
const key = getATNConfigKey(c, false)
let alts = configToAlts.get(key)
if (alts === undefined) {
alts = {}
configToAlts.set(key, alts)
}
alts[c.alt] = true
}
return configToAlts
}
function hasConflictingAltSet(
altSets: Map<string, Record<number, boolean>>
): boolean {
for (const value of Array.from(altSets.values())) {
if (Object.keys(value).length > 1) {
return true
}
}
return false
}
function hasStateAssociatedWithOneAlt(
altSets: Map<string, Record<number, boolean>>
): boolean {
for (const value of Array.from(altSets.values())) {
if (Object.keys(value).length === 1) {
return true
}
}
return false
}

302
node_modules/chevrotain-allstar/src/atn.test.ts generated vendored Normal file
View File

@@ -0,0 +1,302 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { createToken, EmbeddedActionsParser, EOF, IToken, TokenType } from "chevrotain"
import { LLStarLookaheadStrategy } from "./all-star-lookahead"
describe("ATN Simulator", () => {
describe("LL(*) lookahead", () => {
const A = createToken({ name: "A", pattern: "a" })
const B = createToken({ name: "B", pattern: "b" })
class UnboundedLookaheadParser extends EmbeddedActionsParser {
constructor() {
super([A, B], {
lookaheadStrategy: new LLStarLookaheadStrategy()
})
this.performSelfAnalysis()
}
LongRule = this.RULE("LongRule", () => {
return this.OR([
{
ALT: () => {
return 0
}
},
{
ALT: () => {
this.AT_LEAST_ONE1(() => this.CONSUME1(A))
return 1
}
},
{
ALT: () => {
this.AT_LEAST_ONE2(() => this.CONSUME2(A))
this.CONSUME(B)
return 2
}
}
])
})
}
it("Should pick longest alternative instead of first #1", () => {
const parser = new UnboundedLookaheadParser()
parser.input = [
createRegularToken(A),
createRegularToken(A),
createRegularToken(A)
]
const result = parser.LongRule()
expect(result).toBe(1);
})
it("Should pick longest alternative instead of first #2", () => {
const parser = new UnboundedLookaheadParser()
parser.input = [
createRegularToken(A),
createRegularToken(A),
createRegularToken(B)
]
const result = parser.LongRule()
expect(result).toBe(2);
})
it("Should pick shortest fitting alternative", () => {
const parser = new UnboundedLookaheadParser()
parser.input = []
const result = parser.LongRule()
expect(result).toBe(0);
})
})
describe("Ambiguity Detection", () => {
const A = createToken({ name: "A" })
const B = createToken({ name: "B" })
class AmbigiousParser extends EmbeddedActionsParser {
ambiguityReports: string[] = []
constructor() {
super([A, B], {
lookaheadStrategy: new LLStarLookaheadStrategy({
logging: (message) => this.ambiguityReports.push(message)
})
});
this.performSelfAnalysis()
}
OptionRule = this.RULE("OptionRule", () => {
let usedOption = false
this.OPTION(() => {
this.AT_LEAST_ONE1(() => this.CONSUME1(A))
usedOption = true
})
this.AT_LEAST_ONE2(() => this.CONSUME2(A))
return usedOption
})
AltRule = this.RULE("AltRule", () => {
return this.OR([
{
ALT: () => {
this.SUBRULE(this.RuleB)
return 0
}
},
{
ALT: () => {
this.SUBRULE(this.RuleC)
return 1
}
}
])
})
RuleB = this.RULE("RuleB", () => {
this.MANY(() => this.CONSUME(A))
})
RuleC = this.RULE("RuleC", () => {
this.MANY(() => this.CONSUME(A))
this.OPTION(() => this.CONSUME(B))
})
AltRuleWithEOF = this.RULE("AltRuleWithEOF", () => {
return this.OR([
{
ALT: () => {
this.SUBRULE1(this.RuleEOF)
return 0
}
},
{
ALT: () => {
this.SUBRULE2(this.RuleEOF)
return 1
}
}
])
})
RuleEOF = this.RULE("RuleEOF", () => {
this.MANY1(() => this.CONSUME(A))
this.CONSUME(EOF)
})
AltRuleWithPred = this.RULE("AltRuleWithPred", (pred?: boolean) => {
return this.OR([
{
ALT: () => {
this.CONSUME1(A)
return 0
},
GATE: () => (pred === undefined ? true : pred)
},
{
ALT: () => {
this.CONSUME2(A)
return 1
},
GATE: () => (pred === undefined ? true : !pred)
},
{
ALT: () => {
this.CONSUME(B)
return 2
}
}
])
})
AltWithOption = this.RULE("AltWithOption", () => {
const intermediate = this.OR([
{
ALT: () => {
this.CONSUME1(A)
return 2
}
},
{
ALT: () => {
this.CONSUME2(B)
return 4
}
}
])
const option = this.OPTION(() => {
this.CONSUME3(A);
return 1;
})
return (option ?? 0) + intermediate;
})
}
it("Should pick option on ambiguity", () => {
const parser = new AmbigiousParser()
parser.input = [
createRegularToken(A),
createRegularToken(A),
createRegularToken(A)
]
const result = parser.OptionRule()
expect(result).toBeTruthy();
// The rule nests a `AT_LEAST_ONE` inside and outside the OPTION
// Both productions produce lookahead ambiguities
expect(parser.ambiguityReports[0]).toMatch("<0, 1> in <OPTION>")
expect(parser.ambiguityReports[1]).toMatch("<0, 1> in <AT_LEAST_ONE1>")
})
it("Should pick first alternative on ambiguity", () => {
const parser = new AmbigiousParser()
parser.input = [
createRegularToken(A),
createRegularToken(A),
createRegularToken(A)
]
const result = parser.AltRule()
expect(result).toBe(0);
expect(parser.ambiguityReports[0]).toMatch("<0, 1> in <OR>")
})
it("Should pick first alternative on EOF ambiguity", () => {
const parser = new AmbigiousParser()
parser.input = []
const result = parser.AltRuleWithEOF()
expect(result).toBe(0);
expect(parser.ambiguityReports[0]).toMatch("<0, 1> in <OR>")
})
it("Should pick correct alternative on long prefix", () => {
const parser = new AmbigiousParser()
parser.input = [
createRegularToken(A),
createRegularToken(A),
createRegularToken(B)
]
const result = parser.AltRule()
expect(result).toBe(1);
expect(parser.ambiguityReports).toHaveLength(0);
})
it("Should resolve ambiguity using predicate", () => {
const parser = new AmbigiousParser()
parser.input = [createRegularToken(A)]
const resultAutomatic = parser.AltRuleWithPred(undefined)
// Automatically resolving the ambiguity should return `0`
expect(resultAutomatic).toBe(0);
// It should also create an ambiguity report
expect(parser.ambiguityReports[0]).toMatch("<0, 1> in <OR>")
parser.ambiguityReports = []
parser.input = [createRegularToken(A)]
const resultTrue = parser.AltRuleWithPred(true)
expect(resultTrue).toBe(0);
parser.input = [createRegularToken(A)]
const resultFalse = parser.AltRuleWithPred(false)
expect(resultFalse).toBe(1),
expect(parser.ambiguityReports).toHaveLength(0);
})
it("Should pick non-ambigious alternative inside of ambigious, predicated alternation", () => {
const parser = new AmbigiousParser()
parser.input = [createRegularToken(B)]
const result = parser.AltRuleWithPred(undefined)
expect(result).toBe(2);
expect(parser.ambiguityReports).toHaveLength(0);
})
it("Should work with alternatives followed by optional elements", () => {
const parser = new AmbigiousParser();
parser.input = [createRegularToken(B), createRegularToken(A)];
const result = parser.AltWithOption();
expect(result).toBe(5);
})
})
})
function createRegularToken(
tokType: TokenType,
image = "",
startOffset = 1,
startLine?: number,
startColumn?: number,
endOffset?: number,
endLine?: number,
endColumn?: number
): IToken {
return {
image: image,
startOffset: startOffset,
startLine: startLine,
startColumn: startColumn,
endOffset: endOffset,
endLine: endLine,
endColumn: endColumn,
tokenTypeIdx: tokType.tokenTypeIdx!,
tokenType: tokType
}
}

642
node_modules/chevrotain-allstar/src/atn.ts generated vendored Normal file
View File

@@ -0,0 +1,642 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import map from "lodash-es/map.js"
import filter from "lodash-es/filter.js"
import {
IProduction,
IProductionWithOccurrence,
TokenType,
Alternation,
NonTerminal,
Rule,
Option,
RepetitionMandatory,
Repetition,
Terminal,
Alternative,
RepetitionWithSeparator,
RepetitionMandatoryWithSeparator,
LookaheadProductionType
} from "chevrotain"
export function buildATNKey(rule: Rule, type: LookaheadProductionType, occurrence: number): string {
return `${rule.name}_${type}_${occurrence}`;
}
export interface ATN {
decisionMap: Record<string, DecisionState>
states: ATNState[]
decisionStates: DecisionState[]
ruleToStartState: Map<Rule, RuleStartState>
ruleToStopState: Map<Rule, RuleStopState>
}
export const ATN_INVALID_TYPE = 0
export const ATN_BASIC = 1
export const ATN_RULE_START = 2
export const ATN_PLUS_BLOCK_START = 4
export const ATN_STAR_BLOCK_START = 5
// Currently unused as the ATN is not used for lexing
export const ATN_TOKEN_START = 6
export const ATN_RULE_STOP = 7
export const ATN_BLOCK_END = 8
export const ATN_STAR_LOOP_BACK = 9
export const ATN_STAR_LOOP_ENTRY = 10
export const ATN_PLUS_LOOP_BACK = 11
export const ATN_LOOP_END = 12
export type ATNState =
| BasicState
| BasicBlockStartState
| PlusBlockStartState
| PlusLoopbackState
| StarBlockStartState
| StarLoopbackState
| StarLoopEntryState
| BlockEndState
| RuleStartState
| RuleStopState
| LoopEndState
export interface ATNBaseState {
atn: ATN
production: IProductionWithOccurrence
stateNumber: number
rule: Rule
epsilonOnlyTransitions: boolean
transitions: Transition[]
nextTokenWithinRule: number[]
}
export interface BasicState extends ATNBaseState {
type: typeof ATN_BASIC
}
export interface BlockStartState extends DecisionState {
end: BlockEndState
}
export interface BasicBlockStartState extends BlockStartState {
type: typeof ATN_BASIC
}
export interface PlusBlockStartState extends BlockStartState {
loopback: PlusLoopbackState
type: typeof ATN_PLUS_BLOCK_START
}
export interface PlusLoopbackState extends DecisionState {
type: typeof ATN_PLUS_LOOP_BACK
}
export interface StarBlockStartState extends BlockStartState {
type: typeof ATN_STAR_BLOCK_START
}
export interface StarLoopbackState extends ATNBaseState {
type: typeof ATN_STAR_LOOP_BACK
}
export interface StarLoopEntryState extends DecisionState {
loopback: StarLoopbackState
type: typeof ATN_STAR_LOOP_ENTRY
}
export interface BlockEndState extends ATNBaseState {
start: BlockStartState
type: typeof ATN_BLOCK_END
}
export interface DecisionState extends ATNBaseState {
decision: number
}
export interface LoopEndState extends ATNBaseState {
loopback: ATNState
type: typeof ATN_LOOP_END
}
export interface RuleStartState extends ATNBaseState {
stop: RuleStopState
type: typeof ATN_RULE_START
}
export interface RuleStopState extends ATNBaseState {
type: typeof ATN_RULE_STOP
}
export interface Transition {
target: ATNState
isEpsilon(): boolean
}
export abstract class AbstractTransition implements Transition {
target: ATNState
constructor(target: ATNState) {
this.target = target
}
isEpsilon() {
return false
}
}
export class AtomTransition extends AbstractTransition {
tokenType: TokenType
constructor(target: ATNState, tokenType: TokenType) {
super(target)
this.tokenType = tokenType
}
}
export class EpsilonTransition extends AbstractTransition {
constructor(target: ATNState) {
super(target)
}
isEpsilon() {
return true
}
}
export class RuleTransition extends AbstractTransition {
rule: Rule
followState: ATNState
constructor(ruleStart: RuleStartState, rule: Rule, followState: ATNState) {
super(ruleStart)
this.rule = rule
this.followState = followState
}
isEpsilon() {
return true
}
}
interface ATNHandle {
left: ATNState
right: ATNState
}
export function createATN(rules: Rule[]): ATN {
const atn: ATN = {
decisionMap: {},
decisionStates: [],
ruleToStartState: new Map(),
ruleToStopState: new Map(),
states: []
}
createRuleStartAndStopATNStates(atn, rules)
const ruleLength = rules.length
for (let i = 0; i < ruleLength; i++) {
const rule = rules[i]
const ruleBlock = block(atn, rule, rule)
if (ruleBlock === undefined) {
continue
}
buildRuleHandle(atn, rule, ruleBlock)
}
return atn
}
function createRuleStartAndStopATNStates(atn: ATN, rules: Rule[]): void {
const ruleLength = rules.length
for (let i = 0; i < ruleLength; i++) {
const rule = rules[i]
const start = newState<RuleStartState>(atn, rule, undefined, {
type: ATN_RULE_START
})
const stop = newState<RuleStopState>(atn, rule, undefined, {
type: ATN_RULE_STOP
})
start.stop = stop
atn.ruleToStartState.set(rule, start)
atn.ruleToStopState.set(rule, stop)
}
}
function atom(
atn: ATN,
rule: Rule,
production: IProduction
): ATNHandle | undefined {
if (production instanceof Terminal) {
return tokenRef(atn, rule, production.terminalType, production)
} else if (production instanceof NonTerminal) {
return ruleRef(atn, rule, production)
} else if (production instanceof Alternation) {
return alternation(atn, rule, production)
} else if (production instanceof Option) {
return option(atn, rule, production)
} else if (production instanceof Repetition) {
return repetition(atn, rule, production)
} else if (production instanceof RepetitionWithSeparator) {
return repetitionSep(atn, rule, production)
} else if (production instanceof RepetitionMandatory) {
return repetitionMandatory(atn, rule, production)
} else if (production instanceof RepetitionMandatoryWithSeparator) {
return repetitionMandatorySep(atn, rule, production)
} else {
return block(atn, rule, production as Alternative)
}
}
function repetition(atn: ATN, rule: Rule, repetition: Repetition): ATNHandle {
const starState = newState<StarBlockStartState>(atn, rule, repetition, {
type: ATN_STAR_BLOCK_START
})
defineDecisionState(atn, starState)
const handle = makeAlts(
atn,
rule,
starState,
repetition,
block(atn, rule, repetition)
)
return star(atn, rule, repetition, handle)
}
function repetitionSep(
atn: ATN,
rule: Rule,
repetition: RepetitionWithSeparator
): ATNHandle {
const starState = newState<StarBlockStartState>(atn, rule, repetition, {
type: ATN_STAR_BLOCK_START
})
defineDecisionState(atn, starState)
const handle = makeAlts(
atn,
rule,
starState,
repetition,
block(atn, rule, repetition)
)
const sep = tokenRef(atn, rule, repetition.separator, repetition)
return star(atn, rule, repetition, handle, sep)
}
function repetitionMandatory(
atn: ATN,
rule: Rule,
repetition: RepetitionMandatory
): ATNHandle {
const plusState = newState<PlusBlockStartState>(atn, rule, repetition, {
type: ATN_PLUS_BLOCK_START
})
defineDecisionState(atn, plusState)
const handle = makeAlts(
atn,
rule,
plusState,
repetition,
block(atn, rule, repetition)
)
return plus(atn, rule, repetition, handle)
}
function repetitionMandatorySep(
atn: ATN,
rule: Rule,
repetition: RepetitionMandatoryWithSeparator
): ATNHandle {
const plusState = newState<PlusBlockStartState>(atn, rule, repetition, {
type: ATN_PLUS_BLOCK_START
})
defineDecisionState(atn, plusState)
const handle = makeAlts(
atn,
rule,
plusState,
repetition,
block(atn, rule, repetition)
)
const sep = tokenRef(atn, rule, repetition.separator, repetition)
return plus(atn, rule, repetition, handle, sep)
}
function alternation(
atn: ATN,
rule: Rule,
alternation: Alternation
): ATNHandle {
const start = newState<BasicBlockStartState>(atn, rule, alternation, {
type: ATN_BASIC
})
defineDecisionState(atn, start)
const alts = map(alternation.definition, (e) => atom(atn, rule, e))
const handle = makeAlts(atn, rule, start, alternation, ...alts)
return handle
}
function option(atn: ATN, rule: Rule, option: Option): ATNHandle {
const start = newState<BasicBlockStartState>(atn, rule, option, {
type: ATN_BASIC
})
defineDecisionState(atn, start)
const handle = makeAlts(atn, rule, start, option, block(atn, rule, option))
return optional(atn, rule, option, handle)
}
function block(
atn: ATN,
rule: Rule,
block: { definition: IProduction[] }
): ATNHandle | undefined {
const handles = filter(
map(block.definition, (e) => atom(atn, rule, e)),
(e) => e !== undefined
) as ATNHandle[]
if (handles.length === 1) {
return handles[0]
} else if (handles.length === 0) {
return undefined
} else {
return makeBlock(atn, handles)
}
}
function plus(
atn: ATN,
rule: Rule,
plus: IProductionWithOccurrence,
handle: ATNHandle,
sep?: ATNHandle
): ATNHandle {
const blkStart = handle.left as PlusBlockStartState
const blkEnd = handle.right
const loop = newState<PlusLoopbackState>(atn, rule, plus, {
type: ATN_PLUS_LOOP_BACK
})
defineDecisionState(atn, loop)
const end = newState<LoopEndState>(atn, rule, plus, {
type: ATN_LOOP_END
})
blkStart.loopback = loop
end.loopback = loop
atn.decisionMap[buildATNKey(rule, sep ? 'RepetitionMandatoryWithSeparator' : 'RepetitionMandatory', plus.idx)] = loop;
epsilon(blkEnd, loop) // block can see loop back
// Depending on whether we have a separator we put the exit transition at index 1 or 0
// This influences the chosen option in the lookahead DFA
if (sep === undefined) {
epsilon(loop, blkStart) // loop back to start
epsilon(loop, end) // exit
} else {
epsilon(loop, end) // exit
// loop back to start with separator
epsilon(loop, sep.left)
epsilon(sep.right, blkStart)
}
return {
left: blkStart,
right: end
}
}
function star(
atn: ATN,
rule: Rule,
star: IProductionWithOccurrence,
handle: ATNHandle,
sep?: ATNHandle
): ATNHandle {
const start = handle.left
const end = handle.right
const entry = newState<StarLoopEntryState>(atn, rule, star, {
type: ATN_STAR_LOOP_ENTRY
})
defineDecisionState(atn, entry)
const loopEnd = newState<LoopEndState>(atn, rule, star, {
type: ATN_LOOP_END
})
const loop = newState<StarLoopbackState>(atn, rule, star, {
type: ATN_STAR_LOOP_BACK
})
entry.loopback = loop
loopEnd.loopback = loop
epsilon(entry, start) // loop enter edge (alt 2)
epsilon(entry, loopEnd) // bypass loop edge (alt 1)
epsilon(end, loop) // block end hits loop back
if (sep !== undefined) {
epsilon(loop, loopEnd) // end loop
// loop back to start of handle using separator
epsilon(loop, sep.left)
epsilon(sep.right, start)
} else {
epsilon(loop, entry) // loop back to entry/exit decision
}
atn.decisionMap[buildATNKey(rule, sep ? 'RepetitionWithSeparator' : 'Repetition', star.idx)] = entry;
return {
left: entry,
right: loopEnd
}
}
function optional(atn: ATN, rule: Rule, optional: Option, handle: ATNHandle): ATNHandle {
const start = handle.left as DecisionState
const end = handle.right
epsilon(start, end)
atn.decisionMap[buildATNKey(rule, 'Option', optional.idx)] = start;
return handle
}
function defineDecisionState(atn: ATN, state: DecisionState): number {
atn.decisionStates.push(state)
state.decision = atn.decisionStates.length - 1
return state.decision
}
function makeAlts(
atn: ATN,
rule: Rule,
start: BlockStartState,
production: IProductionWithOccurrence,
...alts: (ATNHandle | undefined)[]
): ATNHandle {
const end = newState<BlockEndState>(atn, rule, production, {
type: ATN_BLOCK_END,
start
})
start.end = end
for (const alt of alts) {
if (alt !== undefined) {
// hook alts up to decision block
epsilon(start, alt.left)
epsilon(alt.right, end)
} else {
epsilon(start, end)
}
}
const handle: ATNHandle = {
left: start as ATNState,
right: end
}
atn.decisionMap[buildATNKey(rule, getProdType(production), production.idx)] = start
return handle
}
function getProdType(production: IProduction): LookaheadProductionType {
if (production instanceof Alternation) {
return 'Alternation';
} else if (production instanceof Option) {
return 'Option';
} else if (production instanceof Repetition) {
return 'Repetition';
} else if (production instanceof RepetitionWithSeparator) {
return 'RepetitionWithSeparator';
} else if (production instanceof RepetitionMandatory) {
return 'RepetitionMandatory';
} else if (production instanceof RepetitionMandatoryWithSeparator) {
return 'RepetitionMandatoryWithSeparator';
} else {
throw new Error('Invalid production type encountered');
}
}
function makeBlock(atn: ATN, alts: ATNHandle[]): ATNHandle {
const altsLength = alts.length
for (let i = 0; i < altsLength - 1; i++) {
const handle = alts[i]
let transition: Transition | undefined
if (handle.left.transitions.length === 1) {
transition = handle.left.transitions[0]
}
const isRuleTransition = transition instanceof RuleTransition
const ruleTransition = transition as RuleTransition
const next = alts[i + 1].left
if (
handle.left.type === ATN_BASIC &&
handle.right.type === ATN_BASIC &&
transition !== undefined &&
((isRuleTransition && ruleTransition.followState === handle.right) ||
transition.target === handle.right)
) {
// we can avoid epsilon edge to next element
if (isRuleTransition) {
ruleTransition.followState = next
} else {
transition.target = next
}
removeState(atn, handle.right) // we skipped over this state
} else {
// need epsilon if previous block's right end node is complex
epsilon(handle.right, next)
}
}
const first = alts[0]
const last = alts[altsLength - 1]
return {
left: first.left,
right: last.right
}
}
function tokenRef(
atn: ATN,
rule: Rule,
tokenType: TokenType,
production: IProductionWithOccurrence
): ATNHandle {
const left = newState<BasicState>(atn, rule, production, {
type: ATN_BASIC
})
const right = newState<BasicState>(atn, rule, production, {
type: ATN_BASIC
})
addTransition(left, new AtomTransition(right, tokenType))
return {
left,
right
}
}
function ruleRef(
atn: ATN,
currentRule: Rule,
nonTerminal: NonTerminal
): ATNHandle {
const rule = nonTerminal.referencedRule
const start = atn.ruleToStartState.get(rule)!
const left = newState<BasicBlockStartState>(atn, currentRule, nonTerminal, {
type: ATN_BASIC
})
const right = newState<BasicBlockStartState>(atn, currentRule, nonTerminal, {
type: ATN_BASIC
})
const call = new RuleTransition(start, rule, right)
addTransition(left, call)
return {
left,
right
}
}
function buildRuleHandle(atn: ATN, rule: Rule, block: ATNHandle): ATNHandle {
const start = atn.ruleToStartState.get(rule)!
epsilon(start, block.left)
const stop = atn.ruleToStopState.get(rule)!
epsilon(block.right, stop)
const handle: ATNHandle = {
left: start,
right: stop
}
return handle
}
function epsilon(a: ATNBaseState, b: ATNBaseState): void {
const transition = new EpsilonTransition(b as ATNState)
addTransition(a, transition)
}
function newState<T extends ATNState>(
atn: ATN,
rule: Rule,
production: IProductionWithOccurrence | undefined,
partial: Partial<T>
): T {
const t: T = {
atn,
production,
epsilonOnlyTransitions: false,
rule,
transitions: [],
nextTokenWithinRule: [],
stateNumber: atn.states.length,
...partial
} as unknown as T
atn.states.push(t)
return t
}
function addTransition(state: ATNBaseState, transition: Transition) {
// A single ATN state can only contain epsilon transitions or non-epsilon transitions
// Because they are never mixed, only setting the property for the first transition is fine
if (state.transitions.length === 0) {
state.epsilonOnlyTransitions = transition.isEpsilon()
}
state.transitions.push(transition)
}
function removeState(atn: ATN, state: ATNState): void {
atn.states.splice(atn.states.indexOf(state), 1)
}

78
node_modules/chevrotain-allstar/src/dfa.ts generated vendored Normal file
View File

@@ -0,0 +1,78 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import map from "lodash-es/map.js"
import { ATNState, DecisionState } from "./atn.js"
export interface DFA {
start?: DFAState
states: Record<string, DFAState>
decision: number
atnStartState: DecisionState
}
export interface DFAState {
configs: ATNConfigSet
edges: Record<number, DFAState>
isAcceptState: boolean
prediction: number
}
export const DFA_ERROR = {} as DFAState
export interface ATNConfig {
state: ATNState
alt: number
stack: ATNState[]
}
export class ATNConfigSet {
private map: Record<string, number> = {}
private configs: ATNConfig[] = []
uniqueAlt: number | undefined
get size(): number {
return this.configs.length
}
finalize(): void {
// Empties the map to free up memory
this.map = {}
}
add(config: ATNConfig): void {
const key = getATNConfigKey(config)
// Only add configs which don't exist in our map already
// While this does not influence the actual algorithm, adding them anyway would massively increase memory consumption
if (!(key in this.map)) {
this.map[key] = this.configs.length
this.configs.push(config)
}
}
get elements(): readonly ATNConfig[] {
return this.configs
}
get alts(): number[] {
return map(this.configs, (e) => e.alt)
}
get key(): string {
let value = ""
for (const k in this.map) {
value += k + ":"
}
return value
}
}
export function getATNConfigKey(config: ATNConfig, alt = true) {
return `${alt ? `a${config.alt}` : ""}s${
config.state.stateNumber
}:${config.stack.map((e) => e.stateNumber.toString()).join("_")}`
}

11
node_modules/chevrotain-allstar/src/index.ts generated vendored Normal file
View File

@@ -0,0 +1,11 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
export {
AmbiguityReport,
LLStarLookaheadOptions,
LLStarLookaheadStrategy
} from './all-star-lookahead.js';