From 01a3ddef9773dfab6ac1858842274b4d033e71db Mon Sep 17 00:00:00 2001 From: Pluralia Date: Mon, 27 Sep 2021 14:35:58 +0200 Subject: [PATCH 1/6] Add the global maxLookahead with the service ParserConfig --- .../src/language-server/generated/module.ts | 7 +-- .../syntaxes/arithmetics.tmLanguage.json | 3 -- examples/domainmodel/langium-config.json | 7 +++ .../src/language-server/generated/module.ts | 15 +++++-- .../src/language-server/generated/module.ts | 7 +-- .../langium-cli/langium-config-schema.json | 44 +++++++++++++++++++ .../src/generator/module-generator.ts | 25 +++++++++-- packages/langium-cli/src/package.ts | 3 ++ .../langium/src/grammar/generated/module.ts | 6 ++- packages/langium/src/index.ts | 1 + packages/langium/src/parser/langium-parser.ts | 9 ++-- packages/langium/src/parser/parser-config.ts | 17 +++++++ packages/langium/src/services.ts | 3 +- 13 files changed, 126 insertions(+), 21 deletions(-) create mode 100644 packages/langium/src/parser/parser-config.ts diff --git a/examples/arithmetics/src/language-server/generated/module.ts b/examples/arithmetics/src/language-server/generated/module.ts index ec9a3cc14..f0bf585ef 100644 --- a/examples/arithmetics/src/language-server/generated/module.ts +++ b/examples/arithmetics/src/language-server/generated/module.ts @@ -3,11 +3,11 @@ * DO NOT EDIT MANUALLY! ******************************************************************************/ -import { LangiumGeneratedServices, LangiumServices, Module } from 'langium'; +import { LangiumGeneratedServices, LangiumServices, LanguageMetaData, Module, defaultParserConfig } from 'langium'; import { ArithmeticsAstReflection } from './ast'; import { grammar } from './grammar'; -export const languageMetaData = { +export const languageMetaData: LanguageMetaData = { languageId: 'arithmetics', fileExtensions: ['.calc'] }; @@ -15,5 +15,6 @@ export const languageMetaData = { export const ArithmeticsGeneratedModule: Module = { Grammar: () => grammar(), AstReflection: () => new ArithmeticsAstReflection(), - LanguageMetaData: () => languageMetaData + LanguageMetaData: () => languageMetaData, + ParserConfig: () => defaultParserConfig }; diff --git a/examples/arithmetics/syntaxes/arithmetics.tmLanguage.json b/examples/arithmetics/syntaxes/arithmetics.tmLanguage.json index 06b2df3ac..ef516753c 100644 --- a/examples/arithmetics/syntaxes/arithmetics.tmLanguage.json +++ b/examples/arithmetics/syntaxes/arithmetics.tmLanguage.json @@ -5,9 +5,6 @@ ".calc" ], "patterns": [ - { - "include": "#comments" - }, { "name": "keyword.control.arithmetics", "match": "\\b(def|module)\\b" diff --git a/examples/domainmodel/langium-config.json b/examples/domainmodel/langium-config.json index 71e57a6f9..dcab7cfdd 100644 --- a/examples/domainmodel/langium-config.json +++ b/examples/domainmodel/langium-config.json @@ -5,5 +5,12 @@ "out": "src/language-server/generated", "textMate": { "out": "syntaxes/domain-model.tmLanguage.json" + }, + "parserConfig": { + "chevrotainConfig": { + "recoveryEnabled": true, + "nodeLocationTracking": "onlyOffset", + "maxLookahead": 3 + } } } diff --git a/examples/domainmodel/src/language-server/generated/module.ts b/examples/domainmodel/src/language-server/generated/module.ts index eed83f55a..b785b7e24 100644 --- a/examples/domainmodel/src/language-server/generated/module.ts +++ b/examples/domainmodel/src/language-server/generated/module.ts @@ -3,17 +3,26 @@ * DO NOT EDIT MANUALLY! ******************************************************************************/ -import { LangiumGeneratedServices, LangiumServices, Module } from 'langium'; +import { LangiumGeneratedServices, LangiumServices, LanguageMetaData, Module, ParserConfig } from 'langium'; import { DomainModelAstReflection } from './ast'; import { grammar } from './grammar'; -export const languageMetaData = { +export const languageMetaData: LanguageMetaData = { languageId: 'domain-model', fileExtensions: ['.dmodel'] }; +export const parserConfig: ParserConfig = { + chevrotainConfig: { + recoveryEnabled: true, + nodeLocationTracking: 'onlyOffset', + maxLookahead: 4, + } +}; + export const DomainModelGeneratedModule: Module = { Grammar: () => grammar(), AstReflection: () => new DomainModelAstReflection(), - LanguageMetaData: () => languageMetaData + LanguageMetaData: () => languageMetaData, + ParserConfig: () => parserConfig }; diff --git a/examples/statemachine/src/language-server/generated/module.ts b/examples/statemachine/src/language-server/generated/module.ts index c73fa52a1..6bb525f7b 100644 --- a/examples/statemachine/src/language-server/generated/module.ts +++ b/examples/statemachine/src/language-server/generated/module.ts @@ -3,11 +3,11 @@ * DO NOT EDIT MANUALLY! ******************************************************************************/ -import { LangiumGeneratedServices, LangiumServices, Module } from 'langium'; +import { LangiumGeneratedServices, LangiumServices, LanguageMetaData, Module, defaultParserConfig } from 'langium'; import { StatemachineAstReflection } from './ast'; import { grammar } from './grammar'; -export const languageMetaData = { +export const languageMetaData: LanguageMetaData = { languageId: 'statemachine', fileExtensions: ['.statemachine'] }; @@ -15,5 +15,6 @@ export const languageMetaData = { export const StatemachineGeneratedModule: Module = { Grammar: () => grammar(), AstReflection: () => new StatemachineAstReflection(), - LanguageMetaData: () => languageMetaData + LanguageMetaData: () => languageMetaData, + ParserConfig: () => defaultParserConfig }; diff --git a/packages/langium-cli/langium-config-schema.json b/packages/langium-cli/langium-config-schema.json index 041c707fd..d7ca491a6 100644 --- a/packages/langium-cli/langium-config-schema.json +++ b/packages/langium-cli/langium-config-schema.json @@ -40,6 +40,50 @@ "out" ] }, + "parserConfig": { + "description": "An object to describe the parser configuration", + "type": "object", + "properties": { + "chevrotainConfig": { + "description": "An object to describe the Chevrotain parser configuration", + "type": "object", + "properties": { + "recoveryEnabled": { + "description": "Is the error recovery / fault tolerance of the Chevrotain Parser enabled", + "type": "boolean" + }, + "maxLookahead": { + "description": "Maximum number of tokens the parser will use to choose between alternatives", + "type": "number" + }, + "dynamicTokensEnabled": { + "description": "A flag to support Dynamically defined Tokens", + "type": "boolean" + }, + "nodeLocationTracking": { + "description": "Enable computation of CST nodes location", + "type": "string" + }, + "errorMessageProvider": { + "description": "A custom error message provider", + "type": "object" + }, + "traceInitPerf": { + "description": "A flag to print performance tracing logs during parser initialization", + "type": ["boolean", "number"] + }, + "skipValidations": { + "description": "A flag to avoid running the grammar validations during Parser initialization", + "type": "boolean" + } + }, + "required": [] + } + }, + "required": [ + "chevrotainConfig" + ] + }, "langiumInternal": { "description": "A flag to determine whether langium uses itself to bootstrap", "type": "boolean" diff --git a/packages/langium-cli/src/generator/module-generator.ts b/packages/langium-cli/src/generator/module-generator.ts index b1db5d3f3..c370c1897 100644 --- a/packages/langium-cli/src/generator/module-generator.ts +++ b/packages/langium-cli/src/generator/module-generator.ts @@ -13,29 +13,48 @@ export function generateModule(grammar: langium.Grammar, config: LangiumConfig): const node = new CompositeGeneratorNode(); node.append(generatedHeader); if (config.langiumInternal) { + node.append(`import { LanguageMetaData, ${config.parserConfig ? 'ParserConfig' : 'defaultParserConfig'} } from '../..';`, NL); node.append("import { Module } from '../../dependency-injection';", NL); node.contents.push("import { LangiumGeneratedServices, LangiumServices } from '../../services';", NL); } else { - node.append("import { LangiumGeneratedServices, LangiumServices, Module } from 'langium';", NL); + node.append(`import { LangiumGeneratedServices, LangiumServices, LanguageMetaData, Module, ${config.parserConfig ? 'ParserConfig' : 'defaultParserConfig'} } from 'langium';`, NL); } node.append( 'import { ', grammar.name, "AstReflection } from './ast';", NL, "import { grammar } from './grammar';", NL, NL ); - node.append('export const languageMetaData = {', NL); + node.append('export const languageMetaData: LanguageMetaData = {', NL); node.indent(metaData => { metaData.append(`languageId: '${config.languageId}',`, NL); metaData.append(`fileExtensions: [${config.fileExtensions && config.fileExtensions.map(e => appendQuotesAndDot(e)).join(', ')}]`, NL); }); node.append('};', NL, NL); + if (config.parserConfig) { + node.append('export const parserConfig: ParserConfig = {', NL); + node.indent(configNode => { + const chevrotainConfig = config.parserConfig!.chevrotainConfig; + configNode.append('chevrotainConfig: {', NL); + configNode.indent(chevrotainConfigNode => + Object.keys(chevrotainConfig).forEach(key => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const value = (chevrotainConfig as any)[key]; + chevrotainConfigNode.append(`${key}: ${typeof value === 'string' ? `'${value}'` : value},`, NL); + }) + ); + configNode.append('}', NL); + }); + node.append('};', NL, NL); + } + node.append('export const ', grammar.name, 'GeneratedModule: Module = {', NL); node.indent(moduleNode => { moduleNode.append( 'Grammar: () => grammar(),', NL, 'AstReflection: () => new ', grammar.name, 'AstReflection(),', NL, - 'LanguageMetaData: () => languageMetaData', NL + 'LanguageMetaData: () => languageMetaData,', NL, + `ParserConfig: () => ${config.parserConfig ? 'parserConfig' : 'defaultParserConfig'}`, NL ); }); node.append('};', NL); diff --git a/packages/langium-cli/src/package.ts b/packages/langium-cli/src/package.ts index 80cae84c7..9dcf635fb 100644 --- a/packages/langium-cli/src/package.ts +++ b/packages/langium-cli/src/package.ts @@ -5,6 +5,7 @@ ******************************************************************************/ import fs from 'fs-extra'; +import { ParserConfig } from 'langium'; import path from 'path'; import { getTime } from './generator/util'; @@ -32,6 +33,8 @@ export interface LangiumConfig { /** Output path to syntax highlighting file */ out: string } + /** Configure the parser */ + parserConfig?: ParserConfig, /** The following option is meant to be used only by Langium itself */ langiumInternal?: boolean } diff --git a/packages/langium/src/grammar/generated/module.ts b/packages/langium/src/grammar/generated/module.ts index 91e73683c..9b14b816c 100644 --- a/packages/langium/src/grammar/generated/module.ts +++ b/packages/langium/src/grammar/generated/module.ts @@ -3,12 +3,13 @@ * DO NOT EDIT MANUALLY! ******************************************************************************/ +import { LanguageMetaData, defaultParserConfig } from '../..'; import { Module } from '../../dependency-injection'; import { LangiumGeneratedServices, LangiumServices } from '../../services'; import { LangiumGrammarAstReflection } from './ast'; import { grammar } from './grammar'; -export const languageMetaData = { +export const languageMetaData: LanguageMetaData = { languageId: 'langium', fileExtensions: ['.langium'] }; @@ -16,5 +17,6 @@ export const languageMetaData = { export const LangiumGrammarGeneratedModule: Module = { Grammar: () => grammar(), AstReflection: () => new LangiumGrammarAstReflection(), - LanguageMetaData: () => languageMetaData + LanguageMetaData: () => languageMetaData, + ParserConfig: () => defaultParserConfig }; diff --git a/packages/langium/src/index.ts b/packages/langium/src/index.ts index a651d24ab..4a464b2f5 100644 --- a/packages/langium/src/index.ts +++ b/packages/langium/src/index.ts @@ -24,6 +24,7 @@ export * from './lsp/language-server'; export * from './validation/document-validator'; export * from './validation/validation-registry'; export * from './parser/langium-parser'; +export * from './parser/parser-config'; export * from './references/linker'; export * from './references/naming'; export * from './references/scope'; diff --git a/packages/langium/src/parser/langium-parser.ts b/packages/langium/src/parser/langium-parser.ts index 2460ebe4b..95e417ba4 100644 --- a/packages/langium/src/parser/langium-parser.ts +++ b/packages/langium/src/parser/langium-parser.ts @@ -14,6 +14,7 @@ import { Linker } from '../references/linker'; import { LangiumServices } from '../services'; import { getContainerOfType } from '../utils/ast-util'; import { ValueConverter } from './value-converter'; +import { ParserConfig } from './parser-config'; export type ParseResult = { value: T, @@ -31,6 +32,7 @@ export class LangiumParser { private readonly lexer: Lexer; private readonly nodeBuilder = new CstNodeBuilder(); private readonly wrapper: ChevrotainWrapper; + private readonly config: ParserConfig; private stack: any[] = []; private mainRule!: RuleResult; @@ -39,7 +41,8 @@ export class LangiumParser { } constructor(services: LangiumServices, tokens: TokenType[]) { - this.wrapper = new ChevrotainWrapper(tokens); + this.config = services.ParserConfig; + this.wrapper = new ChevrotainWrapper(tokens, this.config); this.linker = services.references.Linker; this.converter = services.parser.ValueConverter; this.lexer = new Lexer(tokens); @@ -302,8 +305,8 @@ class ChevrotainWrapper extends EmbeddedActionsParser { private analysed = false; - constructor(tokens: TokenType[]) { - super(tokens, { recoveryEnabled: true, nodeLocationTracking: 'onlyOffset' }); + constructor(tokens: TokenType[], config: ParserConfig) { + super(tokens, config.chevrotainConfig); } get IS_RECORDING(): boolean { diff --git a/packages/langium/src/parser/parser-config.ts b/packages/langium/src/parser/parser-config.ts new file mode 100644 index 000000000..93d513346 --- /dev/null +++ b/packages/langium/src/parser/parser-config.ts @@ -0,0 +1,17 @@ +/****************************************************************************** + * 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 { IParserConfig } from 'chevrotain'; + +export { IParserConfig } from 'chevrotain'; + +export interface ParserConfig { + chevrotainConfig: IParserConfig +} + +export const defaultParserConfig: ParserConfig = { + chevrotainConfig: { recoveryEnabled: true, nodeLocationTracking: 'onlyOffset' } +}; diff --git a/packages/langium/src/services.ts b/packages/langium/src/services.ts index 623f3c2fd..41c084ba9 100644 --- a/packages/langium/src/services.ts +++ b/packages/langium/src/services.ts @@ -6,7 +6,7 @@ import { Connection, TextDocuments } from 'vscode-languageserver'; import { TextDocument } from 'vscode-languageserver-textdocument'; -import { AstReflection, CompletionProvider, DocumentBuilder, LangiumDocumentFactory, LangiumDocuments, DocumentValidator, Grammar, JsonSerializer, LangiumParser, LanguageMetaData, Linker, NameProvider, RuleInterpreter, ScopeComputation, ScopeProvider, TextDocumentFactory, ValidationRegistry } from '.'; +import { AstReflection, CompletionProvider, DocumentBuilder, LangiumDocumentFactory, LangiumDocuments, DocumentValidator, Grammar, JsonSerializer, LangiumParser, LanguageMetaData, Linker, NameProvider, RuleInterpreter, ScopeComputation, ScopeProvider, TextDocumentFactory, ValidationRegistry, ParserConfig } from '.'; import { AstNodeDescriptionProvider, ReferenceDescriptionProvider } from './index/ast-descriptions'; import { AstNodeLocator } from './index/ast-node-locator'; import { IndexManager } from './index/index-manager'; @@ -26,6 +26,7 @@ export type LangiumGeneratedServices = { Grammar: Grammar AstReflection: AstReflection LanguageMetaData: LanguageMetaData + ParserConfig: ParserConfig } export type LangiumLspServices = { From 60fca42751b6e5dc8ddec9c8e411fbc38b6c252c Mon Sep 17 00:00:00 2001 From: Pluralia Date: Wed, 29 Sep 2021 12:47:52 +0200 Subject: [PATCH 2/6] Eliminate nested level of the parser config --- examples/domainmodel/langium-config.json | 10 ++- .../src/language-server/generated/module.ts | 12 ++-- .../langium-cli/langium-config-schema.json | 69 ++++++++----------- .../src/generator/module-generator.ts | 27 ++++---- packages/langium-cli/src/package.ts | 6 +- packages/langium/src/parser/langium-parser.ts | 8 +-- packages/langium/src/parser/parser-config.ts | 9 +-- packages/langium/src/services.ts | 4 +- 8 files changed, 63 insertions(+), 82 deletions(-) diff --git a/examples/domainmodel/langium-config.json b/examples/domainmodel/langium-config.json index dcab7cfdd..d442821dd 100644 --- a/examples/domainmodel/langium-config.json +++ b/examples/domainmodel/langium-config.json @@ -6,11 +6,9 @@ "textMate": { "out": "syntaxes/domain-model.tmLanguage.json" }, - "parserConfig": { - "chevrotainConfig": { - "recoveryEnabled": true, - "nodeLocationTracking": "onlyOffset", - "maxLookahead": 3 - } + "chevrotainParserConfig": { + "recoveryEnabled": true, + "nodeLocationTracking": "onlyOffset", + "maxLookahead": 3 } } diff --git a/examples/domainmodel/src/language-server/generated/module.ts b/examples/domainmodel/src/language-server/generated/module.ts index b785b7e24..743f10b19 100644 --- a/examples/domainmodel/src/language-server/generated/module.ts +++ b/examples/domainmodel/src/language-server/generated/module.ts @@ -3,7 +3,7 @@ * DO NOT EDIT MANUALLY! ******************************************************************************/ -import { LangiumGeneratedServices, LangiumServices, LanguageMetaData, Module, ParserConfig } from 'langium'; +import { LangiumGeneratedServices, LangiumServices, LanguageMetaData, Module, IParserConfig } from 'langium'; import { DomainModelAstReflection } from './ast'; import { grammar } from './grammar'; @@ -12,12 +12,10 @@ export const languageMetaData: LanguageMetaData = { fileExtensions: ['.dmodel'] }; -export const parserConfig: ParserConfig = { - chevrotainConfig: { - recoveryEnabled: true, - nodeLocationTracking: 'onlyOffset', - maxLookahead: 4, - } +export const parserConfig: IParserConfig = { + recoveryEnabled: true, + nodeLocationTracking: 'onlyOffset', + maxLookahead: 3, }; export const DomainModelGeneratedModule: Module = { diff --git a/packages/langium-cli/langium-config-schema.json b/packages/langium-cli/langium-config-schema.json index d7ca491a6..f40a2d228 100644 --- a/packages/langium-cli/langium-config-schema.json +++ b/packages/langium-cli/langium-config-schema.json @@ -40,49 +40,40 @@ "out" ] }, - "parserConfig": { - "description": "An object to describe the parser configuration", + "chevrotainParserConfig": { + "description": "An object to describe the Chevrotain parser configuration", "type": "object", "properties": { - "chevrotainConfig": { - "description": "An object to describe the Chevrotain parser configuration", - "type": "object", - "properties": { - "recoveryEnabled": { - "description": "Is the error recovery / fault tolerance of the Chevrotain Parser enabled", - "type": "boolean" - }, - "maxLookahead": { - "description": "Maximum number of tokens the parser will use to choose between alternatives", - "type": "number" - }, - "dynamicTokensEnabled": { - "description": "A flag to support Dynamically defined Tokens", - "type": "boolean" - }, - "nodeLocationTracking": { - "description": "Enable computation of CST nodes location", - "type": "string" - }, - "errorMessageProvider": { - "description": "A custom error message provider", - "type": "object" - }, - "traceInitPerf": { - "description": "A flag to print performance tracing logs during parser initialization", - "type": ["boolean", "number"] - }, - "skipValidations": { - "description": "A flag to avoid running the grammar validations during Parser initialization", - "type": "boolean" - } - }, - "required": [] + "recoveryEnabled": { + "description": "Is the error recovery / fault tolerance of the Chevrotain Parser enabled", + "type": "boolean" + }, + "maxLookahead": { + "description": "Maximum number of tokens the parser will use to choose between alternatives", + "type": "number" + }, + "dynamicTokensEnabled": { + "description": "A flag to support Dynamically defined Tokens", + "type": "boolean" + }, + "nodeLocationTracking": { + "description": "Enable computation of CST nodes location", + "type": "string" + }, + "errorMessageProvider": { + "description": "A custom error message provider", + "type": "object" + }, + "traceInitPerf": { + "description": "A flag to print performance tracing logs during parser initialization", + "type": ["boolean", "number"] + }, + "skipValidations": { + "description": "A flag to avoid running the grammar validations during Parser initialization", + "type": "boolean" } }, - "required": [ - "chevrotainConfig" - ] + "required": [] }, "langiumInternal": { "description": "A flag to determine whether langium uses itself to bootstrap", diff --git a/packages/langium-cli/src/generator/module-generator.ts b/packages/langium-cli/src/generator/module-generator.ts index c370c1897..69ac5f610 100644 --- a/packages/langium-cli/src/generator/module-generator.ts +++ b/packages/langium-cli/src/generator/module-generator.ts @@ -10,14 +10,16 @@ import { LangiumConfig } from '../package'; import { generatedHeader } from './util'; export function generateModule(grammar: langium.Grammar, config: LangiumConfig): string { + const parserConfig = config.chevrotainParserConfig; const node = new CompositeGeneratorNode(); + node.append(generatedHeader); if (config.langiumInternal) { - node.append(`import { LanguageMetaData, ${config.parserConfig ? 'ParserConfig' : 'defaultParserConfig'} } from '../..';`, NL); + node.append(`import { LanguageMetaData, ${parserConfig ? 'IParserConfig' : 'defaultParserConfig'} } from '../..';`, NL); node.append("import { Module } from '../../dependency-injection';", NL); node.contents.push("import { LangiumGeneratedServices, LangiumServices } from '../../services';", NL); } else { - node.append(`import { LangiumGeneratedServices, LangiumServices, LanguageMetaData, Module, ${config.parserConfig ? 'ParserConfig' : 'defaultParserConfig'} } from 'langium';`, NL); + node.append(`import { LangiumGeneratedServices, LangiumServices, LanguageMetaData, Module, ${parserConfig ? 'IParserConfig' : 'defaultParserConfig'} } from 'langium';`, NL); } node.append( 'import { ', grammar.name, "AstReflection } from './ast';", NL, @@ -31,19 +33,14 @@ export function generateModule(grammar: langium.Grammar, config: LangiumConfig): }); node.append('};', NL, NL); - if (config.parserConfig) { - node.append('export const parserConfig: ParserConfig = {', NL); + if (parserConfig) { + node.append('export const parserConfig: IParserConfig = {', NL); node.indent(configNode => { - const chevrotainConfig = config.parserConfig!.chevrotainConfig; - configNode.append('chevrotainConfig: {', NL); - configNode.indent(chevrotainConfigNode => - Object.keys(chevrotainConfig).forEach(key => { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const value = (chevrotainConfig as any)[key]; - chevrotainConfigNode.append(`${key}: ${typeof value === 'string' ? `'${value}'` : value},`, NL); - }) - ); - configNode.append('}', NL); + Object.keys(parserConfig).forEach(key => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const value = (parserConfig as any)[key]; + configNode.append(`${key}: ${typeof value === 'string' ? `'${value}'` : value},`, NL); + }); }); node.append('};', NL, NL); } @@ -54,7 +51,7 @@ export function generateModule(grammar: langium.Grammar, config: LangiumConfig): 'Grammar: () => grammar(),', NL, 'AstReflection: () => new ', grammar.name, 'AstReflection(),', NL, 'LanguageMetaData: () => languageMetaData,', NL, - `ParserConfig: () => ${config.parserConfig ? 'parserConfig' : 'defaultParserConfig'}`, NL + `ParserConfig: () => ${parserConfig ? 'parserConfig' : 'defaultParserConfig'}`, NL ); }); node.append('};', NL); diff --git a/packages/langium-cli/src/package.ts b/packages/langium-cli/src/package.ts index 9dcf635fb..d6d8af4fd 100644 --- a/packages/langium-cli/src/package.ts +++ b/packages/langium-cli/src/package.ts @@ -5,7 +5,7 @@ ******************************************************************************/ import fs from 'fs-extra'; -import { ParserConfig } from 'langium'; +import { IParserConfig } from 'langium'; import path from 'path'; import { getTime } from './generator/util'; @@ -33,8 +33,8 @@ export interface LangiumConfig { /** Output path to syntax highlighting file */ out: string } - /** Configure the parser */ - parserConfig?: ParserConfig, + /** Configure the chevrotain parser */ + chevrotainParserConfig?: IParserConfig, /** The following option is meant to be used only by Langium itself */ langiumInternal?: boolean } diff --git a/packages/langium/src/parser/langium-parser.ts b/packages/langium/src/parser/langium-parser.ts index 95e417ba4..5f0c85b46 100644 --- a/packages/langium/src/parser/langium-parser.ts +++ b/packages/langium/src/parser/langium-parser.ts @@ -14,7 +14,7 @@ import { Linker } from '../references/linker'; import { LangiumServices } from '../services'; import { getContainerOfType } from '../utils/ast-util'; import { ValueConverter } from './value-converter'; -import { ParserConfig } from './parser-config'; +import { IParserConfig } from './parser-config'; export type ParseResult = { value: T, @@ -32,7 +32,7 @@ export class LangiumParser { private readonly lexer: Lexer; private readonly nodeBuilder = new CstNodeBuilder(); private readonly wrapper: ChevrotainWrapper; - private readonly config: ParserConfig; + private readonly config: IParserConfig; private stack: any[] = []; private mainRule!: RuleResult; @@ -305,8 +305,8 @@ class ChevrotainWrapper extends EmbeddedActionsParser { private analysed = false; - constructor(tokens: TokenType[], config: ParserConfig) { - super(tokens, config.chevrotainConfig); + constructor(tokens: TokenType[], config: IParserConfig) { + super(tokens, config); } get IS_RECORDING(): boolean { diff --git a/packages/langium/src/parser/parser-config.ts b/packages/langium/src/parser/parser-config.ts index 93d513346..43b8c08f7 100644 --- a/packages/langium/src/parser/parser-config.ts +++ b/packages/langium/src/parser/parser-config.ts @@ -8,10 +8,7 @@ import { IParserConfig } from 'chevrotain'; export { IParserConfig } from 'chevrotain'; -export interface ParserConfig { - chevrotainConfig: IParserConfig -} - -export const defaultParserConfig: ParserConfig = { - chevrotainConfig: { recoveryEnabled: true, nodeLocationTracking: 'onlyOffset' } +export const defaultParserConfig: IParserConfig = { + recoveryEnabled: true, + nodeLocationTracking: 'onlyOffset' }; diff --git a/packages/langium/src/services.ts b/packages/langium/src/services.ts index 41c084ba9..b9838c879 100644 --- a/packages/langium/src/services.ts +++ b/packages/langium/src/services.ts @@ -6,7 +6,7 @@ import { Connection, TextDocuments } from 'vscode-languageserver'; import { TextDocument } from 'vscode-languageserver-textdocument'; -import { AstReflection, CompletionProvider, DocumentBuilder, LangiumDocumentFactory, LangiumDocuments, DocumentValidator, Grammar, JsonSerializer, LangiumParser, LanguageMetaData, Linker, NameProvider, RuleInterpreter, ScopeComputation, ScopeProvider, TextDocumentFactory, ValidationRegistry, ParserConfig } from '.'; +import { AstReflection, CompletionProvider, DocumentBuilder, LangiumDocumentFactory, LangiumDocuments, DocumentValidator, Grammar, JsonSerializer, LangiumParser, LanguageMetaData, Linker, NameProvider, RuleInterpreter, ScopeComputation, ScopeProvider, TextDocumentFactory, ValidationRegistry, IParserConfig } from '.'; import { AstNodeDescriptionProvider, ReferenceDescriptionProvider } from './index/ast-descriptions'; import { AstNodeLocator } from './index/ast-node-locator'; import { IndexManager } from './index/index-manager'; @@ -26,7 +26,7 @@ export type LangiumGeneratedServices = { Grammar: Grammar AstReflection: AstReflection LanguageMetaData: LanguageMetaData - ParserConfig: ParserConfig + ParserConfig: IParserConfig } export type LangiumLspServices = { From ef7eeb8ec31d84863522d7326fbadb53e9c2597f Mon Sep 17 00:00:00 2001 From: Pluralia Date: Wed, 29 Sep 2021 12:51:34 +0200 Subject: [PATCH 3/6] Remove errorMessageProvider propery from the chevrotainParserConfig JSON schema --- packages/langium-cli/langium-config-schema.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/langium-cli/langium-config-schema.json b/packages/langium-cli/langium-config-schema.json index f40a2d228..31d45734a 100644 --- a/packages/langium-cli/langium-config-schema.json +++ b/packages/langium-cli/langium-config-schema.json @@ -60,10 +60,6 @@ "description": "Enable computation of CST nodes location", "type": "string" }, - "errorMessageProvider": { - "description": "A custom error message provider", - "type": "object" - }, "traceInitPerf": { "description": "A flag to print performance tracing logs during parser initialization", "type": ["boolean", "number"] From f28ed1f127b9ca153c17fb6b2498ecea0b60f070 Mon Sep 17 00:00:00 2001 From: Pluralia Date: Wed, 29 Sep 2021 12:58:58 +0200 Subject: [PATCH 4/6] Extract the ParserConfig service in a group parser --- .../arithmetics/src/language-server/generated/module.ts | 4 +++- .../domainmodel/src/language-server/generated/module.ts | 4 +++- .../statemachine/src/language-server/generated/module.ts | 4 +++- packages/langium-cli/src/generator/module-generator.ts | 6 +++++- packages/langium/src/grammar/generated/module.ts | 4 +++- packages/langium/src/parser/langium-parser.ts | 2 +- packages/langium/src/services.ts | 4 +++- 7 files changed, 21 insertions(+), 7 deletions(-) diff --git a/examples/arithmetics/src/language-server/generated/module.ts b/examples/arithmetics/src/language-server/generated/module.ts index f0bf585ef..d6872ee34 100644 --- a/examples/arithmetics/src/language-server/generated/module.ts +++ b/examples/arithmetics/src/language-server/generated/module.ts @@ -16,5 +16,7 @@ export const ArithmeticsGeneratedModule: Module grammar(), AstReflection: () => new ArithmeticsAstReflection(), LanguageMetaData: () => languageMetaData, - ParserConfig: () => defaultParserConfig + parser: { + ParserConfig: () => defaultParserConfig + } }; diff --git a/examples/domainmodel/src/language-server/generated/module.ts b/examples/domainmodel/src/language-server/generated/module.ts index 743f10b19..7864991ca 100644 --- a/examples/domainmodel/src/language-server/generated/module.ts +++ b/examples/domainmodel/src/language-server/generated/module.ts @@ -22,5 +22,7 @@ export const DomainModelGeneratedModule: Module grammar(), AstReflection: () => new DomainModelAstReflection(), LanguageMetaData: () => languageMetaData, - ParserConfig: () => parserConfig + parser: { + ParserConfig: () => parserConfig + } }; diff --git a/examples/statemachine/src/language-server/generated/module.ts b/examples/statemachine/src/language-server/generated/module.ts index 6bb525f7b..ae3e582ab 100644 --- a/examples/statemachine/src/language-server/generated/module.ts +++ b/examples/statemachine/src/language-server/generated/module.ts @@ -16,5 +16,7 @@ export const StatemachineGeneratedModule: Module grammar(), AstReflection: () => new StatemachineAstReflection(), LanguageMetaData: () => languageMetaData, - ParserConfig: () => defaultParserConfig + parser: { + ParserConfig: () => defaultParserConfig + } }; diff --git a/packages/langium-cli/src/generator/module-generator.ts b/packages/langium-cli/src/generator/module-generator.ts index 69ac5f610..35aa3b98a 100644 --- a/packages/langium-cli/src/generator/module-generator.ts +++ b/packages/langium-cli/src/generator/module-generator.ts @@ -51,8 +51,12 @@ export function generateModule(grammar: langium.Grammar, config: LangiumConfig): 'Grammar: () => grammar(),', NL, 'AstReflection: () => new ', grammar.name, 'AstReflection(),', NL, 'LanguageMetaData: () => languageMetaData,', NL, - `ParserConfig: () => ${parserConfig ? 'parserConfig' : 'defaultParserConfig'}`, NL + 'parser: {', NL ); + moduleNode.indent(parserGroupNode => { + parserGroupNode.append(`ParserConfig: () => ${parserConfig ? 'parserConfig' : 'defaultParserConfig'}`, NL); + }); + moduleNode.append('}', NL); }); node.append('};', NL); diff --git a/packages/langium/src/grammar/generated/module.ts b/packages/langium/src/grammar/generated/module.ts index 9b14b816c..836cd3c76 100644 --- a/packages/langium/src/grammar/generated/module.ts +++ b/packages/langium/src/grammar/generated/module.ts @@ -18,5 +18,7 @@ export const LangiumGrammarGeneratedModule: Module grammar(), AstReflection: () => new LangiumGrammarAstReflection(), LanguageMetaData: () => languageMetaData, - ParserConfig: () => defaultParserConfig + parser: { + ParserConfig: () => defaultParserConfig + } }; diff --git a/packages/langium/src/parser/langium-parser.ts b/packages/langium/src/parser/langium-parser.ts index 5f0c85b46..20e559803 100644 --- a/packages/langium/src/parser/langium-parser.ts +++ b/packages/langium/src/parser/langium-parser.ts @@ -41,7 +41,7 @@ export class LangiumParser { } constructor(services: LangiumServices, tokens: TokenType[]) { - this.config = services.ParserConfig; + this.config = services.parser.ParserConfig; this.wrapper = new ChevrotainWrapper(tokens, this.config); this.linker = services.references.Linker; this.converter = services.parser.ValueConverter; diff --git a/packages/langium/src/services.ts b/packages/langium/src/services.ts index b9838c879..4b70cb325 100644 --- a/packages/langium/src/services.ts +++ b/packages/langium/src/services.ts @@ -26,7 +26,9 @@ export type LangiumGeneratedServices = { Grammar: Grammar AstReflection: AstReflection LanguageMetaData: LanguageMetaData - ParserConfig: IParserConfig + parser: { + ParserConfig: IParserConfig + } } export type LangiumLspServices = { From a79138848b27ccbd18400b72289830189696069c Mon Sep 17 00:00:00 2001 From: Pluralia Date: Wed, 29 Sep 2021 13:24:46 +0200 Subject: [PATCH 5/6] Make ParserConfig an optional service & Remove defaultParserConfig --- .../src/language-server/generated/module.ts | 6 ++---- .../src/language-server/generated/module.ts | 6 ++---- .../langium-cli/src/generator/module-generator.ts | 15 +++++++++------ packages/langium/src/grammar/generated/module.ts | 6 ++---- packages/langium/src/parser/langium-parser.ts | 10 +++++++--- packages/langium/src/parser/parser-config.ts | 7 ------- packages/langium/src/services.ts | 2 +- 7 files changed, 23 insertions(+), 29 deletions(-) diff --git a/examples/arithmetics/src/language-server/generated/module.ts b/examples/arithmetics/src/language-server/generated/module.ts index d6872ee34..3728403d8 100644 --- a/examples/arithmetics/src/language-server/generated/module.ts +++ b/examples/arithmetics/src/language-server/generated/module.ts @@ -3,7 +3,7 @@ * DO NOT EDIT MANUALLY! ******************************************************************************/ -import { LangiumGeneratedServices, LangiumServices, LanguageMetaData, Module, defaultParserConfig } from 'langium'; +import { LangiumGeneratedServices, LangiumServices, LanguageMetaData, Module } from 'langium'; import { ArithmeticsAstReflection } from './ast'; import { grammar } from './grammar'; @@ -16,7 +16,5 @@ export const ArithmeticsGeneratedModule: Module grammar(), AstReflection: () => new ArithmeticsAstReflection(), LanguageMetaData: () => languageMetaData, - parser: { - ParserConfig: () => defaultParserConfig - } + parser: {} }; diff --git a/examples/statemachine/src/language-server/generated/module.ts b/examples/statemachine/src/language-server/generated/module.ts index ae3e582ab..ebecf857f 100644 --- a/examples/statemachine/src/language-server/generated/module.ts +++ b/examples/statemachine/src/language-server/generated/module.ts @@ -3,7 +3,7 @@ * DO NOT EDIT MANUALLY! ******************************************************************************/ -import { LangiumGeneratedServices, LangiumServices, LanguageMetaData, Module, defaultParserConfig } from 'langium'; +import { LangiumGeneratedServices, LangiumServices, LanguageMetaData, Module } from 'langium'; import { StatemachineAstReflection } from './ast'; import { grammar } from './grammar'; @@ -16,7 +16,5 @@ export const StatemachineGeneratedModule: Module grammar(), AstReflection: () => new StatemachineAstReflection(), LanguageMetaData: () => languageMetaData, - parser: { - ParserConfig: () => defaultParserConfig - } + parser: {} }; diff --git a/packages/langium-cli/src/generator/module-generator.ts b/packages/langium-cli/src/generator/module-generator.ts index 35aa3b98a..692267972 100644 --- a/packages/langium-cli/src/generator/module-generator.ts +++ b/packages/langium-cli/src/generator/module-generator.ts @@ -15,11 +15,11 @@ export function generateModule(grammar: langium.Grammar, config: LangiumConfig): node.append(generatedHeader); if (config.langiumInternal) { - node.append(`import { LanguageMetaData, ${parserConfig ? 'IParserConfig' : 'defaultParserConfig'} } from '../..';`, NL); + node.append(`import { LanguageMetaData${parserConfig ? ', IParserConfig' : ''} } from '../..';`, NL); node.append("import { Module } from '../../dependency-injection';", NL); node.contents.push("import { LangiumGeneratedServices, LangiumServices } from '../../services';", NL); } else { - node.append(`import { LangiumGeneratedServices, LangiumServices, LanguageMetaData, Module, ${parserConfig ? 'IParserConfig' : 'defaultParserConfig'} } from 'langium';`, NL); + node.append(`import { LangiumGeneratedServices, LangiumServices, LanguageMetaData, Module${parserConfig ? ', IParserConfig' : ''} } from 'langium';`, NL); } node.append( 'import { ', grammar.name, "AstReflection } from './ast';", NL, @@ -51,11 +51,14 @@ export function generateModule(grammar: langium.Grammar, config: LangiumConfig): 'Grammar: () => grammar(),', NL, 'AstReflection: () => new ', grammar.name, 'AstReflection(),', NL, 'LanguageMetaData: () => languageMetaData,', NL, - 'parser: {', NL + 'parser: {', ); - moduleNode.indent(parserGroupNode => { - parserGroupNode.append(`ParserConfig: () => ${parserConfig ? 'parserConfig' : 'defaultParserConfig'}`, NL); - }); + if (parserConfig) { + moduleNode.append(NL); + moduleNode.indent(parserGroupNode => { + parserGroupNode.append('ParserConfig: () => parserConfig', NL); + }); + } moduleNode.append('}', NL); }); node.append('};', NL); diff --git a/packages/langium/src/grammar/generated/module.ts b/packages/langium/src/grammar/generated/module.ts index 836cd3c76..544f1cba6 100644 --- a/packages/langium/src/grammar/generated/module.ts +++ b/packages/langium/src/grammar/generated/module.ts @@ -3,7 +3,7 @@ * DO NOT EDIT MANUALLY! ******************************************************************************/ -import { LanguageMetaData, defaultParserConfig } from '../..'; +import { LanguageMetaData } from '../..'; import { Module } from '../../dependency-injection'; import { LangiumGeneratedServices, LangiumServices } from '../../services'; import { LangiumGrammarAstReflection } from './ast'; @@ -18,7 +18,5 @@ export const LangiumGrammarGeneratedModule: Module grammar(), AstReflection: () => new LangiumGrammarAstReflection(), LanguageMetaData: () => languageMetaData, - parser: { - ParserConfig: () => defaultParserConfig - } + parser: {} }; diff --git a/packages/langium/src/parser/langium-parser.ts b/packages/langium/src/parser/langium-parser.ts index 20e559803..5cf555dca 100644 --- a/packages/langium/src/parser/langium-parser.ts +++ b/packages/langium/src/parser/langium-parser.ts @@ -32,7 +32,7 @@ export class LangiumParser { private readonly lexer: Lexer; private readonly nodeBuilder = new CstNodeBuilder(); private readonly wrapper: ChevrotainWrapper; - private readonly config: IParserConfig; + private readonly config: IParserConfig | undefined; private stack: any[] = []; private mainRule!: RuleResult; @@ -305,8 +305,12 @@ class ChevrotainWrapper extends EmbeddedActionsParser { private analysed = false; - constructor(tokens: TokenType[], config: IParserConfig) { - super(tokens, config); + constructor(tokens: TokenType[], config?: IParserConfig) { + super(tokens, { + recoveryEnabled: true, + nodeLocationTracking: 'onlyOffset', + ...config + }); } get IS_RECORDING(): boolean { diff --git a/packages/langium/src/parser/parser-config.ts b/packages/langium/src/parser/parser-config.ts index 43b8c08f7..f90e28968 100644 --- a/packages/langium/src/parser/parser-config.ts +++ b/packages/langium/src/parser/parser-config.ts @@ -4,11 +4,4 @@ * terms of the MIT License, which is available in the project root. ******************************************************************************/ -import { IParserConfig } from 'chevrotain'; - export { IParserConfig } from 'chevrotain'; - -export const defaultParserConfig: IParserConfig = { - recoveryEnabled: true, - nodeLocationTracking: 'onlyOffset' -}; diff --git a/packages/langium/src/services.ts b/packages/langium/src/services.ts index 4b70cb325..5d0d59530 100644 --- a/packages/langium/src/services.ts +++ b/packages/langium/src/services.ts @@ -27,7 +27,7 @@ export type LangiumGeneratedServices = { AstReflection: AstReflection LanguageMetaData: LanguageMetaData parser: { - ParserConfig: IParserConfig + ParserConfig?: IParserConfig } } From 1bc7bd36d7ed81fb226d6b13dd5020e796fce94f Mon Sep 17 00:00:00 2001 From: Pluralia Date: Thu, 30 Sep 2021 09:22:49 +0200 Subject: [PATCH 6/6] Remove config field from LangiumParser class --- packages/langium/src/parser/langium-parser.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/langium/src/parser/langium-parser.ts b/packages/langium/src/parser/langium-parser.ts index 5cf555dca..6cdea1bde 100644 --- a/packages/langium/src/parser/langium-parser.ts +++ b/packages/langium/src/parser/langium-parser.ts @@ -32,7 +32,6 @@ export class LangiumParser { private readonly lexer: Lexer; private readonly nodeBuilder = new CstNodeBuilder(); private readonly wrapper: ChevrotainWrapper; - private readonly config: IParserConfig | undefined; private stack: any[] = []; private mainRule!: RuleResult; @@ -41,8 +40,7 @@ export class LangiumParser { } constructor(services: LangiumServices, tokens: TokenType[]) { - this.config = services.parser.ParserConfig; - this.wrapper = new ChevrotainWrapper(tokens, this.config); + this.wrapper = new ChevrotainWrapper(tokens, services.parser.ParserConfig); this.linker = services.references.Linker; this.converter = services.parser.ValueConverter; this.lexer = new Lexer(tokens);