UNPKG

chevrotain

Version:

Chevrotain is a high performance fault tolerant javascript parsing DSL for building recursive decent parsers

720 lines (623 loc) 18.2 kB
import { AtLeastOneSepMethodOpts, ConsumeMethodOpts, DSLMethodOpts, DSLMethodOptsWithErr, GrammarAction, IOrAlt, IRuleConfig, ISerializedGast, IToken, ManySepMethodOpts, OrMethodOpts, SubruleMethodOpts, TokenType, } from "@chevrotain/types"; import { includes, values } from "lodash-es"; import { isRecognitionException } from "../../exceptions_public.js"; import { DEFAULT_RULE_CONFIG, ParserDefinitionErrorType } from "../parser.js"; import { defaultGrammarValidatorErrorProvider } from "../../errors_public.js"; import { validateRuleIsOverridden } from "../../grammar/checks.js"; import { MixedInParser } from "./parser_traits.js"; import { Rule, serializeGrammar } from "@chevrotain/gast"; import { IParserDefinitionError } from "../../grammar/types.js"; import { ParserMethodInternal } from "../types.js"; /** * This trait is responsible for implementing the public API * for defining Chevrotain parsers, i.e: * - CONSUME * - RULE * - OPTION * - ... */ export class RecognizerApi { ACTION<T>(this: MixedInParser, impl: () => T): T { return impl.call(this); } consume( this: MixedInParser, idx: number, tokType: TokenType, options?: ConsumeMethodOpts, ): IToken { return this.consumeInternal(tokType, idx, options); } subrule<ARGS extends unknown[], R>( this: MixedInParser, idx: number, ruleToCall: ParserMethodInternal<ARGS, R>, options?: SubruleMethodOpts<ARGS>, ): R { return this.subruleInternal(ruleToCall, idx, options); } option<OUT>( this: MixedInParser, idx: number, actionORMethodDef: GrammarAction<OUT> | DSLMethodOpts<OUT>, ): OUT | undefined { return this.optionInternal(actionORMethodDef, idx); } or( this: MixedInParser, idx: number, altsOrOpts: IOrAlt<any>[] | OrMethodOpts<any>, ): any { return this.orInternal(altsOrOpts, idx); } many( this: MixedInParser, idx: number, actionORMethodDef: GrammarAction<any> | DSLMethodOpts<any>, ): void { return this.manyInternal(idx, actionORMethodDef); } atLeastOne( this: MixedInParser, idx: number, actionORMethodDef: GrammarAction<any> | DSLMethodOptsWithErr<any>, ): void { return this.atLeastOneInternal(idx, actionORMethodDef); } CONSUME( this: MixedInParser, tokType: TokenType, options?: ConsumeMethodOpts, ): IToken { return this.consumeInternal(tokType, 0, options); } CONSUME1( this: MixedInParser, tokType: TokenType, options?: ConsumeMethodOpts, ): IToken { return this.consumeInternal(tokType, 1, options); } CONSUME2( this: MixedInParser, tokType: TokenType, options?: ConsumeMethodOpts, ): IToken { return this.consumeInternal(tokType, 2, options); } CONSUME3( this: MixedInParser, tokType: TokenType, options?: ConsumeMethodOpts, ): IToken { return this.consumeInternal(tokType, 3, options); } CONSUME4( this: MixedInParser, tokType: TokenType, options?: ConsumeMethodOpts, ): IToken { return this.consumeInternal(tokType, 4, options); } CONSUME5( this: MixedInParser, tokType: TokenType, options?: ConsumeMethodOpts, ): IToken { return this.consumeInternal(tokType, 5, options); } CONSUME6( this: MixedInParser, tokType: TokenType, options?: ConsumeMethodOpts, ): IToken { return this.consumeInternal(tokType, 6, options); } CONSUME7( this: MixedInParser, tokType: TokenType, options?: ConsumeMethodOpts, ): IToken { return this.consumeInternal(tokType, 7, options); } CONSUME8( this: MixedInParser, tokType: TokenType, options?: ConsumeMethodOpts, ): IToken { return this.consumeInternal(tokType, 8, options); } CONSUME9( this: MixedInParser, tokType: TokenType, options?: ConsumeMethodOpts, ): IToken { return this.consumeInternal(tokType, 9, options); } SUBRULE<ARGS extends unknown[], R>( this: MixedInParser, ruleToCall: ParserMethodInternal<ARGS, R>, options?: SubruleMethodOpts<ARGS>, ): R { return this.subruleInternal(ruleToCall, 0, options); } SUBRULE1<ARGS extends unknown[], R>( this: MixedInParser, ruleToCall: ParserMethodInternal<ARGS, R>, options?: SubruleMethodOpts<ARGS>, ): R { return this.subruleInternal(ruleToCall, 1, options); } SUBRULE2<ARGS extends unknown[], R>( this: MixedInParser, ruleToCall: ParserMethodInternal<ARGS, R>, options?: SubruleMethodOpts<ARGS>, ): R { return this.subruleInternal(ruleToCall, 2, options); } SUBRULE3<ARGS extends unknown[], R>( this: MixedInParser, ruleToCall: ParserMethodInternal<ARGS, R>, options?: SubruleMethodOpts<ARGS>, ): R { return this.subruleInternal(ruleToCall, 3, options); } SUBRULE4<ARGS extends unknown[], R>( this: MixedInParser, ruleToCall: ParserMethodInternal<ARGS, R>, options?: SubruleMethodOpts<ARGS>, ): R { return this.subruleInternal(ruleToCall, 4, options); } SUBRULE5<ARGS extends unknown[], R>( this: MixedInParser, ruleToCall: ParserMethodInternal<ARGS, R>, options?: SubruleMethodOpts<ARGS>, ): R { return this.subruleInternal(ruleToCall, 5, options); } SUBRULE6<ARGS extends unknown[], R>( this: MixedInParser, ruleToCall: ParserMethodInternal<ARGS, R>, options?: SubruleMethodOpts<ARGS>, ): R { return this.subruleInternal(ruleToCall, 6, options); } SUBRULE7<ARGS extends unknown[], R>( this: MixedInParser, ruleToCall: ParserMethodInternal<ARGS, R>, options?: SubruleMethodOpts<ARGS>, ): R { return this.subruleInternal(ruleToCall, 7, options); } SUBRULE8<ARGS extends unknown[], R>( this: MixedInParser, ruleToCall: ParserMethodInternal<ARGS, R>, options?: SubruleMethodOpts<ARGS>, ): R { return this.subruleInternal(ruleToCall, 8, options); } SUBRULE9<ARGS extends unknown[], R>( this: MixedInParser, ruleToCall: ParserMethodInternal<ARGS, R>, options?: SubruleMethodOpts<ARGS>, ): R { return this.subruleInternal(ruleToCall, 9, options); } OPTION<OUT>( this: MixedInParser, actionORMethodDef: GrammarAction<OUT> | DSLMethodOpts<OUT>, ): OUT | undefined { return this.optionInternal(actionORMethodDef, 0); } OPTION1<OUT>( this: MixedInParser, actionORMethodDef: GrammarAction<OUT> | DSLMethodOpts<OUT>, ): OUT | undefined { return this.optionInternal(actionORMethodDef, 1); } OPTION2<OUT>( this: MixedInParser, actionORMethodDef: GrammarAction<OUT> | DSLMethodOpts<OUT>, ): OUT | undefined { return this.optionInternal(actionORMethodDef, 2); } OPTION3<OUT>( this: MixedInParser, actionORMethodDef: GrammarAction<OUT> | DSLMethodOpts<OUT>, ): OUT | undefined { return this.optionInternal(actionORMethodDef, 3); } OPTION4<OUT>( this: MixedInParser, actionORMethodDef: GrammarAction<OUT> | DSLMethodOpts<OUT>, ): OUT | undefined { return this.optionInternal(actionORMethodDef, 4); } OPTION5<OUT>( this: MixedInParser, actionORMethodDef: GrammarAction<OUT> | DSLMethodOpts<OUT>, ): OUT | undefined { return this.optionInternal(actionORMethodDef, 5); } OPTION6<OUT>( this: MixedInParser, actionORMethodDef: GrammarAction<OUT> | DSLMethodOpts<OUT>, ): OUT | undefined { return this.optionInternal(actionORMethodDef, 6); } OPTION7<OUT>( this: MixedInParser, actionORMethodDef: GrammarAction<OUT> | DSLMethodOpts<OUT>, ): OUT | undefined { return this.optionInternal(actionORMethodDef, 7); } OPTION8<OUT>( this: MixedInParser, actionORMethodDef: GrammarAction<OUT> | DSLMethodOpts<OUT>, ): OUT | undefined { return this.optionInternal(actionORMethodDef, 8); } OPTION9<OUT>( this: MixedInParser, actionORMethodDef: GrammarAction<OUT> | DSLMethodOpts<OUT>, ): OUT | undefined { return this.optionInternal(actionORMethodDef, 9); } OR<T>( this: MixedInParser, altsOrOpts: IOrAlt<any>[] | OrMethodOpts<unknown>, ): T { return this.orInternal(altsOrOpts, 0); } OR1<T>( this: MixedInParser, altsOrOpts: IOrAlt<any>[] | OrMethodOpts<unknown>, ): T { return this.orInternal(altsOrOpts, 1); } OR2<T>( this: MixedInParser, altsOrOpts: IOrAlt<any>[] | OrMethodOpts<unknown>, ): T { return this.orInternal(altsOrOpts, 2); } OR3<T>( this: MixedInParser, altsOrOpts: IOrAlt<any>[] | OrMethodOpts<unknown>, ): T { return this.orInternal(altsOrOpts, 3); } OR4<T>( this: MixedInParser, altsOrOpts: IOrAlt<any>[] | OrMethodOpts<unknown>, ): T { return this.orInternal(altsOrOpts, 4); } OR5<T>( this: MixedInParser, altsOrOpts: IOrAlt<any>[] | OrMethodOpts<unknown>, ): T { return this.orInternal(altsOrOpts, 5); } OR6<T>( this: MixedInParser, altsOrOpts: IOrAlt<any>[] | OrMethodOpts<unknown>, ): T { return this.orInternal(altsOrOpts, 6); } OR7<T>( this: MixedInParser, altsOrOpts: IOrAlt<any>[] | OrMethodOpts<unknown>, ): T { return this.orInternal(altsOrOpts, 7); } OR8<T>( this: MixedInParser, altsOrOpts: IOrAlt<any>[] | OrMethodOpts<unknown>, ): T { return this.orInternal(altsOrOpts, 8); } OR9<T>( this: MixedInParser, altsOrOpts: IOrAlt<any>[] | OrMethodOpts<unknown>, ): T { return this.orInternal(altsOrOpts, 9); } MANY<OUT>( this: MixedInParser, actionORMethodDef: GrammarAction<OUT> | DSLMethodOpts<OUT>, ): void { this.manyInternal(0, actionORMethodDef); } MANY1<OUT>( this: MixedInParser, actionORMethodDef: GrammarAction<OUT> | DSLMethodOpts<OUT>, ): void { this.manyInternal(1, actionORMethodDef); } MANY2<OUT>( this: MixedInParser, actionORMethodDef: GrammarAction<OUT> | DSLMethodOpts<OUT>, ): void { this.manyInternal(2, actionORMethodDef); } MANY3<OUT>( this: MixedInParser, actionORMethodDef: GrammarAction<OUT> | DSLMethodOpts<OUT>, ): void { this.manyInternal(3, actionORMethodDef); } MANY4<OUT>( this: MixedInParser, actionORMethodDef: GrammarAction<OUT> | DSLMethodOpts<OUT>, ): void { this.manyInternal(4, actionORMethodDef); } MANY5<OUT>( this: MixedInParser, actionORMethodDef: GrammarAction<OUT> | DSLMethodOpts<OUT>, ): void { this.manyInternal(5, actionORMethodDef); } MANY6<OUT>( this: MixedInParser, actionORMethodDef: GrammarAction<OUT> | DSLMethodOpts<OUT>, ): void { this.manyInternal(6, actionORMethodDef); } MANY7<OUT>( this: MixedInParser, actionORMethodDef: GrammarAction<OUT> | DSLMethodOpts<OUT>, ): void { this.manyInternal(7, actionORMethodDef); } MANY8<OUT>( this: MixedInParser, actionORMethodDef: GrammarAction<OUT> | DSLMethodOpts<OUT>, ): void { this.manyInternal(8, actionORMethodDef); } MANY9<OUT>( this: MixedInParser, actionORMethodDef: GrammarAction<OUT> | DSLMethodOpts<OUT>, ): void { this.manyInternal(9, actionORMethodDef); } MANY_SEP<OUT>(this: MixedInParser, options: ManySepMethodOpts<OUT>): void { this.manySepFirstInternal(0, options); } MANY_SEP1<OUT>(this: MixedInParser, options: ManySepMethodOpts<OUT>): void { this.manySepFirstInternal(1, options); } MANY_SEP2<OUT>(this: MixedInParser, options: ManySepMethodOpts<OUT>): void { this.manySepFirstInternal(2, options); } MANY_SEP3<OUT>(this: MixedInParser, options: ManySepMethodOpts<OUT>): void { this.manySepFirstInternal(3, options); } MANY_SEP4<OUT>(this: MixedInParser, options: ManySepMethodOpts<OUT>): void { this.manySepFirstInternal(4, options); } MANY_SEP5<OUT>(this: MixedInParser, options: ManySepMethodOpts<OUT>): void { this.manySepFirstInternal(5, options); } MANY_SEP6<OUT>(this: MixedInParser, options: ManySepMethodOpts<OUT>): void { this.manySepFirstInternal(6, options); } MANY_SEP7<OUT>(this: MixedInParser, options: ManySepMethodOpts<OUT>): void { this.manySepFirstInternal(7, options); } MANY_SEP8<OUT>(this: MixedInParser, options: ManySepMethodOpts<OUT>): void { this.manySepFirstInternal(8, options); } MANY_SEP9<OUT>(this: MixedInParser, options: ManySepMethodOpts<OUT>): void { this.manySepFirstInternal(9, options); } AT_LEAST_ONE<OUT>( this: MixedInParser, actionORMethodDef: GrammarAction<OUT> | DSLMethodOptsWithErr<OUT>, ): void { this.atLeastOneInternal(0, actionORMethodDef); } AT_LEAST_ONE1<OUT>( this: MixedInParser, actionORMethodDef: GrammarAction<OUT> | DSLMethodOptsWithErr<OUT>, ): void { return this.atLeastOneInternal(1, actionORMethodDef); } AT_LEAST_ONE2<OUT>( this: MixedInParser, actionORMethodDef: GrammarAction<OUT> | DSLMethodOptsWithErr<OUT>, ): void { this.atLeastOneInternal(2, actionORMethodDef); } AT_LEAST_ONE3<OUT>( this: MixedInParser, actionORMethodDef: GrammarAction<OUT> | DSLMethodOptsWithErr<OUT>, ): void { this.atLeastOneInternal(3, actionORMethodDef); } AT_LEAST_ONE4<OUT>( this: MixedInParser, actionORMethodDef: GrammarAction<OUT> | DSLMethodOptsWithErr<OUT>, ): void { this.atLeastOneInternal(4, actionORMethodDef); } AT_LEAST_ONE5<OUT>( this: MixedInParser, actionORMethodDef: GrammarAction<OUT> | DSLMethodOptsWithErr<OUT>, ): void { this.atLeastOneInternal(5, actionORMethodDef); } AT_LEAST_ONE6<OUT>( this: MixedInParser, actionORMethodDef: GrammarAction<OUT> | DSLMethodOptsWithErr<OUT>, ): void { this.atLeastOneInternal(6, actionORMethodDef); } AT_LEAST_ONE7<OUT>( this: MixedInParser, actionORMethodDef: GrammarAction<OUT> | DSLMethodOptsWithErr<OUT>, ): void { this.atLeastOneInternal(7, actionORMethodDef); } AT_LEAST_ONE8<OUT>( this: MixedInParser, actionORMethodDef: GrammarAction<OUT> | DSLMethodOptsWithErr<OUT>, ): void { this.atLeastOneInternal(8, actionORMethodDef); } AT_LEAST_ONE9<OUT>( this: MixedInParser, actionORMethodDef: GrammarAction<OUT> | DSLMethodOptsWithErr<OUT>, ): void { this.atLeastOneInternal(9, actionORMethodDef); } AT_LEAST_ONE_SEP<OUT>( this: MixedInParser, options: AtLeastOneSepMethodOpts<OUT>, ): void { this.atLeastOneSepFirstInternal(0, options); } AT_LEAST_ONE_SEP1<OUT>( this: MixedInParser, options: AtLeastOneSepMethodOpts<OUT>, ): void { this.atLeastOneSepFirstInternal(1, options); } AT_LEAST_ONE_SEP2<OUT>( this: MixedInParser, options: AtLeastOneSepMethodOpts<OUT>, ): void { this.atLeastOneSepFirstInternal(2, options); } AT_LEAST_ONE_SEP3<OUT>( this: MixedInParser, options: AtLeastOneSepMethodOpts<OUT>, ): void { this.atLeastOneSepFirstInternal(3, options); } AT_LEAST_ONE_SEP4<OUT>( this: MixedInParser, options: AtLeastOneSepMethodOpts<OUT>, ): void { this.atLeastOneSepFirstInternal(4, options); } AT_LEAST_ONE_SEP5<OUT>( this: MixedInParser, options: AtLeastOneSepMethodOpts<OUT>, ): void { this.atLeastOneSepFirstInternal(5, options); } AT_LEAST_ONE_SEP6<OUT>( this: MixedInParser, options: AtLeastOneSepMethodOpts<OUT>, ): void { this.atLeastOneSepFirstInternal(6, options); } AT_LEAST_ONE_SEP7<OUT>( this: MixedInParser, options: AtLeastOneSepMethodOpts<OUT>, ): void { this.atLeastOneSepFirstInternal(7, options); } AT_LEAST_ONE_SEP8<OUT>( this: MixedInParser, options: AtLeastOneSepMethodOpts<OUT>, ): void { this.atLeastOneSepFirstInternal(8, options); } AT_LEAST_ONE_SEP9<OUT>( this: MixedInParser, options: AtLeastOneSepMethodOpts<OUT>, ): void { this.atLeastOneSepFirstInternal(9, options); } RULE<T>( this: MixedInParser, name: string, implementation: (...implArgs: any[]) => T, config: IRuleConfig<T> = DEFAULT_RULE_CONFIG, ): (idxInCallingRule?: number, ...args: any[]) => T | any { if (includes(this.definedRulesNames, name)) { const errMsg = defaultGrammarValidatorErrorProvider.buildDuplicateRuleNameError({ topLevelRule: name, grammarName: this.className, }); const error = { message: errMsg, type: ParserDefinitionErrorType.DUPLICATE_RULE_NAME, ruleName: name, }; this.definitionErrors.push(error); } this.definedRulesNames.push(name); const ruleImplementation = this.defineRule(name, implementation, config); (this as any)[name] = ruleImplementation; return ruleImplementation; } OVERRIDE_RULE<T>( this: MixedInParser, name: string, impl: (...implArgs: any[]) => T, config: IRuleConfig<T> = DEFAULT_RULE_CONFIG, ): (idxInCallingRule?: number, ...args: any[]) => T { const ruleErrors: IParserDefinitionError[] = validateRuleIsOverridden( name, this.definedRulesNames, this.className, ); this.definitionErrors = this.definitionErrors.concat(ruleErrors); const ruleImplementation = this.defineRule(name, impl, config); (this as any)[name] = ruleImplementation; return ruleImplementation; } BACKTRACK<T>( this: MixedInParser, grammarRule: (...args: any[]) => T, args?: any[], ): () => boolean { return function () { // save org state this.isBackTrackingStack.push(1); const orgState = this.saveRecogState(); try { grammarRule.apply(this, args); // if no exception was thrown we have succeed parsing the rule. return true; } catch (e) { if (isRecognitionException(e)) { return false; } else { throw e; } } finally { this.reloadRecogState(orgState); this.isBackTrackingStack.pop(); } }; } // GAST export APIs public getGAstProductions(this: MixedInParser): Record<string, Rule> { return this.gastProductionsCache; } public getSerializedGastProductions(this: MixedInParser): ISerializedGast[] { return serializeGrammar(values(this.gastProductionsCache)); } }