Skip to content

Commit 644660a

Browse files
authored
Add lexer error message provider (#1716)
1 parent 21b1051 commit 644660a

File tree

3 files changed

+24
-8
lines changed

3 files changed

+24
-8
lines changed

packages/langium/src/default-module.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import { DefaultDocumentBuilder } from './workspace/document-builder.js';
2828
import { DefaultLangiumDocumentFactory, DefaultLangiumDocuments } from './workspace/documents.js';
2929
import { DefaultIndexManager } from './workspace/index-manager.js';
3030
import { DefaultWorkspaceManager } from './workspace/workspace-manager.js';
31-
import { DefaultLexer } from './parser/lexer.js';
31+
import { DefaultLexer, DefaultLexerErrorMessageProvider } from './parser/lexer.js';
3232
import { JSDocDocumentationProvider } from './documentation/documentation-provider.js';
3333
import { DefaultCommentProvider } from './documentation/comment-provider.js';
3434
import { LangiumParserErrorMessageProvider } from './parser/langium-parser.js';
@@ -61,7 +61,8 @@ export function createDefaultCoreModule(context: DefaultCoreModuleContext): Modu
6161
ValueConverter: () => new DefaultValueConverter(),
6262
TokenBuilder: () => new DefaultTokenBuilder(),
6363
Lexer: (services) => new DefaultLexer(services),
64-
ParserErrorMessageProvider: () => new LangiumParserErrorMessageProvider()
64+
ParserErrorMessageProvider: () => new LangiumParserErrorMessageProvider(),
65+
LexerErrorMessageProvider: () => new DefaultLexerErrorMessageProvider()
6566
},
6667
workspace: {
6768
AstNodeLocator: () => new DefaultAstNodeLocator(),

packages/langium/src/parser/lexer.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,22 @@
44
* terms of the MIT License, which is available in the project root.
55
******************************************************************************/
66

7-
import type { ILexingError, IMultiModeLexerDefinition, IToken, TokenType, TokenTypeDictionary, TokenVocabulary } from 'chevrotain';
7+
import type { ILexerErrorMessageProvider, ILexingError, IMultiModeLexerDefinition, IToken, TokenType, TokenTypeDictionary, TokenVocabulary } from 'chevrotain';
88
import type { LangiumCoreServices } from '../services.js';
9-
import { Lexer as ChevrotainLexer } from 'chevrotain';
9+
import { Lexer as ChevrotainLexer, defaultLexerErrorProvider } from 'chevrotain';
1010
import type { LexingReport, TokenBuilder } from './token-builder.js';
1111

12+
export class DefaultLexerErrorMessageProvider implements ILexerErrorMessageProvider {
13+
14+
buildUnexpectedCharactersMessage(fullText: string, startOffset: number, length: number, line?: number, column?: number): string {
15+
return defaultLexerErrorProvider.buildUnexpectedCharactersMessage(fullText, startOffset, length, line, column);
16+
}
17+
18+
buildUnableToPopLexerModeMessage(token: IToken): string {
19+
return defaultLexerErrorProvider.buildUnableToPopLexerModeMessage(token);
20+
}
21+
}
22+
1223
export interface LexerResult {
1324
/**
1425
* A list of all tokens that were lexed from the input.
@@ -40,11 +51,13 @@ export interface Lexer {
4051

4152
export class DefaultLexer implements Lexer {
4253

43-
protected chevrotainLexer: ChevrotainLexer;
44-
protected tokenBuilder: TokenBuilder;
54+
protected readonly tokenBuilder: TokenBuilder;
55+
protected readonly errorMessageProvider: ILexerErrorMessageProvider;
4556
protected tokenTypes: TokenTypeDictionary;
57+
protected chevrotainLexer: ChevrotainLexer;
4658

4759
constructor(services: LangiumCoreServices) {
60+
this.errorMessageProvider = services.parser.LexerErrorMessageProvider;
4861
this.tokenBuilder = services.parser.TokenBuilder;
4962
const tokens = this.tokenBuilder.buildTokens(services.Grammar, {
5063
caseInsensitive: services.LanguageMetaData.caseInsensitive
@@ -54,7 +67,8 @@ export class DefaultLexer implements Lexer {
5467
const production = services.LanguageMetaData.mode === 'production';
5568
this.chevrotainLexer = new ChevrotainLexer(lexerTokens, {
5669
positionTracking: 'full',
57-
skipValidations: production
70+
skipValidations: production,
71+
errorMessageProvider: this.errorMessageProvider
5872
});
5973
}
6074

packages/langium/src/services.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
******************************************************************************/
66

77
// Ensure that all imports are erased at runtime to avoid circular dependencies.
8-
import type { IParserErrorMessageProvider } from 'chevrotain';
8+
import type { IParserErrorMessageProvider, ILexerErrorMessageProvider } from 'chevrotain';
99
import type { CommentProvider } from './documentation/comment-provider.js';
1010
import type { DocumentationProvider } from './documentation/documentation-provider.js';
1111
import type { Grammar } from './languages/generated/ast.js';
@@ -60,6 +60,7 @@ export type LangiumDefaultCoreServices = {
6060
readonly ValueConverter: ValueConverter
6161
readonly LangiumParser: LangiumParser
6262
readonly ParserErrorMessageProvider: IParserErrorMessageProvider
63+
readonly LexerErrorMessageProvider: ILexerErrorMessageProvider
6364
readonly CompletionParser: LangiumCompletionParser
6465
readonly TokenBuilder: TokenBuilder
6566
readonly Lexer: Lexer

0 commit comments

Comments
 (0)