完成世界书、骰子、apiconfig页面处理

This commit is contained in:
2026-04-30 01:35:10 +08:00
parent a3e3711b2b
commit ba9b925c32
4602 changed files with 785225 additions and 23 deletions

View File

@@ -0,0 +1 @@
{"version":3,"file":"async-parser.js","sourceRoot":"","sources":["../../src/parser/async-parser.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1 @@
{"version":3,"file":"completion-parser-builder.js","sourceRoot":"","sources":["../../src/parser/completion-parser-builder.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAGhF,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAExD,MAAM,UAAU,sBAAsB,CAAC,QAA6B;IAChE,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;IACjC,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC;IACpC,MAAM,MAAM,GAAG,IAAI,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IACrD,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IAChD,MAAM,CAAC,QAAQ,EAAE,CAAC;IAClB,OAAO,MAAM,CAAC;AAClB,CAAC"}

View File

@@ -0,0 +1 @@
{"version":3,"file":"cst-node-builder.d.ts","sourceRoot":"","sources":["../../src/parser/cst-node-builder.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,183 @@
/******************************************************************************
* Copyright 2024 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 type { CustomPatternMatcherFunc, TokenType, IToken, TokenVocabulary } from 'chevrotain';
import type { Grammar, TerminalRule } from '../languages/generated/ast.js';
import type { LexingReport, TokenBuilderOptions } from './token-builder.js';
import type { LexerResult, TokenizeOptions } from './lexer.js';
import type { LangiumCoreServices } from '../services.js';
import { DefaultTokenBuilder } from './token-builder.js';
import { DefaultLexer } from './lexer.js';
type IndentationAwareDelimiter<TokenName extends string> = [begin: TokenName, end: TokenName];
export interface IndentationTokenBuilderOptions<TerminalName extends string = string, KeywordName extends string = string> {
/**
* The name of the token used to denote indentation in the grammar.
* A possible definition in the grammar could look like this:
* ```langium
* terminal INDENT: ':synthetic-indent:';
* ```
*
* @default 'INDENT'
*/
indentTokenName: TerminalName;
/**
* The name of the token used to denote deindentation in the grammar.
* A possible definition in the grammar could look like this:
* ```langium
* terminal DEDENT: ':synthetic-dedent:';
* ```
*
* @default 'DEDENT'
*/
dedentTokenName: TerminalName;
/**
* The name of the token used to denote whitespace other than indentation and newlines in the grammar.
* A possible definition in the grammar could look like this:
* ```langium
* hidden terminal WS: /[ \t]+/;
* ```
*
* @default 'WS'
*/
whitespaceTokenName: TerminalName;
/**
* The delimiter tokens inside of which indentation should be ignored and treated as normal whitespace.
* For example, Python doesn't treat any whitespace between `(` and `)` as significant.
*
* Can be either terminal tokens or keyword tokens.
*
* @default []
*/
ignoreIndentationDelimiters: Array<IndentationAwareDelimiter<TerminalName | KeywordName>>;
}
export declare const indentationBuilderDefaultOptions: IndentationTokenBuilderOptions;
export declare enum LexingMode {
REGULAR = "indentation-sensitive",
IGNORE_INDENTATION = "ignore-indentation"
}
export interface IndentationLexingReport extends LexingReport {
/** Dedent tokens that are necessary to close the remaining indents. */
remainingDedents: IToken[];
}
/**
* A token builder that is sensitive to indentation in the input text.
* It will generate tokens for indentation and dedentation based on the indentation level.
*
* The first generic parameter corresponds to the names of terminal tokens,
* while the second one corresponds to the names of keyword tokens.
* Both parameters are optional and can be imported from `./generated/ast.js`.
*
* Inspired by https://github.com/chevrotain/chevrotain/blob/master/examples/lexer/python_indentation/python_indentation.js
*/
export declare class IndentationAwareTokenBuilder<Terminals extends string = string, KeywordName extends string = string> extends DefaultTokenBuilder {
/**
* The stack stores all the previously matched indentation levels to understand how deeply the next tokens are nested.
* The stack is valid for lexing
*/
protected indentationStack: number[];
readonly options: IndentationTokenBuilderOptions<Terminals, KeywordName>;
/**
* The token type to be used for indentation tokens
*/
readonly indentTokenType: TokenType;
/**
* The token type to be used for dedentation tokens
*/
readonly dedentTokenType: TokenType;
/**
* A regular expression to match a series of tabs and/or spaces.
* Override this to customize what the indentation is allowed to consist of.
*/
protected whitespaceRegExp: RegExp;
constructor(options?: Partial<IndentationTokenBuilderOptions<NoInfer<Terminals>, NoInfer<KeywordName>>>);
buildTokens(grammar: Grammar, options?: TokenBuilderOptions | undefined): TokenVocabulary;
flushLexingReport(text: string): IndentationLexingReport;
/**
* Helper function to check if the current position is the start of a new line.
*
* @param text The full input string.
* @param offset The current position at which to check
* @returns Whether the current position is the start of a new line
*/
protected isStartOfLine(text: string, offset: number): boolean;
/**
* A helper function used in matching both indents and dedents.
*
* @param text The full input string.
* @param offset The current position at which to attempt a match
* @param tokens Previously scanned tokens
* @param groups Token Groups
* @returns The current and previous indentation levels and the matched whitespace
*/
protected matchWhitespace(text: string, offset: number, tokens: IToken[], groups: Record<string, IToken[]>): {
currIndentLevel: number;
prevIndentLevel: number;
match: RegExpExecArray | null;
};
/**
* Helper function to create an instance of an indentation token.
*
* @param tokenType Indent or dedent token type
* @param text Full input string, used to calculate the line number
* @param image The original image of the token (tabs or spaces)
* @param offset Current position in the input string
* @returns The indentation token instance
*/
protected createIndentationTokenInstance(tokenType: TokenType, text: string, image: string, offset: number): IToken;
/**
* Helper function to get the line number at a given offset.
*
* @param text Full input string, used to calculate the line number
* @param offset Current position in the input string
* @returns The line number at the given offset
*/
protected getLineNumber(text: string, offset: number): number;
/**
* A custom pattern for matching indents
*
* @param text The full input string.
* @param offset The offset at which to attempt a match
* @param tokens Previously scanned tokens
* @param groups Token Groups
*/
protected indentMatcher(text: string, offset: number, tokens: IToken[], groups: Record<string, IToken[]>): ReturnType<CustomPatternMatcherFunc>;
/**
* A custom pattern for matching dedents
*
* @param text The full input string.
* @param offset The offset at which to attempt a match
* @param tokens Previously scanned tokens
* @param groups Token Groups
*/
protected dedentMatcher(text: string, offset: number, tokens: IToken[], groups: Record<string, IToken[]>): ReturnType<CustomPatternMatcherFunc>;
protected buildTerminalToken(terminal: TerminalRule): TokenType;
/**
* Resets the indentation stack between different runs of the lexer
*
* @param text Full text that was tokenized
* @returns Remaining dedent tokens to match all previous indents at the end of the file
*/
flushRemainingDedents(text: string): IToken[];
}
/**
* A lexer that is aware of indentation in the input text.
* The only purpose of this lexer is to reset the internal state of the {@link IndentationAwareTokenBuilder}
* between the tokenization of different text inputs.
*
* In your module, you can override the default lexer with this one as such:
* ```ts
* parser: {
* TokenBuilder: () => new IndentationAwareTokenBuilder(),
* Lexer: (services) => new IndentationAwareLexer(services),
* }
* ```
*/
export declare class IndentationAwareLexer extends DefaultLexer {
protected readonly indentationTokenBuilder: IndentationAwareTokenBuilder;
constructor(services: LangiumCoreServices);
tokenize(text: string, options?: TokenizeOptions): LexerResult;
}
export {};
//# sourceMappingURL=indentation-aware.d.ts.map

17
frontend/node_modules/langium/lib/parser/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,17 @@
/******************************************************************************
* Copyright 2023 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 * from './async-parser.js';
export * from './completion-parser-builder.js';
export * from './cst-node-builder.js';
export * from './indentation-aware.js';
export * from './langium-parser-builder.js';
export * from './langium-parser.js';
export * from './lexer.js';
export * from './parser-builder-base.js';
export * from './parser-config.js';
export * from './token-builder.js';
export * from './value-converter.js';
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"parser-builder-base.d.ts","sourceRoot":"","sources":["../../src/parser/parser-builder-base.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,KAAK,EAAqB,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACzE,OAAO,KAAK,EAAgF,OAAO,EAAkF,MAAM,+BAA+B,CAAC;AAC3N,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AA+BtD,wBAAgB,YAAY,CAAC,CAAC,SAAS,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,mBAAmB,GAAG,CAAC,CAQ9G"}

View File

@@ -0,0 +1,474 @@
/******************************************************************************
* 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 { EMPTY_ALT, EOF } from 'chevrotain';
import { isAction, isAlternatives, isEndOfFile, isAssignment, isConjunction, isCrossReference, isDisjunction, isGroup, isKeyword, isNegation, isParameterReference, isParserRule, isRuleCall, isTerminalRule, isUnorderedGroup, isBooleanLiteral, isInfixRule, isAbstractParserRule } from '../languages/generated/ast.js';
import { assertUnreachable, ErrorWithLocation } from '../utils/errors.js';
import { stream } from '../utils/stream.js';
import { findNameAssignment, getAllReachableRules, getTypeName } from '../utils/grammar-utils.js';
export function createParser(grammar, parser, tokens) {
const parserContext = {
parser,
tokens,
ruleNames: new Map()
};
buildRules(parserContext, grammar);
return parser;
}
function buildRules(parserContext, grammar) {
const reachable = getAllReachableRules(grammar, false);
const parserRules = stream(grammar.rules).filter(isParserRule).filter(rule => reachable.has(rule));
for (const rule of parserRules) {
const ctx = {
...parserContext,
consume: 1,
optional: 1,
subrule: 1,
many: 1,
or: 1
};
parserContext.parser.rule(rule, buildElement(ctx, rule.definition));
}
const infixRules = stream(grammar.rules).filter(isInfixRule).filter(rule => reachable.has(rule));
for (const rule of infixRules) {
parserContext.parser.rule(rule, buildInfixRule(parserContext, rule));
}
}
function buildInfixRule(ctx, rule) {
const expressionRule = rule.call.rule.ref;
if (!expressionRule) {
throw new Error('Could not resolve reference to infix operator rule: ' + rule.call.rule.$refText);
}
if (isTerminalRule(expressionRule)) {
throw new Error('Cannot use terminal rule in infix expression');
}
// We need to construct a bunch of synthetic grammar AST nodes here
// This ensures that the CST and completion engine get populated as expected
const allKeywords = rule.operators.precedences.flatMap(e => e.operators);
// The outer group represents the first expression call and the whole (optional) loop
const outerGroup = {
$type: 'Group',
elements: []
};
const part1Assignment = {
$container: outerGroup,
$type: 'Assignment',
feature: 'parts',
operator: '+=',
terminal: rule.call
};
// The inner group represents the loop that contains the operator and expression call
// It can be infinitely repeated
const innerGroup = {
$container: outerGroup,
$type: 'Group',
elements: [],
cardinality: '*'
};
outerGroup.elements.push(part1Assignment, innerGroup);
// Store all operator keywords in one alternative/assignment
const alternatives = {
$type: 'Alternatives',
elements: allKeywords
};
const operatorAssignment = {
$container: innerGroup,
$type: 'Assignment',
feature: 'operators',
operator: '+=',
terminal: alternatives
};
// We need a second assignment of the called expression here
const part2Assignment = {
...part1Assignment,
$container: innerGroup
};
innerGroup.elements.push(operatorAssignment, part2Assignment);
const tokens = allKeywords.map(e => ctx.tokens[e.value]);
const orAlts = tokens.map((token, index) => ({
ALT: () => ctx.parser.consume(index, token, operatorAssignment)
}));
let subrule;
return (args) => {
subrule ?? (subrule = getRule(ctx, expressionRule));
ctx.parser.subrule(0, subrule, false, part1Assignment, args);
ctx.parser.many(0, {
DEF: () => {
ctx.parser.alternatives(0, orAlts);
ctx.parser.subrule(1, subrule, false, part2Assignment, args);
}
});
};
}
function buildElement(ctx, element, ignoreGuard = false) {
let method;
if (isKeyword(element)) {
method = buildKeyword(ctx, element);
}
else if (isAction(element)) {
method = buildAction(ctx, element);
}
else if (isAssignment(element)) {
method = buildElement(ctx, element.terminal);
}
else if (isCrossReference(element)) {
method = buildCrossReference(ctx, element);
}
else if (isRuleCall(element)) {
method = buildRuleCall(ctx, element);
}
else if (isAlternatives(element)) {
method = buildAlternatives(ctx, element);
}
else if (isUnorderedGroup(element)) {
method = buildUnorderedGroup(ctx, element);
}
else if (isGroup(element)) {
method = buildGroup(ctx, element);
}
else if (isEndOfFile(element)) {
const idx = ctx.consume++;
method = () => ctx.parser.consume(idx, EOF, element);
}
else {
throw new ErrorWithLocation(element.$cstNode, `Unexpected element type: ${element.$type}`);
}
return wrap(ctx, ignoreGuard ? undefined : getGuardCondition(element), method, element.cardinality);
}
function buildAction(ctx, action) {
const actionType = getTypeName(action);
return () => ctx.parser.action(actionType, action);
}
function buildRuleCall(ctx, ruleCall) {
const rule = ruleCall.rule.ref;
if (isAbstractParserRule(rule)) {
const idx = ctx.subrule++;
const fragment = isParserRule(rule) && rule.fragment;
const predicate = ruleCall.arguments.length > 0 ? buildRuleCallPredicate(rule, ruleCall.arguments) : () => ({});
let subrule;
return (args) => {
subrule ?? (subrule = getRule(ctx, rule));
ctx.parser.subrule(idx, subrule, fragment, ruleCall, predicate(args));
};
}
else if (isTerminalRule(rule)) {
const idx = ctx.consume++;
const method = getToken(ctx, rule.name);
return () => ctx.parser.consume(idx, method, ruleCall);
}
else if (!rule) {
throw new ErrorWithLocation(ruleCall.$cstNode, `Undefined rule: ${ruleCall.rule.$refText}`);
}
else {
assertUnreachable(rule);
}
}
function buildRuleCallPredicate(rule, namedArgs) {
const hasNamedArguments = namedArgs.some(arg => arg.calledByName);
if (hasNamedArguments) {
const namedPredicates = namedArgs.map(arg => ({
parameterName: arg.parameter?.ref?.name,
predicate: buildPredicate(arg.value)
}));
return (args) => {
const ruleArgs = {};
for (const { parameterName, predicate } of namedPredicates) {
if (parameterName) {
ruleArgs[parameterName] = predicate(args);
}
}
return ruleArgs;
};
}
else {
const predicates = namedArgs.map(arg => buildPredicate(arg.value));
return (args) => {
const ruleArgs = {};
for (let i = 0; i < predicates.length; i++) {
if (i < rule.parameters.length) {
const parameterName = rule.parameters[i].name;
const predicate = predicates[i];
ruleArgs[parameterName] = predicate(args);
}
}
return ruleArgs;
};
}
}
function buildPredicate(condition) {
if (isDisjunction(condition)) {
const left = buildPredicate(condition.left);
const right = buildPredicate(condition.right);
return (args) => (left(args) || right(args));
}
else if (isConjunction(condition)) {
const left = buildPredicate(condition.left);
const right = buildPredicate(condition.right);
return (args) => (left(args) && right(args));
}
else if (isNegation(condition)) {
const value = buildPredicate(condition.value);
return (args) => !value(args);
}
else if (isParameterReference(condition)) {
const name = condition.parameter.ref.name;
return (args) => args !== undefined && args[name] === true;
}
else if (isBooleanLiteral(condition)) {
const value = Boolean(condition.true);
return () => value;
}
assertUnreachable(condition);
}
function buildAlternatives(ctx, alternatives) {
if (alternatives.elements.length === 1) {
return buildElement(ctx, alternatives.elements[0]);
}
else {
const methods = [];
for (const element of alternatives.elements) {
const predicatedMethod = {
// Since we handle the guard condition in the alternative already
// We can ignore the group guard condition inside
ALT: buildElement(ctx, element, true)
};
const guard = getGuardCondition(element);
if (guard) {
predicatedMethod.GATE = buildPredicate(guard);
}
methods.push(predicatedMethod);
}
const idx = ctx.or++;
return (args) => ctx.parser.alternatives(idx, methods.map(method => {
const alt = {
ALT: () => method.ALT(args)
};
const gate = method.GATE;
if (gate) {
alt.GATE = () => gate(args);
}
return alt;
}));
}
}
function buildUnorderedGroup(ctx, group) {
if (group.elements.length === 1) {
return buildElement(ctx, group.elements[0]);
}
const methods = [];
for (const element of group.elements) {
const predicatedMethod = {
// Since we handle the guard condition in the alternative already
// We can ignore the group guard condition inside
ALT: buildElement(ctx, element, true)
};
const guard = getGuardCondition(element);
if (guard) {
predicatedMethod.GATE = buildPredicate(guard);
}
methods.push(predicatedMethod);
}
const orIdx = ctx.or++;
const idFunc = (groupIdx, lParser) => {
const stackId = lParser.getRuleStack().join('-');
return `uGroup_${groupIdx}_${stackId}`;
};
const alternatives = (args) => ctx.parser.alternatives(orIdx, methods.map((method, idx) => {
const alt = { ALT: () => true };
const parser = ctx.parser;
alt.ALT = () => {
method.ALT(args);
if (!parser.isRecording()) {
const key = idFunc(orIdx, parser);
if (!parser.unorderedGroups.get(key)) {
// init after clear state
parser.unorderedGroups.set(key, []);
}
const groupState = parser.unorderedGroups.get(key);
if (typeof groupState?.[idx] === 'undefined') {
// Not accessed yet
groupState[idx] = true;
}
}
};
const gate = method.GATE;
if (gate) {
alt.GATE = () => gate(args);
}
else {
alt.GATE = () => {
const trackedAlternatives = parser.unorderedGroups.get(idFunc(orIdx, parser));
const allow = !trackedAlternatives?.[idx];
return allow;
};
}
return alt;
}));
const wrapped = wrap(ctx, getGuardCondition(group), alternatives, '*');
return (args) => {
wrapped(args);
if (!ctx.parser.isRecording()) {
ctx.parser.unorderedGroups.delete(idFunc(orIdx, ctx.parser));
}
};
}
function buildGroup(ctx, group) {
const methods = group.elements.map(e => buildElement(ctx, e));
return (args) => methods.forEach(method => method(args));
}
function getGuardCondition(element) {
if (isGroup(element)) {
return element.guardCondition;
}
return undefined;
}
function buildCrossReference(ctx, crossRef, terminal = crossRef.terminal) {
if (!terminal) {
if (!crossRef.type.ref) {
throw new Error('Could not resolve reference to type: ' + crossRef.type.$refText);
}
const assignment = findNameAssignment(crossRef.type.ref);
const assignTerminal = assignment?.terminal;
if (!assignTerminal) {
throw new Error('Could not find name assignment for type: ' + getTypeName(crossRef.type.ref));
}
return buildCrossReference(ctx, crossRef, assignTerminal);
}
else if (isRuleCall(terminal) && isParserRule(terminal.rule.ref)) {
// The terminal is a data type rule here. Everything else will result in a validation error.
const rule = terminal.rule.ref;
const idx = ctx.subrule++;
let subrule;
return (args) => {
subrule ?? (subrule = getRule(ctx, rule));
ctx.parser.subrule(idx, subrule, false, crossRef, args);
};
}
else if (isRuleCall(terminal) && isTerminalRule(terminal.rule.ref)) {
const idx = ctx.consume++;
const terminalRule = getToken(ctx, terminal.rule.ref.name);
return () => ctx.parser.consume(idx, terminalRule, crossRef);
}
else if (isKeyword(terminal)) {
const idx = ctx.consume++;
const keyword = getToken(ctx, terminal.value);
return () => ctx.parser.consume(idx, keyword, crossRef);
}
else {
throw new Error('Could not build cross reference parser');
}
}
function buildKeyword(ctx, keyword) {
const idx = ctx.consume++;
const token = ctx.tokens[keyword.value];
if (!token) {
throw new Error('Could not find token for keyword: ' + keyword.value);
}
return () => ctx.parser.consume(idx, token, keyword);
}
function wrap(ctx, guard, method, cardinality) {
const gate = guard && buildPredicate(guard);
if (!cardinality) {
if (gate) {
const idx = ctx.or++;
return (args) => ctx.parser.alternatives(idx, [
{
ALT: () => method(args),
GATE: () => gate(args)
},
{
ALT: EMPTY_ALT(),
GATE: () => !gate(args)
}
]);
}
else {
return method;
}
}
if (cardinality === '*') {
const idx = ctx.many++;
return (args) => ctx.parser.many(idx, {
DEF: () => method(args),
GATE: gate ? () => gate(args) : undefined
});
}
else if (cardinality === '+') {
const idx = ctx.many++;
if (gate) {
const orIdx = ctx.or++;
// In the case of a guard condition for the `+` group
// We combine it with an empty alternative
// If the condition returns true, it needs to parse at least a single iteration
// If its false, it is not allowed to parse anything
return (args) => ctx.parser.alternatives(orIdx, [
{
ALT: () => ctx.parser.atLeastOne(idx, {
DEF: () => method(args)
}),
GATE: () => gate(args)
},
{
ALT: EMPTY_ALT(),
GATE: () => !gate(args)
}
]);
}
else {
return (args) => ctx.parser.atLeastOne(idx, {
DEF: () => method(args),
});
}
}
else if (cardinality === '?') {
const idx = ctx.optional++;
return (args) => ctx.parser.optional(idx, {
DEF: () => method(args),
GATE: gate ? () => gate(args) : undefined
});
}
else {
assertUnreachable(cardinality);
}
}
function getRule(ctx, element) {
const name = getRuleName(ctx, element);
const rule = ctx.parser.getRule(name);
if (!rule)
throw new Error(`Rule "${name}" not found."`);
return rule;
}
function getRuleName(ctx, element) {
if (isAbstractParserRule(element)) {
return element.name;
}
else if (ctx.ruleNames.has(element)) {
return ctx.ruleNames.get(element);
}
else {
let item = element;
let parent = item.$container;
let ruleName = element.$type;
while (!isParserRule(parent)) {
if (isGroup(parent) || isAlternatives(parent) || isUnorderedGroup(parent)) {
const index = parent.elements.indexOf(item);
ruleName = index.toString() + ':' + ruleName;
}
item = parent;
parent = parent.$container;
}
const rule = parent;
ruleName = rule.name + ':' + ruleName;
ctx.ruleNames.set(element, ruleName);
return ruleName;
}
}
function getToken(ctx, name) {
const token = ctx.tokens[name];
if (!token)
throw new Error(`Token "${name}" not found."`);
return token;
}
//# sourceMappingURL=parser-builder-base.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"token-builder.d.ts","sourceRoot":"","sources":["../../src/parser/token-builder.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,KAAK,EAAE,wBAAwB,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AACnH,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAClG,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAQjD,MAAM,WAAW,mBAAmB;IAChC,eAAe,CAAC,EAAE,OAAO,CAAA;CAC5B;AAED,MAAM,WAAW,YAAY;IACzB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,eAAe,CAAC;IAC9E;;;;OAIG;IACH,iBAAiB,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAAC;CAClD;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IACzB,WAAW,EAAE,gBAAgB,EAAE,CAAC;CACnC;AAED,MAAM,MAAM,wBAAwB,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;AAE7E,MAAM,WAAW,gBAAiB,SAAQ,YAAY;IAClD,QAAQ,CAAC,EAAE,wBAAwB,CAAC;CACvC;AAED,qBAAa,mBAAoB,YAAW,YAAY;IACpD;;OAEG;IACH,SAAS,CAAC,WAAW,EAAE,gBAAgB,EAAE,CAAM;IAE/C,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,eAAe;IAe7E,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY;IAI7C,SAAS,CAAC,cAAc,IAAI,gBAAgB,EAAE;IAM9C,SAAS,CAAC,mBAAmB,CAAC,KAAK,EAAE,MAAM,CAAC,YAAY,CAAC,GAAG,SAAS,EAAE;IAKvE,SAAS,CAAC,kBAAkB,CAAC,QAAQ,EAAE,YAAY,GAAG,SAAS;IAiB/D,SAAS,CAAC,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IASvD,SAAS,CAAC,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,wBAAwB;IASvE,SAAS,CAAC,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,YAAY,CAAC,EAAE,cAAc,EAAE,SAAS,EAAE,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,SAAS,EAAE;IAWlI,SAAS,CAAC,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,EAAE,eAAe,EAAE,OAAO,GAAG,SAAS;IAe/G,SAAS,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,GAAG,YAAY;IAMvF,SAAS,CAAC,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,GAAG,SAAS,EAAE;CAStF"}

View File

@@ -0,0 +1,114 @@
/******************************************************************************
* Copyright 2021 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 { Lexer } from 'chevrotain';
import { isAbstractParserRule, isKeyword, isTerminalRule } from '../languages/generated/ast.js';
import { streamAllContents } from '../utils/ast-utils.js';
import { getAllReachableRules, terminalRegex } from '../utils/grammar-utils.js';
import { escapeRegExp, isWhitespace, partialMatches } from '../utils/regexp-utils.js';
import { stream } from '../utils/stream.js';
export class DefaultTokenBuilder {
constructor() {
/**
* The list of diagnostics stored during the lexing process of a single text.
*/
this.diagnostics = [];
}
buildTokens(grammar, options) {
const reachableRules = stream(getAllReachableRules(grammar, false));
const terminalTokens = this.buildTerminalTokens(reachableRules);
const tokens = this.buildKeywordTokens(reachableRules, terminalTokens, options);
// Add all terminals tokens to the end in the order they were defined
// Chevrotain documentation recommends to add Whitespace-like tokens at the start
// However, assuming the lexer is able to optimize the tokens, it should not matter
tokens.push(...terminalTokens);
// We don't need to add the EOF token explicitly.
// It is automatically available at the end of the token stream.
return tokens;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
flushLexingReport(text) {
return { diagnostics: this.popDiagnostics() };
}
popDiagnostics() {
const diagnostics = [...this.diagnostics];
this.diagnostics = [];
return diagnostics;
}
buildTerminalTokens(rules) {
return rules.filter(isTerminalRule).filter(e => !e.fragment)
.map(terminal => this.buildTerminalToken(terminal)).toArray();
}
buildTerminalToken(terminal) {
const regex = terminalRegex(terminal);
const pattern = this.requiresCustomPattern(regex) ? this.regexPatternFunction(regex) : regex;
const tokenType = {
name: terminal.name,
PATTERN: pattern,
};
if (typeof pattern === 'function') {
tokenType.LINE_BREAKS = true;
}
if (terminal.hidden) {
// Only skip tokens that are able to accept whitespace
tokenType.GROUP = isWhitespace(regex) ? Lexer.SKIPPED : 'hidden';
}
return tokenType;
}
requiresCustomPattern(regex) {
if (regex.flags.includes('u') || regex.flags.includes('s')) {
// Unicode and dotall regexes are not supported by Chevrotain.
return true;
}
else {
return false;
}
}
regexPatternFunction(regex) {
const stickyRegex = new RegExp(regex, regex.flags + 'y');
return (text, offset) => {
stickyRegex.lastIndex = offset;
const execResult = stickyRegex.exec(text);
return execResult;
};
}
buildKeywordTokens(rules, terminalTokens, options) {
return rules
// We filter by parser rules, since keywords in terminal rules get transformed into regex and are not actual tokens
.filter(isAbstractParserRule)
.flatMap(rule => streamAllContents(rule).filter(isKeyword))
.distinct(e => e.value).toArray()
// Sort keywords by descending length
.sort((a, b) => b.value.length - a.value.length)
.map(keyword => this.buildKeywordToken(keyword, terminalTokens, Boolean(options?.caseInsensitive)));
}
buildKeywordToken(keyword, terminalTokens, caseInsensitive) {
const keywordPattern = this.buildKeywordPattern(keyword, caseInsensitive);
const tokenType = {
name: keyword.value,
PATTERN: keywordPattern,
LONGER_ALT: this.findLongerAlt(keyword, terminalTokens)
};
if (typeof keywordPattern === 'function') {
tokenType.LINE_BREAKS = true;
}
return tokenType;
}
buildKeywordPattern(keyword, caseInsensitive) {
return caseInsensitive ?
new RegExp(escapeRegExp(keyword.value), 'i') :
keyword.value;
}
findLongerAlt(keyword, terminalTokens) {
return terminalTokens.reduce((longerAlts, token) => {
const pattern = token?.PATTERN;
if (pattern?.source && partialMatches('^' + pattern.source + '$', keyword.value)) {
longerAlts.push(token);
}
return longerAlts;
}, []);
}
}
//# sourceMappingURL=token-builder.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"token-builder.js","sourceRoot":"","sources":["../../src/parser/token-builder.ts"],"names":[],"mappings":"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"}