chevrotain
Advanced tools
Comparing version 10.3.0 to 10.4.0
"use strict"; | ||
/* istanbul ignore file - tricky to import some things from this module during testing */ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Parser = exports.createSyntaxDiagramsCode = exports.clearCache = exports.generateCstDts = exports.GAstVisitor = exports.serializeProduction = exports.serializeGrammar = exports.Terminal = exports.Rule = exports.RepetitionWithSeparator = exports.RepetitionMandatoryWithSeparator = exports.RepetitionMandatory = exports.Repetition = exports.Option = exports.NonTerminal = exports.Alternative = exports.Alternation = exports.defaultLexerErrorProvider = exports.NoViableAltException = exports.NotAllInputParsedException = exports.MismatchedTokenException = exports.isRecognitionException = exports.EarlyExitException = exports.defaultParserErrorProvider = exports.tokenName = exports.tokenMatcher = exports.tokenLabel = exports.EOF = exports.createTokenInstance = exports.createToken = exports.LexerDefinitionErrorType = exports.Lexer = exports.EMPTY_ALT = exports.ParserDefinitionErrorType = exports.EmbeddedActionsParser = exports.CstParser = exports.VERSION = void 0; | ||
exports.Parser = exports.createSyntaxDiagramsCode = exports.clearCache = exports.generateCstDts = exports.GAstVisitor = exports.serializeProduction = exports.serializeGrammar = exports.Terminal = exports.Rule = exports.RepetitionWithSeparator = exports.RepetitionMandatoryWithSeparator = exports.RepetitionMandatory = exports.Repetition = exports.Option = exports.NonTerminal = exports.Alternative = exports.Alternation = exports.defaultLexerErrorProvider = exports.NoViableAltException = exports.NotAllInputParsedException = exports.MismatchedTokenException = exports.isRecognitionException = exports.EarlyExitException = exports.defaultParserErrorProvider = exports.LLkLookaheadStrategy = exports.getLookaheadPaths = exports.tokenName = exports.tokenMatcher = exports.tokenLabel = exports.EOF = exports.createTokenInstance = exports.createToken = exports.LexerDefinitionErrorType = exports.Lexer = exports.EMPTY_ALT = exports.ParserDefinitionErrorType = exports.EmbeddedActionsParser = exports.CstParser = exports.VERSION = void 0; | ||
// semantic version | ||
@@ -24,2 +24,7 @@ var version_1 = require("./version"); | ||
Object.defineProperty(exports, "tokenName", { enumerable: true, get: function () { return tokens_public_1.tokenName; } }); | ||
// Lookahead | ||
var lookahead_1 = require("./parse/grammar/lookahead"); | ||
Object.defineProperty(exports, "getLookaheadPaths", { enumerable: true, get: function () { return lookahead_1.getLookaheadPaths; } }); | ||
var llk_lookahead_1 = require("./parse/grammar/llk_lookahead"); | ||
Object.defineProperty(exports, "LLkLookaheadStrategy", { enumerable: true, get: function () { return llk_lookahead_1.LLkLookaheadStrategy; } }); | ||
// Other Utilities | ||
@@ -26,0 +31,0 @@ var errors_public_1 = require("./parse/errors_public"); |
@@ -17,2 +17,13 @@ "use strict"; | ||
})(); | ||
var __assign = (this && this.__assign) || function () { | ||
__assign = Object.assign || function(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) | ||
t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
@@ -22,3 +33,3 @@ return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.checkPrefixAlternativesAmbiguities = exports.validateSomeNonEmptyLookaheadPath = exports.validateTooManyAlts = exports.RepetitionCollector = exports.validateAmbiguousAlternationAlternatives = exports.validateEmptyOrAlternative = exports.getFirstNoneTerminal = exports.validateNoLeftRecursion = exports.validateRuleIsOverridden = exports.validateRuleDoesNotAlreadyExist = exports.OccurrenceValidationCollector = exports.identifyProductionForDuplicates = exports.validateGrammar = void 0; | ||
exports.checkPrefixAlternativesAmbiguities = exports.validateSomeNonEmptyLookaheadPath = exports.validateTooManyAlts = exports.RepetitionCollector = exports.validateAmbiguousAlternationAlternatives = exports.validateEmptyOrAlternative = exports.getFirstNoneTerminal = exports.validateNoLeftRecursion = exports.validateRuleIsOverridden = exports.validateRuleDoesNotAlreadyExist = exports.OccurrenceValidationCollector = exports.identifyProductionForDuplicates = exports.validateGrammar = exports.validateLookahead = void 0; | ||
var first_1 = __importDefault(require("lodash/first")); | ||
@@ -49,23 +60,13 @@ var isEmpty_1 = __importDefault(require("lodash/isEmpty")); | ||
var tokens_1 = require("../../scan/tokens"); | ||
function validateGrammar(topLevels, globalMaxLookahead, tokenTypes, errMsgProvider, grammarName) { | ||
var duplicateErrors = (0, flatMap_1.default)(topLevels, function (currTopLevel) { | ||
return validateDuplicateProductions(currTopLevel, errMsgProvider); | ||
function validateLookahead(options) { | ||
var lookaheadValidationErrorMessages = options.lookaheadStrategy.validate({ | ||
rules: options.rules, | ||
tokenTypes: options.tokenTypes, | ||
grammarName: options.grammarName | ||
}); | ||
var leftRecursionErrors = (0, flatMap_1.default)(topLevels, function (currTopRule) { | ||
return validateNoLeftRecursion(currTopRule, currTopRule, errMsgProvider); | ||
}); | ||
var emptyAltErrors = []; | ||
var ambiguousAltsErrors = []; | ||
var emptyRepetitionErrors = []; | ||
// left recursion could cause infinite loops in the following validations. | ||
// It is safest to first have the user fix the left recursion errors first and only then examine Further issues. | ||
if ((0, isEmpty_1.default)(leftRecursionErrors)) { | ||
emptyAltErrors = (0, flatMap_1.default)(topLevels, function (currTopRule) { | ||
return validateEmptyOrAlternative(currTopRule, errMsgProvider); | ||
}); | ||
ambiguousAltsErrors = (0, flatMap_1.default)(topLevels, function (currTopRule) { | ||
return validateAmbiguousAlternationAlternatives(currTopRule, globalMaxLookahead, errMsgProvider); | ||
}); | ||
emptyRepetitionErrors = validateSomeNonEmptyLookaheadPath(topLevels, globalMaxLookahead, errMsgProvider); | ||
} | ||
return (0, map_1.default)(lookaheadValidationErrorMessages, function (errorMessage) { return (__assign({ type: parser_1.ParserDefinitionErrorType.CUSTOM_LOOKAHEAD_VALIDATION }, errorMessage)); }); | ||
} | ||
exports.validateLookahead = validateLookahead; | ||
function validateGrammar(topLevels, tokenTypes, errMsgProvider, grammarName) { | ||
var duplicateErrors = (0, flatMap_1.default)(topLevels, function (currTopLevel) { return validateDuplicateProductions(currTopLevel, errMsgProvider); }); | ||
var termsNamespaceConflictErrors = checkTerminalAndNoneTerminalsNameSpace(topLevels, tokenTypes, errMsgProvider); | ||
@@ -78,3 +79,3 @@ var tooManyAltsErrors = (0, flatMap_1.default)(topLevels, function (curRule) { | ||
}); | ||
return duplicateErrors.concat(emptyRepetitionErrors, leftRecursionErrors, emptyAltErrors, ambiguousAltsErrors, termsNamespaceConflictErrors, tooManyAltsErrors, duplicateRulesError); | ||
return duplicateErrors.concat(termsNamespaceConflictErrors, tooManyAltsErrors, duplicateRulesError); | ||
} | ||
@@ -81,0 +82,0 @@ exports.validateGrammar = validateGrammar; |
@@ -27,5 +27,5 @@ "use strict"; | ||
}); | ||
return (0, checks_1.validateGrammar)(options.rules, options.maxLookahead, options.tokenTypes, options.errMsgProvider, options.grammarName); | ||
return (0, checks_1.validateGrammar)(options.rules, options.tokenTypes, options.errMsgProvider, options.grammarName); | ||
} | ||
exports.validateGrammar = validateGrammar; | ||
//# sourceMappingURL=gast_resolver_public.js.map |
@@ -21,3 +21,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.areTokenCategoriesNotUsed = exports.isStrictPrefixOfPath = exports.containsPath = exports.getLookaheadPathsForOptionalProd = exports.getLookaheadPathsForOr = exports.lookAheadSequenceFromAlternatives = exports.buildSingleAlternativeLookaheadFunction = exports.buildAlternativesLookAheadFunc = exports.buildLookaheadFuncForOptionalProd = exports.buildLookaheadFuncForOr = exports.getProdType = exports.PROD_TYPE = void 0; | ||
exports.areTokenCategoriesNotUsed = exports.isStrictPrefixOfPath = exports.containsPath = exports.getLookaheadPathsForOptionalProd = exports.getLookaheadPathsForOr = exports.lookAheadSequenceFromAlternatives = exports.buildSingleAlternativeLookaheadFunction = exports.buildAlternativesLookAheadFunc = exports.buildLookaheadFuncForOptionalProd = exports.buildLookaheadFuncForOr = exports.getLookaheadPaths = exports.getProdType = exports.PROD_TYPE = void 0; | ||
var isEmpty_1 = __importDefault(require("lodash/isEmpty")); | ||
@@ -46,18 +46,21 @@ var flatten_1 = __importDefault(require("lodash/flatten")); | ||
/* istanbul ignore else */ | ||
if (prod instanceof gast_1.Option) { | ||
if (prod instanceof gast_1.Option || prod === "Option") { | ||
return PROD_TYPE.OPTION; | ||
} | ||
else if (prod instanceof gast_1.Repetition) { | ||
else if (prod instanceof gast_1.Repetition || prod === "Repetition") { | ||
return PROD_TYPE.REPETITION; | ||
} | ||
else if (prod instanceof gast_1.RepetitionMandatory) { | ||
else if (prod instanceof gast_1.RepetitionMandatory || | ||
prod === "RepetitionMandatory") { | ||
return PROD_TYPE.REPETITION_MANDATORY; | ||
} | ||
else if (prod instanceof gast_1.RepetitionMandatoryWithSeparator) { | ||
else if (prod instanceof gast_1.RepetitionMandatoryWithSeparator || | ||
prod === "RepetitionMandatoryWithSeparator") { | ||
return PROD_TYPE.REPETITION_MANDATORY_WITH_SEPARATOR; | ||
} | ||
else if (prod instanceof gast_1.RepetitionWithSeparator) { | ||
else if (prod instanceof gast_1.RepetitionWithSeparator || | ||
prod === "RepetitionWithSeparator") { | ||
return PROD_TYPE.REPETITION_WITH_SEPARATOR; | ||
} | ||
else if (prod instanceof gast_1.Alternation) { | ||
else if (prod instanceof gast_1.Alternation || prod === "Alternation") { | ||
return PROD_TYPE.ALTERNATION; | ||
@@ -70,2 +73,13 @@ } | ||
exports.getProdType = getProdType; | ||
function getLookaheadPaths(options) { | ||
var occurrence = options.occurrence, rule = options.rule, prodType = options.prodType, maxLookahead = options.maxLookahead; | ||
var type = getProdType(prodType); | ||
if (type === PROD_TYPE.ALTERNATION) { | ||
return getLookaheadPathsForOr(occurrence, rule, maxLookahead); | ||
} | ||
else { | ||
return getLookaheadPathsForOptionalProd(occurrence, rule, type, maxLookahead); | ||
} | ||
} | ||
exports.getLookaheadPaths = getLookaheadPaths; | ||
function buildLookaheadFuncForOr(occurrence, ruleGrammar, maxLookahead, hasPredicates, dynamicTokensEnabled, laFuncBuilder) { | ||
@@ -72,0 +86,0 @@ var lookAheadPaths = getLookaheadPathsForOr(occurrence, ruleGrammar, maxLookahead); |
@@ -44,2 +44,3 @@ "use strict"; | ||
var apply_mixins_1 = require("./utils/apply_mixins"); | ||
var checks_1 = require("../grammar/checks"); | ||
exports.END_OF_FILE = (0, tokens_public_1.createTokenInstance)(tokens_public_1.EOF, "", NaN, NaN, NaN, NaN, NaN, NaN); | ||
@@ -76,2 +77,3 @@ Object.freeze(exports.END_OF_FILE); | ||
ParserDefinitionErrorType[ParserDefinitionErrorType["TOO_MANY_ALTS"] = 12] = "TOO_MANY_ALTS"; | ||
ParserDefinitionErrorType[ParserDefinitionErrorType["CUSTOM_LOOKAHEAD_VALIDATION"] = 13] = "CUSTOM_LOOKAHEAD_VALIDATION"; | ||
})(ParserDefinitionErrorType = exports.ParserDefinitionErrorType || (exports.ParserDefinitionErrorType = {})); | ||
@@ -159,3 +161,2 @@ function EMPTY_ALT(value) { | ||
rules: (0, values_1.default)(_this.gastProductionsCache), | ||
maxLookahead: _this.maxLookahead, | ||
tokenTypes: (0, values_1.default)(_this.tokensMap), | ||
@@ -165,3 +166,9 @@ errMsgProvider: errors_public_1.defaultGrammarValidatorErrorProvider, | ||
}); | ||
_this.definitionErrors = _this.definitionErrors.concat(validationErrors); | ||
var lookaheadValidationErrors = (0, checks_1.validateLookahead)({ | ||
lookaheadStrategy: _this.lookaheadStrategy, | ||
rules: (0, values_1.default)(_this.gastProductionsCache), | ||
tokenTypes: (0, values_1.default)(_this.tokensMap), | ||
grammarName: className | ||
}); | ||
_this.definitionErrors = _this.definitionErrors.concat(validationErrors, lookaheadValidationErrors); | ||
} | ||
@@ -168,0 +175,0 @@ }); |
@@ -22,3 +22,2 @@ "use strict"; | ||
exports.collectMethods = exports.LooksAhead = void 0; | ||
var lookahead_1 = require("../../grammar/lookahead"); | ||
var forEach_1 = __importDefault(require("lodash/forEach")); | ||
@@ -30,2 +29,3 @@ var has_1 = __importDefault(require("lodash/has")); | ||
var gast_2 = require("@chevrotain/gast"); | ||
var llk_lookahead_1 = require("../../grammar/llk_lookahead"); | ||
/** | ||
@@ -44,2 +44,5 @@ * Trait responsible for the lookahead related utilities and optimizations. | ||
: parser_1.DEFAULT_PARSER_CONFIG.maxLookahead; | ||
this.lookaheadStrategy = (0, has_1.default)(config, "lookaheadStrategy") | ||
? config.lookaheadStrategy // assumes end user provides the correct config value/type | ||
: new llk_lookahead_1.LLkLookaheadStrategy({ maxLookahead: this.maxLookahead }); | ||
this.lookAheadFuncsCache = new Map(); | ||
@@ -55,3 +58,9 @@ }; | ||
_this.TRACE_INIT("".concat((0, gast_2.getProductionDslName)(currProd)).concat(prodIdx), function () { | ||
var laFunc = (0, lookahead_1.buildLookaheadFuncForOr)(currProd.idx, currRule, currProd.maxLookahead || _this.maxLookahead, currProd.hasPredicates, _this.dynamicTokensEnabled, _this.lookAheadBuilderForAlternatives); | ||
var laFunc = _this.lookaheadStrategy.buildLookaheadForAlternation({ | ||
prodOccurrence: currProd.idx, | ||
rule: currRule, | ||
maxLookahead: currProd.maxLookahead || _this.maxLookahead, | ||
hasPredicates: currProd.hasPredicates, | ||
dynamicTokensEnabled: _this.dynamicTokensEnabled | ||
}); | ||
var key = (0, keys_1.getKeyForAutomaticLookahead)(_this.fullRuleNameToShort[currRule.name], keys_1.OR_IDX, currProd.idx); | ||
@@ -62,15 +71,15 @@ _this.setLaFuncCache(key, laFunc); | ||
(0, forEach_1.default)(repetition, function (currProd) { | ||
_this.computeLookaheadFunc(currRule, currProd.idx, keys_1.MANY_IDX, lookahead_1.PROD_TYPE.REPETITION, currProd.maxLookahead, (0, gast_2.getProductionDslName)(currProd)); | ||
_this.computeLookaheadFunc(currRule, currProd.idx, keys_1.MANY_IDX, "Repetition", currProd.maxLookahead, (0, gast_2.getProductionDslName)(currProd)); | ||
}); | ||
(0, forEach_1.default)(option, function (currProd) { | ||
_this.computeLookaheadFunc(currRule, currProd.idx, keys_1.OPTION_IDX, lookahead_1.PROD_TYPE.OPTION, currProd.maxLookahead, (0, gast_2.getProductionDslName)(currProd)); | ||
_this.computeLookaheadFunc(currRule, currProd.idx, keys_1.OPTION_IDX, "Option", currProd.maxLookahead, (0, gast_2.getProductionDslName)(currProd)); | ||
}); | ||
(0, forEach_1.default)(repetitionMandatory, function (currProd) { | ||
_this.computeLookaheadFunc(currRule, currProd.idx, keys_1.AT_LEAST_ONE_IDX, lookahead_1.PROD_TYPE.REPETITION_MANDATORY, currProd.maxLookahead, (0, gast_2.getProductionDslName)(currProd)); | ||
_this.computeLookaheadFunc(currRule, currProd.idx, keys_1.AT_LEAST_ONE_IDX, "RepetitionMandatory", currProd.maxLookahead, (0, gast_2.getProductionDslName)(currProd)); | ||
}); | ||
(0, forEach_1.default)(repetitionMandatoryWithSeparator, function (currProd) { | ||
_this.computeLookaheadFunc(currRule, currProd.idx, keys_1.AT_LEAST_ONE_SEP_IDX, lookahead_1.PROD_TYPE.REPETITION_MANDATORY_WITH_SEPARATOR, currProd.maxLookahead, (0, gast_2.getProductionDslName)(currProd)); | ||
_this.computeLookaheadFunc(currRule, currProd.idx, keys_1.AT_LEAST_ONE_SEP_IDX, "RepetitionMandatoryWithSeparator", currProd.maxLookahead, (0, gast_2.getProductionDslName)(currProd)); | ||
}); | ||
(0, forEach_1.default)(repetitionWithSeparator, function (currProd) { | ||
_this.computeLookaheadFunc(currRule, currProd.idx, keys_1.MANY_SEP_IDX, lookahead_1.PROD_TYPE.REPETITION_WITH_SEPARATOR, currProd.maxLookahead, (0, gast_2.getProductionDslName)(currProd)); | ||
_this.computeLookaheadFunc(currRule, currProd.idx, keys_1.MANY_SEP_IDX, "RepetitionWithSeparator", currProd.maxLookahead, (0, gast_2.getProductionDslName)(currProd)); | ||
}); | ||
@@ -83,3 +92,9 @@ }); | ||
this.TRACE_INIT("".concat(dslMethodName).concat(prodOccurrence === 0 ? "" : prodOccurrence), function () { | ||
var laFunc = (0, lookahead_1.buildLookaheadFuncForOptionalProd)(prodOccurrence, rule, prodMaxLookahead || _this.maxLookahead, _this.dynamicTokensEnabled, prodType, _this.lookAheadBuilderForOptional); | ||
var laFunc = _this.lookaheadStrategy.buildLookaheadForOptional({ | ||
prodOccurrence: prodOccurrence, | ||
rule: rule, | ||
maxLookahead: prodMaxLookahead || _this.maxLookahead, | ||
dynamicTokensEnabled: _this.dynamicTokensEnabled, | ||
prodType: prodType | ||
}); | ||
var key = (0, keys_1.getKeyForAutomaticLookahead)(_this.fullRuleNameToShort[rule.name], prodKey, prodOccurrence); | ||
@@ -89,8 +104,2 @@ _this.setLaFuncCache(key, laFunc); | ||
}; | ||
LooksAhead.prototype.lookAheadBuilderForOptional = function (alt, tokenMatcher, dynamicTokensEnabled) { | ||
return (0, lookahead_1.buildSingleAlternativeLookaheadFunction)(alt, tokenMatcher, dynamicTokensEnabled); | ||
}; | ||
LooksAhead.prototype.lookAheadBuilderForAlternatives = function (alts, hasPredicates, tokenMatcher, dynamicTokensEnabled) { | ||
return (0, lookahead_1.buildAlternativesLookAheadFunc)(alts, hasPredicates, tokenMatcher, dynamicTokensEnabled); | ||
}; | ||
// this actually returns a number, but it is always used as a string (object prop key) | ||
@@ -97,0 +106,0 @@ LooksAhead.prototype.getKeyForAutomaticLookahead = function (dslMethodIdx, occurrence) { |
@@ -7,3 +7,3 @@ "use strict"; | ||
// A separate file avoids cyclic dependencies and webpack errors. | ||
exports.VERSION = "10.3.0"; | ||
exports.VERSION = "10.4.0"; | ||
//# sourceMappingURL=version.js.map |
{ | ||
"name": "chevrotain", | ||
"version": "10.3.0", | ||
"version": "10.4.0", | ||
"description": "Chevrotain is a high performance fault tolerant javascript parsing DSL for building recursive decent parsers", | ||
@@ -75,6 +75,6 @@ "keywords": [ | ||
"dependencies": { | ||
"@chevrotain/cst-dts-gen": "10.3.0", | ||
"@chevrotain/gast": "10.3.0", | ||
"@chevrotain/types": "10.3.0", | ||
"@chevrotain/utils": "10.3.0", | ||
"@chevrotain/cst-dts-gen": "10.4.0", | ||
"@chevrotain/gast": "10.4.0", | ||
"@chevrotain/types": "10.4.0", | ||
"@chevrotain/utils": "10.4.0", | ||
"lodash": "4.17.21", | ||
@@ -97,3 +97,3 @@ "regexp-to-ast": "0.5.0" | ||
}, | ||
"gitHead": "5ca7d276f475839c815a2686f38e2814371935c9" | ||
"gitHead": "55b21562f046b11ccd9fdb06f7ccb4ed3e315116" | ||
} |
@@ -25,2 +25,8 @@ /* istanbul ignore file - tricky to import some things from this module during testing */ | ||
// Lookahead | ||
export { getLookaheadPaths } from "./parse/grammar/lookahead" | ||
export { LLkLookaheadStrategy } from "./parse/grammar/llk_lookahead" | ||
// Other Utilities | ||
@@ -27,0 +33,0 @@ |
@@ -42,3 +42,2 @@ import first from "lodash/first" | ||
RepetitionWithSeparator, | ||
Rule, | ||
Terminal | ||
@@ -48,5 +47,7 @@ } from "@chevrotain/gast" | ||
import { | ||
ILookaheadStrategy, | ||
IProduction, | ||
IProductionWithOccurrence, | ||
TokenType | ||
TokenType, | ||
Rule | ||
} from "@chevrotain/types" | ||
@@ -61,5 +62,21 @@ import { | ||
export function validateLookahead(options: { | ||
lookaheadStrategy: ILookaheadStrategy | ||
rules: Rule[] | ||
tokenTypes: TokenType[] | ||
grammarName: string | ||
}): IParserDefinitionError[] { | ||
const lookaheadValidationErrorMessages = options.lookaheadStrategy.validate({ | ||
rules: options.rules, | ||
tokenTypes: options.tokenTypes, | ||
grammarName: options.grammarName | ||
}) | ||
return map(lookaheadValidationErrorMessages, (errorMessage) => ({ | ||
type: ParserDefinitionErrorType.CUSTOM_LOOKAHEAD_VALIDATION, | ||
...errorMessage | ||
})) | ||
} | ||
export function validateGrammar( | ||
topLevels: Rule[], | ||
globalMaxLookahead: number, | ||
tokenTypes: TokenType[], | ||
@@ -69,34 +86,7 @@ errMsgProvider: IGrammarValidatorErrorMessageProvider, | ||
): IParserDefinitionError[] { | ||
const duplicateErrors = flatMap(topLevels, (currTopLevel) => | ||
validateDuplicateProductions(currTopLevel, errMsgProvider) | ||
const duplicateErrors: IParserDefinitionError[] = flatMap( | ||
topLevels, | ||
(currTopLevel) => validateDuplicateProductions(currTopLevel, errMsgProvider) | ||
) | ||
const leftRecursionErrors = flatMap(topLevels, (currTopRule) => | ||
validateNoLeftRecursion(currTopRule, currTopRule, errMsgProvider) | ||
) | ||
let emptyAltErrors: IParserEmptyAlternativeDefinitionError[] = [] | ||
let ambiguousAltsErrors: IParserAmbiguousAlternativesDefinitionError[] = [] | ||
let emptyRepetitionErrors: IParserDefinitionError[] = [] | ||
// left recursion could cause infinite loops in the following validations. | ||
// It is safest to first have the user fix the left recursion errors first and only then examine Further issues. | ||
if (isEmpty(leftRecursionErrors)) { | ||
emptyAltErrors = flatMap(topLevels, (currTopRule) => | ||
validateEmptyOrAlternative(currTopRule, errMsgProvider) | ||
) | ||
ambiguousAltsErrors = flatMap(topLevels, (currTopRule) => | ||
validateAmbiguousAlternationAlternatives( | ||
currTopRule, | ||
globalMaxLookahead, | ||
errMsgProvider | ||
) | ||
) | ||
emptyRepetitionErrors = validateSomeNonEmptyLookaheadPath( | ||
topLevels, | ||
globalMaxLookahead, | ||
errMsgProvider | ||
) | ||
} | ||
const termsNamespaceConflictErrors = checkTerminalAndNoneTerminalsNameSpace( | ||
@@ -121,7 +111,3 @@ topLevels, | ||
return (duplicateErrors as IParserDefinitionError[]).concat( | ||
emptyRepetitionErrors, | ||
leftRecursionErrors, | ||
emptyAltErrors, | ||
ambiguousAltsErrors, | ||
return duplicateErrors.concat( | ||
termsNamespaceConflictErrors, | ||
@@ -300,3 +286,3 @@ tooManyAltsErrors, | ||
const ruleName = topRule.name | ||
const foundLeftRecursion = includes(<any>nextNonTerminals, topRule) | ||
const foundLeftRecursion = includes(nextNonTerminals, topRule) | ||
if (foundLeftRecursion) { | ||
@@ -303,0 +289,0 @@ errors.push({ |
@@ -37,3 +37,2 @@ import { Rule } from "@chevrotain/gast" | ||
rules: Rule[] | ||
maxLookahead: number | ||
tokenTypes: TokenType[] | ||
@@ -49,3 +48,2 @@ grammarName: string | ||
options.rules, | ||
options.maxLookahead, | ||
options.tokenTypes, | ||
@@ -52,0 +50,0 @@ options.errMsgProvider, |
@@ -10,3 +10,3 @@ import isEmpty from "lodash/isEmpty" | ||
import { RestWalker } from "./rest" | ||
import { Predicate, TokenMatcher, LookAheadSequence } from "../parser/parser" | ||
import { Predicate, TokenMatcher } from "../parser/parser" | ||
import { | ||
@@ -23,4 +23,3 @@ tokenStructuredMatcher, | ||
RepetitionMandatoryWithSeparator, | ||
RepetitionWithSeparator, | ||
Rule | ||
RepetitionWithSeparator | ||
} from "@chevrotain/gast" | ||
@@ -32,3 +31,7 @@ import { GAstVisitor } from "@chevrotain/gast" | ||
IProductionWithOccurrence, | ||
TokenType | ||
LookaheadSequence, | ||
LookaheadProductionType, | ||
Rule, | ||
TokenType, | ||
BaseParser | ||
} from "@chevrotain/types" | ||
@@ -45,15 +48,26 @@ | ||
export function getProdType(prod: IProduction): PROD_TYPE { | ||
export function getProdType( | ||
prod: IProduction | LookaheadProductionType | ||
): PROD_TYPE { | ||
/* istanbul ignore else */ | ||
if (prod instanceof Option) { | ||
if (prod instanceof Option || prod === "Option") { | ||
return PROD_TYPE.OPTION | ||
} else if (prod instanceof Repetition) { | ||
} else if (prod instanceof Repetition || prod === "Repetition") { | ||
return PROD_TYPE.REPETITION | ||
} else if (prod instanceof RepetitionMandatory) { | ||
} else if ( | ||
prod instanceof RepetitionMandatory || | ||
prod === "RepetitionMandatory" | ||
) { | ||
return PROD_TYPE.REPETITION_MANDATORY | ||
} else if (prod instanceof RepetitionMandatoryWithSeparator) { | ||
} else if ( | ||
prod instanceof RepetitionMandatoryWithSeparator || | ||
prod === "RepetitionMandatoryWithSeparator" | ||
) { | ||
return PROD_TYPE.REPETITION_MANDATORY_WITH_SEPARATOR | ||
} else if (prod instanceof RepetitionWithSeparator) { | ||
} else if ( | ||
prod instanceof RepetitionWithSeparator || | ||
prod === "RepetitionWithSeparator" | ||
) { | ||
return PROD_TYPE.REPETITION_WITH_SEPARATOR | ||
} else if (prod instanceof Alternation) { | ||
} else if (prod instanceof Alternation || prod === "Alternation") { | ||
return PROD_TYPE.ALTERNATION | ||
@@ -65,2 +79,22 @@ } else { | ||
export function getLookaheadPaths(options: { | ||
occurrence: number | ||
rule: Rule | ||
prodType: LookaheadProductionType | ||
maxLookahead: number | ||
}): LookaheadSequence[] { | ||
const { occurrence, rule, prodType, maxLookahead } = options | ||
const type = getProdType(prodType) | ||
if (type === PROD_TYPE.ALTERNATION) { | ||
return getLookaheadPathsForOr(occurrence, rule, maxLookahead) | ||
} else { | ||
return getLookaheadPathsForOptionalProd( | ||
occurrence, | ||
rule, | ||
type, | ||
maxLookahead | ||
) | ||
} | ||
} | ||
export function buildLookaheadFuncForOr( | ||
@@ -73,3 +107,3 @@ occurrence: number, | ||
laFuncBuilder: Function | ||
): (orAlts?: IOrAlt<any>[]) => number { | ||
): (orAlts?: IOrAlt<any>[]) => number | undefined { | ||
const lookAheadPaths = getLookaheadPathsForOr( | ||
@@ -112,3 +146,3 @@ occurrence, | ||
lookaheadBuilder: ( | ||
lookAheadSequence: LookAheadSequence, | ||
lookAheadSequence: LookaheadSequence, | ||
tokenMatcher: TokenMatcher, | ||
@@ -135,3 +169,3 @@ dynamicTokensEnabled: boolean | ||
export function buildAlternativesLookAheadFunc( | ||
alts: LookAheadSequence[], | ||
alts: LookaheadSequence[], | ||
hasPredicates: boolean, | ||
@@ -153,3 +187,6 @@ tokenMatcher: TokenMatcher, | ||
*/ | ||
return function (orAlts: IOrAlt<any>[]): number | undefined { | ||
return function ( | ||
this: BaseParser, | ||
orAlts: IOrAlt<any>[] | ||
): number | undefined { | ||
// unfortunately the predicates must be extracted every single time | ||
@@ -221,3 +258,3 @@ // as they cannot be cached due to references to parameters(vars) which are no longer valid. | ||
*/ | ||
return function (): number { | ||
return function (this: BaseParser): number { | ||
const nextToken = this.LA(1) | ||
@@ -232,3 +269,3 @@ return choiceToAlt[nextToken.tokenTypeIdx] | ||
*/ | ||
return function (): number | undefined { | ||
return function (this: BaseParser): number | undefined { | ||
for (let t = 0; t < numOfAlts; t++) { | ||
@@ -262,3 +299,3 @@ const currAlt = alts[t] | ||
export function buildSingleAlternativeLookaheadFunction( | ||
alt: LookAheadSequence, | ||
alt: LookaheadSequence, | ||
tokenMatcher: TokenMatcher, | ||
@@ -285,3 +322,3 @@ dynamicTokensEnabled: boolean | ||
return function (): boolean { | ||
return function (this: BaseParser): boolean { | ||
return this.LA(1).tokenTypeIdx === expectedTokenUniqueKey | ||
@@ -302,3 +339,3 @@ } | ||
return function (): boolean { | ||
return function (this: BaseParser): boolean { | ||
const nextToken = this.LA(1) | ||
@@ -309,3 +346,3 @@ return choiceToAlt[nextToken.tokenTypeIdx] === true | ||
} else { | ||
return function (): boolean { | ||
return function (this: BaseParser): boolean { | ||
nextPath: for (let j = 0; j < numOfPaths; j++) { | ||
@@ -556,3 +593,3 @@ const currPath = alt[j] | ||
k: number | ||
): LookAheadSequence[] { | ||
): LookaheadSequence[] { | ||
const partialAlts = map(altsDefs, (currAlt) => | ||
@@ -634,3 +671,3 @@ possiblePathsFrom([currAlt], 1) | ||
orProd?: Alternation | ||
): LookAheadSequence[] { | ||
): LookaheadSequence[] { | ||
const visitor = new InsideDefinitionFinderVisitor( | ||
@@ -650,3 +687,3 @@ occurrence, | ||
k: number | ||
): LookAheadSequence[] { | ||
): LookaheadSequence[] { | ||
const insideDefVisitor = new InsideDefinitionFinderVisitor( | ||
@@ -715,3 +752,3 @@ occurrence, | ||
export function areTokenCategoriesNotUsed( | ||
lookAheadPaths: LookAheadSequence[] | ||
lookAheadPaths: LookaheadSequence[] | ||
): boolean { | ||
@@ -718,0 +755,0 @@ return every(lookAheadPaths, (singleAltPaths) => |
@@ -28,3 +28,4 @@ import { | ||
AMBIGUOUS_PREFIX_ALTS = 11, | ||
TOO_MANY_ALTS = 12 | ||
TOO_MANY_ALTS = 12, | ||
CUSTOM_LOOKAHEAD_VALIDATION = 13 | ||
} | ||
@@ -31,0 +32,0 @@ |
@@ -43,2 +43,3 @@ import isEmpty from "lodash/isEmpty" | ||
import { IParserConfigInternal, ParserMethodInternal } from "./types" | ||
import { validateLookahead } from "../grammar/checks" | ||
@@ -59,16 +60,15 @@ export const END_OF_FILE = createTokenInstance( | ||
export type LookAheadSequence = TokenType[][] | ||
export const DEFAULT_PARSER_CONFIG: Required< | ||
Omit<IParserConfigInternal, "lookaheadStrategy"> | ||
> = Object.freeze({ | ||
recoveryEnabled: false, | ||
maxLookahead: 3, | ||
dynamicTokensEnabled: false, | ||
outputCst: true, | ||
errorMessageProvider: defaultParserErrorProvider, | ||
nodeLocationTracking: "none", | ||
traceInitPerf: false, | ||
skipValidations: false | ||
}) | ||
export const DEFAULT_PARSER_CONFIG: Required<IParserConfigInternal> = | ||
Object.freeze({ | ||
recoveryEnabled: false, | ||
maxLookahead: 3, | ||
dynamicTokensEnabled: false, | ||
outputCst: true, | ||
errorMessageProvider: defaultParserErrorProvider, | ||
nodeLocationTracking: "none", | ||
traceInitPerf: false, | ||
skipValidations: false | ||
}) | ||
export const DEFAULT_RULE_CONFIG: Required<IRuleConfig<any>> = Object.freeze({ | ||
@@ -92,3 +92,4 @@ recoveryValueFunc: () => undefined, | ||
AMBIGUOUS_PREFIX_ALTS = 11, | ||
TOO_MANY_ALTS = 12 | ||
TOO_MANY_ALTS = 12, | ||
CUSTOM_LOOKAHEAD_VALIDATION = 13 | ||
} | ||
@@ -207,3 +208,2 @@ | ||
rules: values(this.gastProductionsCache), | ||
maxLookahead: this.maxLookahead, | ||
tokenTypes: values(this.tokensMap), | ||
@@ -213,3 +213,12 @@ errMsgProvider: defaultGrammarValidatorErrorProvider, | ||
}) | ||
this.definitionErrors = this.definitionErrors.concat(validationErrors) | ||
const lookaheadValidationErrors = validateLookahead({ | ||
lookaheadStrategy: this.lookaheadStrategy, | ||
rules: values(this.gastProductionsCache), | ||
tokenTypes: values(this.tokensMap), | ||
grammarName: className | ||
}) | ||
this.definitionErrors = this.definitionErrors.concat( | ||
validationErrors, | ||
lookaheadValidationErrors | ||
) | ||
} | ||
@@ -216,0 +225,0 @@ }) |
@@ -1,16 +0,9 @@ | ||
import { | ||
buildAlternativesLookAheadFunc, | ||
buildLookaheadFuncForOptionalProd, | ||
buildLookaheadFuncForOr, | ||
buildSingleAlternativeLookaheadFunction, | ||
PROD_TYPE | ||
} from "../../grammar/lookahead" | ||
import forEach from "lodash/forEach" | ||
import has from "lodash/has" | ||
import { DEFAULT_PARSER_CONFIG } from "../parser" | ||
import { | ||
DEFAULT_PARSER_CONFIG, | ||
LookAheadSequence, | ||
TokenMatcher | ||
} from "../parser" | ||
import { IOrAlt, IParserConfig } from "@chevrotain/types" | ||
ILookaheadStrategy, | ||
IParserConfig, | ||
OptionalProductionType | ||
} from "@chevrotain/types" | ||
import { | ||
@@ -37,2 +30,3 @@ AT_LEAST_ONE_IDX, | ||
import { getProductionDslName } from "@chevrotain/gast" | ||
import { LLkLookaheadStrategy } from "../../grammar/llk_lookahead" | ||
@@ -46,2 +40,3 @@ /** | ||
dynamicTokensEnabled: boolean | ||
lookaheadStrategy: ILookaheadStrategy | ||
@@ -57,2 +52,6 @@ initLooksAhead(config: IParserConfig) { | ||
this.lookaheadStrategy = has(config, "lookaheadStrategy") | ||
? (config.lookaheadStrategy as ILookaheadStrategy) // assumes end user provides the correct config value/type | ||
: new LLkLookaheadStrategy({ maxLookahead: this.maxLookahead }) | ||
this.lookAheadFuncsCache = new Map() | ||
@@ -76,10 +75,9 @@ } | ||
this.TRACE_INIT(`${getProductionDslName(currProd)}${prodIdx}`, () => { | ||
const laFunc = buildLookaheadFuncForOr( | ||
currProd.idx, | ||
currRule, | ||
currProd.maxLookahead || this.maxLookahead, | ||
currProd.hasPredicates, | ||
this.dynamicTokensEnabled, | ||
this.lookAheadBuilderForAlternatives | ||
) | ||
const laFunc = this.lookaheadStrategy.buildLookaheadForAlternation({ | ||
prodOccurrence: currProd.idx, | ||
rule: currRule, | ||
maxLookahead: currProd.maxLookahead || this.maxLookahead, | ||
hasPredicates: currProd.hasPredicates, | ||
dynamicTokensEnabled: this.dynamicTokensEnabled | ||
}) | ||
@@ -100,3 +98,3 @@ const key = getKeyForAutomaticLookahead( | ||
MANY_IDX, | ||
PROD_TYPE.REPETITION, | ||
"Repetition", | ||
currProd.maxLookahead, | ||
@@ -112,3 +110,3 @@ getProductionDslName(currProd) | ||
OPTION_IDX, | ||
PROD_TYPE.OPTION, | ||
"Option", | ||
currProd.maxLookahead, | ||
@@ -124,3 +122,3 @@ getProductionDslName(currProd) | ||
AT_LEAST_ONE_IDX, | ||
PROD_TYPE.REPETITION_MANDATORY, | ||
"RepetitionMandatory", | ||
currProd.maxLookahead, | ||
@@ -136,3 +134,3 @@ getProductionDslName(currProd) | ||
AT_LEAST_ONE_SEP_IDX, | ||
PROD_TYPE.REPETITION_MANDATORY_WITH_SEPARATOR, | ||
"RepetitionMandatoryWithSeparator", | ||
currProd.maxLookahead, | ||
@@ -148,3 +146,3 @@ getProductionDslName(currProd) | ||
MANY_SEP_IDX, | ||
PROD_TYPE.REPETITION_WITH_SEPARATOR, | ||
"RepetitionWithSeparator", | ||
currProd.maxLookahead, | ||
@@ -163,3 +161,3 @@ getProductionDslName(currProd) | ||
prodKey: number, | ||
prodType: PROD_TYPE, | ||
prodType: OptionalProductionType, | ||
prodMaxLookahead: number | undefined, | ||
@@ -171,10 +169,9 @@ dslMethodName: string | ||
() => { | ||
const laFunc = buildLookaheadFuncForOptionalProd( | ||
const laFunc = this.lookaheadStrategy.buildLookaheadForOptional({ | ||
prodOccurrence, | ||
rule, | ||
prodMaxLookahead || this.maxLookahead, | ||
this.dynamicTokensEnabled, | ||
prodType, | ||
this.lookAheadBuilderForOptional | ||
) | ||
maxLookahead: prodMaxLookahead || this.maxLookahead, | ||
dynamicTokensEnabled: this.dynamicTokensEnabled, | ||
prodType | ||
}) | ||
const key = getKeyForAutomaticLookahead( | ||
@@ -190,30 +187,2 @@ this.fullRuleNameToShort[rule.name], | ||
lookAheadBuilderForOptional( | ||
this: MixedInParser, | ||
alt: LookAheadSequence, | ||
tokenMatcher: TokenMatcher, | ||
dynamicTokensEnabled: boolean | ||
): () => boolean { | ||
return buildSingleAlternativeLookaheadFunction( | ||
alt, | ||
tokenMatcher, | ||
dynamicTokensEnabled | ||
) | ||
} | ||
lookAheadBuilderForAlternatives( | ||
this: MixedInParser, | ||
alts: LookAheadSequence[], | ||
hasPredicates: boolean, | ||
tokenMatcher: TokenMatcher, | ||
dynamicTokensEnabled: boolean | ||
): (orAlts: IOrAlt<any>[]) => number | undefined { | ||
return buildAlternativesLookAheadFunc( | ||
alts, | ||
hasPredicates, | ||
tokenMatcher, | ||
dynamicTokensEnabled | ||
) | ||
} | ||
// this actually returns a number, but it is always used as a string (object prop key) | ||
@@ -220,0 +189,0 @@ getKeyForAutomaticLookahead( |
// needs a separate module as this is required inside chevrotain productive code | ||
// and also in the entry point for webpack(api.ts). | ||
// A separate file avoids cyclic dependencies and webpack errors. | ||
export const VERSION = "10.3.0" | ||
export const VERSION = "10.4.0" |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
3537280
148
46974
+ Added@chevrotain/cst-dts-gen@10.4.0(transitive)
+ Added@chevrotain/gast@10.4.0(transitive)
+ Added@chevrotain/types@10.4.0(transitive)
+ Added@chevrotain/utils@10.4.0(transitive)
- Removed@chevrotain/cst-dts-gen@10.3.0(transitive)
- Removed@chevrotain/gast@10.3.0(transitive)
- Removed@chevrotain/types@10.3.0(transitive)
- Removed@chevrotain/utils@10.3.0(transitive)
Updated@chevrotain/gast@10.4.0
Updated@chevrotain/types@10.4.0
Updated@chevrotain/utils@10.4.0