Breaking Changes
11.0.0
- Chevrotain is now ESM only. If you need to use Chevrotain 11.0.0+ in a CommonJS project, either:
- Use dynamic import
- Bundle Chevrotain yourself to Commonjs (e.g using Webpack / esbuild).
- UMD bundles (e.g:
chevrotain.js/chevrotain.min.js
) were removed. - ESM bundles have been moved from
lib_esm
tolib
folder, so CDN urls will break, e.g:- New:
https://unpkg.com/chevrotain/lib/chevrotain.min.mjs
. - Old:
https://unpkg.com/chevrotain/lib_esm/chevrotain.min.mjs
(now broken).
- New:
10.0.0
Dropped support for legacy ES5.1 runtimes (e.g: IE11) The minimum ECMAScript version needed to run Chevrotain is now ES2015 (ES6). This should not affect anyone running on a modern engine,
meaning modern NodeJS versions or popular evergreen browsers.Various TypeScript signatures are now more accurate and strict which could potentially cause compilation errors with some grammars implemented in TypeScript, e.g:
OPTION
methods now returnOUT | undefined
instead of justOUT
.- A
RULE
implementation function inCstParser
is now defined as returningvoid
. - The
ARGS
forSubruleMethodOpts
options type is now better enforced via generics in thesubrule
definition.
9.0.0
- Custom APIs feature has been deprecated and removed. This means the following public APIs no longer exist:
resolveGrammar
validateGrammar
assignOccurrenceIndices
defaultGrammarValidatorErrorProvider
defaultGrammarResolverErrorProvider
IGrammarValidatorErrorMessageProvider
IGrammarResolverErrorMessageProvider
IParserDefinitionError
generateParserFactory
generateParserModule
8.0.0
- Chevrotain now uses the package.json
exports
field, as specified in the documentation:Warning: Introducing the "exports" field prevents consumers of a package from using any entry points that are not defined, including the package.json (e.g. require('your-package/package.json'). This will likely be a breaking change.
7.0.0
The Parser's default
maxLookahead
was reduced to 3. This could cause ambiguity issues in existing Parsers. The pre 7.0.0 behavior can be reproduced by passing an explicitmaxLookahead
class MoreLookaheadParser extends CstParser { constructor() { super([], { maxLookahead: 4, }); // ... } }
It is also possible (and recommended) to increase the maxLookahead for a specific DSL method rather than globally for all. See relevant issue.
The soft deprecated
Parser
class has been fully removed, useCstParser
orEmbeddedActionsParser
instead. The choice depends on if your parser outputs a CST or not. theoutputCst
property of the IParserConfig was also removed as this behavior is now controlled by base Parser class which is extended.The soft deprecated static
performSelfAnalysis
method has been fully removed, use the instance method with the same name instead.The IParserConfig's
ignoredIssues
property has been deprecated. Any Parser still using this property will throw an exception on initialization. If any ambiguities need be ignored, theIGNORE_AMBIGUITIES
property should be used instead on specific DSL rules.Nested / In-Lined rules via the
NAME
parameter for DSL rules have been deprecated, e.g:this.RULE("statements", () => { this.OR([ { NAME: "$letStatement", ALT: () => { // ... }, }, { NAME: "$selectStatement", ALT: () => { // ... }, }, ]); });
This feature was not orthogonal with other features (e.g error recovery) and added quite a-lot of complexity for the small benefit of a little syntactic sugar. Instead of using "nested / in-lined" rules, simply extract the content of these rules to "regular" top level rules.
Reducing the usage of 'any' in the 'OR' method type signature may cause existing code to fail TypeScript compilation. In such a case an explicit usage of a generic
any
type will resolve the problem.this.OR<any>(/* ... */);
All methods of the Interface
errorMessageProvider
are now mandatory. To defer to the default error message template behavior, defer tochevrotain.defaultParserErrorProvider
, e.g:import { defaultParserErrorProvider, IParserErrorMessageProvider, IToken, TokenType, } from "chevrotain"; class myCustomErrorMsgProvider implements IParserErrorMessageProvider { buildNoViableAltMessage(options: { expectedPathsPerAlt: TokenType[][][]; actual: IToken[]; previous: IToken; customUserDescription: string; ruleName: string; }): string { // Custom user error message builder return "sad sad panda:" + options.actual[0].image; } buildEarlyExitMessage(options: { expectedIterationPaths: TokenType[][]; actual: IToken[]; previous: IToken; customUserDescription: string; ruleName: string; }): string { // invoking the default error message string builder. return defaultParserErrorProvider.buildEarlyExitMessage(options); } // Implementation of other properties from `IParserErrorMessageProvider` // ... }
The TokenType's
tokenName
property has been deprecated (This actually happened in 6.3.1...) use thename
property instead.The GAST
Flat
class was renamed toAlternative
.
6.0.0
Due to re-implementation of the grammar analysis via "grammar recording", certain semantics action will now need to be wrapped in the new ACTION Parsing DSL method. This will not affect Parsers that output a CST and only affect some of the Parsers which employ embedded semantic actions. The Missing
ACTION
wrappers will be automatically detected and throw a descriptive error message to ease migration.Grammar de-serialization support has been removed as it is now redundant as Chevrotain no longer relies on
Function.prototype.toString
. And the de-serialization feature was a workaround to issues caused byFunction.prototype.toString
. This means the serializedGrammar property of the Parser's configuration was removed, and using it will cause an error to be thrown during initialization.The Parser's getGAstProductions method now returns a plain JavaScript object representing a Map/Dictionary rather than the Chevrotain's internal HashTable implementation.
5.0.0
- Setting the Parser's input before
this.performSelfAnalysis
is called will now throw an error. This limitation is necessary in order to enable to enable the automatic detection of missingthis.performSelfAnalysis
calls. To avoid this issue do not pass the input token vector input to the Parser's constructor and instead always set the input after the Parser instance was created, This pattern is demonstrated in the tutorial:
4.0.0
The Parser constructor no longer accepts a token vector as an argument. The "input" setter should be used instead, for example:
// Old API class MyOldParser extends Parser { constructor(input, config) { super(input, allTokens, config); } } const oldInstance = new MyOldParser( [ /* token vector */ ], {}, ); // New API class MyNewParser extends Parser { constructor(config) { super(allTokens, config); } } const newInstance = new MyNewParser({}); newInstance.input = [ /* token vector */ ];
- Note that the input setter has existed for a while and has been used in the official examples and documentation, therefore it is likely that only the constructor need be modified in existing parsers.
Automatic Concrete Syntax Tree output is now enabled by default. This means that parser which rely on embedded actions must explicitly disable the CST output, for example:
class MyNewParser extends Parser { constructor() { // we have to explicitly disable the CST building for embedded actions to work. super(allTokens, { outputCst: false }); } }
- If a parser already uses CST output no change is needed in 4.0
DSL repetitions no longer return any values in embedded actions mode:
MANY / AT_LEAST_ONE no longer return an array of the iteration results. The iterations results should be collected manually instead:
// Before 4.0.0 const stmts = $.MANY(() => { return $.SUBRULE(Statement); }); // After 4.0.0 const stmts = []; $.MANY(() => { stmts.push($.SUBRULE(Statement)); });
Similarly MANY_SEP / AT_LEAST_ONE_SEP also no longer return any results. These used to return both the repetition result array and an array of separators Tokens consumed. It is still possible to manually collect the repetition results, but not the separator tokens.
This change has no effect when using automatic CST creation.
3.0.0
A CST Node's children dictionary no longer contains empty arrays for unmatched terminals and non-terminals. This means that some existence checks conditions in the CST visitor must be refactored, for example:
class MyVisitor extends SomeBaseVisitor { atomicExpression(ctx) { // BAD - will fail due to "TypeError: Cannot read property '0' of undefined" if (ctx.Integer[0]) { return ctx.Integer[0].image; } // GOOD - safe check if (ctx.Integer) { // if a property exists it's value is guaranteed to have at least one element. return ctx.Identifier[0].image; } } }
2.0.0
The creation of TokenTypes using the class keyword syntax has been soft deprecated. and is no longer officially supported. e.g:
// No longer officially supported class Identifier { static pattern = /[a-zA-Z_]\w+/; } // Use the createToken API instead const Identifier = createToken({ name: "Identifier", pattern: /[a-zA-Z_]\w+/, });
See the reasoning in this issue.
defaultErrorProvider was renamed to defaultParserErrorProvider
All the gast namespace was flattened into the API's root, e.g:
// Old API - using nested namespace. chevrotain.gast.Alternation; // New API - No nested namespaces. chevrotain.Alternation;
The exceptions namespace was also flattened into the API's root.
The constructors of all the gast (Grammar AST) structure have been refactored to use the config object pattern additionally some properties have been renamed or removed. See the new SDK docs for details: