Add capacitorjs runtime

This commit is contained in:
olcxja 2026-05-03 17:09:55 +02:00
commit f90c0e6c40
8362 changed files with 1502407 additions and 1 deletions

View file

@ -0,0 +1,3 @@
// TODO: can this be removed? where is it used?
export var IN = "_~IN~_";
//# sourceMappingURL=constants.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/parse/constants.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,MAAM,CAAC,IAAI,EAAE,GAAG,QAAQ,CAAA"}

71
node_modules/chevrotain/lib_esm/src/parse/cst/cst.js generated vendored Normal file
View file

@ -0,0 +1,71 @@
/**
* This nodeLocation tracking is not efficient and should only be used
* when error recovery is enabled or the Token Vector contains virtual Tokens
* (e.g, Python Indent/Outdent)
* As it executes the calculation for every single terminal/nonTerminal
* and does not rely on the fact the token vector is **sorted**
*/
export function setNodeLocationOnlyOffset(currNodeLocation, newLocationInfo) {
// First (valid) update for this cst node
if (isNaN(currNodeLocation.startOffset) === true) {
// assumption1: Token location information is either NaN or a valid number
// assumption2: Token location information is fully valid if it exist
// (both start/end offsets exist and are numbers).
currNodeLocation.startOffset = newLocationInfo.startOffset;
currNodeLocation.endOffset = newLocationInfo.endOffset;
}
// Once the startOffset has been updated with a valid number it should never receive
// any farther updates as the Token vector is sorted.
// We still have to check this this condition for every new possible location info
// because with error recovery enabled we may encounter invalid tokens (NaN location props)
else if (currNodeLocation.endOffset < newLocationInfo.endOffset === true) {
currNodeLocation.endOffset = newLocationInfo.endOffset;
}
}
/**
* This nodeLocation tracking is not efficient and should only be used
* when error recovery is enabled or the Token Vector contains virtual Tokens
* (e.g, Python Indent/Outdent)
* As it executes the calculation for every single terminal/nonTerminal
* and does not rely on the fact the token vector is **sorted**
*/
export function setNodeLocationFull(currNodeLocation, newLocationInfo) {
// First (valid) update for this cst node
if (isNaN(currNodeLocation.startOffset) === true) {
// assumption1: Token location information is either NaN or a valid number
// assumption2: Token location information is fully valid if it exist
// (all start/end props exist and are numbers).
currNodeLocation.startOffset = newLocationInfo.startOffset;
currNodeLocation.startColumn = newLocationInfo.startColumn;
currNodeLocation.startLine = newLocationInfo.startLine;
currNodeLocation.endOffset = newLocationInfo.endOffset;
currNodeLocation.endColumn = newLocationInfo.endColumn;
currNodeLocation.endLine = newLocationInfo.endLine;
}
// Once the start props has been updated with a valid number it should never receive
// any farther updates as the Token vector is sorted.
// We still have to check this this condition for every new possible location info
// because with error recovery enabled we may encounter invalid tokens (NaN location props)
else if (currNodeLocation.endOffset < newLocationInfo.endOffset === true) {
currNodeLocation.endOffset = newLocationInfo.endOffset;
currNodeLocation.endColumn = newLocationInfo.endColumn;
currNodeLocation.endLine = newLocationInfo.endLine;
}
}
export function addTerminalToCst(node, token, tokenTypeName) {
if (node.children[tokenTypeName] === undefined) {
node.children[tokenTypeName] = [token];
}
else {
node.children[tokenTypeName].push(token);
}
}
export function addNoneTerminalToCst(node, ruleName, ruleResult) {
if (node.children[ruleName] === undefined) {
node.children[ruleName] = [ruleResult];
}
else {
node.children[ruleName].push(ruleResult);
}
}
//# sourceMappingURL=cst.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"cst.js","sourceRoot":"","sources":["../../../../src/parse/cst/cst.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,UAAU,yBAAyB,CACvC,gBAAiC,EACjC,eAAuB;IAEvB,yCAAyC;IACzC,IAAI,KAAK,CAAC,gBAAgB,CAAC,WAAW,CAAC,KAAK,IAAI,EAAE;QAChD,0EAA0E;QAC1E,qEAAqE;QACrE,kDAAkD;QAClD,gBAAgB,CAAC,WAAW,GAAG,eAAe,CAAC,WAAW,CAAA;QAC1D,gBAAgB,CAAC,SAAS,GAAG,eAAe,CAAC,SAAS,CAAA;KACvD;IACD,oFAAoF;IACpF,qDAAqD;IACrD,kFAAkF;IAClF,2FAA2F;SACtF,IAAI,gBAAgB,CAAC,SAAS,GAAG,eAAe,CAAC,SAAS,KAAK,IAAI,EAAE;QACxE,gBAAgB,CAAC,SAAS,GAAG,eAAe,CAAC,SAAS,CAAA;KACvD;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CACjC,gBAAiC,EACjC,eAAgC;IAEhC,yCAAyC;IACzC,IAAI,KAAK,CAAC,gBAAgB,CAAC,WAAW,CAAC,KAAK,IAAI,EAAE;QAChD,0EAA0E;QAC1E,qEAAqE;QACrE,+CAA+C;QAC/C,gBAAgB,CAAC,WAAW,GAAG,eAAe,CAAC,WAAW,CAAA;QAC1D,gBAAgB,CAAC,WAAW,GAAG,eAAe,CAAC,WAAW,CAAA;QAC1D,gBAAgB,CAAC,SAAS,GAAG,eAAe,CAAC,SAAS,CAAA;QACtD,gBAAgB,CAAC,SAAS,GAAG,eAAe,CAAC,SAAS,CAAA;QACtD,gBAAgB,CAAC,SAAS,GAAG,eAAe,CAAC,SAAS,CAAA;QACtD,gBAAgB,CAAC,OAAO,GAAG,eAAe,CAAC,OAAO,CAAA;KACnD;IACD,oFAAoF;IACpF,qDAAqD;IACrD,kFAAkF;IAClF,2FAA2F;SACtF,IAAI,gBAAgB,CAAC,SAAS,GAAG,eAAe,CAAC,SAAS,KAAK,IAAI,EAAE;QACxE,gBAAgB,CAAC,SAAS,GAAG,eAAe,CAAC,SAAS,CAAA;QACtD,gBAAgB,CAAC,SAAS,GAAG,eAAe,CAAC,SAAS,CAAA;QACtD,gBAAgB,CAAC,OAAO,GAAG,eAAe,CAAC,OAAO,CAAA;KACnD;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,IAAa,EACb,KAAa,EACb,aAAqB;IAErB,IAAI,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,KAAK,SAAS,EAAE;QAC9C,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;KACvC;SAAM;QACL,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;KACzC;AACH,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,IAAa,EACb,QAAgB,EAChB,UAAe;IAEf,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,SAAS,EAAE;QACzC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;KACvC;SAAM;QACL,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;KACzC;AACH,CAAC"}

View file

@ -0,0 +1,107 @@
import { compact, contains, forEach, isArray, isEmpty, isFunction, isUndefined, keys, map } from "../../utils/utils";
import { defineNameProp, functionName } from "../../lang/lang_extensions";
export function defaultVisit(ctx, param) {
var childrenNames = keys(ctx);
var childrenNamesLength = childrenNames.length;
for (var i = 0; i < childrenNamesLength; i++) {
var currChildName = childrenNames[i];
var currChildArray = ctx[currChildName];
var currChildArrayLength = currChildArray.length;
for (var j = 0; j < currChildArrayLength; j++) {
var currChild = currChildArray[j];
// distinction between Tokens Children and CstNode children
if (currChild.tokenTypeIdx === undefined) {
this[currChild.name](currChild.children, param);
}
}
}
// defaultVisit does not support generic out param
return undefined;
}
export function createBaseSemanticVisitorConstructor(grammarName, ruleNames) {
var derivedConstructor = function () { };
// can be overwritten according to:
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/
// name?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FGlobal_Objects%2FFunction%2Fname
defineNameProp(derivedConstructor, grammarName + "BaseSemantics");
var semanticProto = {
visit: function (cstNode, param) {
// enables writing more concise visitor methods when CstNode has only a single child
if (isArray(cstNode)) {
// A CST Node's children dictionary can never have empty arrays as values
// If a key is defined there will be at least one element in the corresponding value array.
cstNode = cstNode[0];
}
// enables passing optional CstNodes concisely.
if (isUndefined(cstNode)) {
return undefined;
}
return this[cstNode.name](cstNode.children, param);
},
validateVisitor: function () {
var semanticDefinitionErrors = validateVisitor(this, ruleNames);
if (!isEmpty(semanticDefinitionErrors)) {
var errorMessages = map(semanticDefinitionErrors, function (currDefError) { return currDefError.msg; });
throw Error("Errors Detected in CST Visitor <" + functionName(this.constructor) + ">:\n\t" + ("" + errorMessages.join("\n\n").replace(/\n/g, "\n\t")));
}
}
};
derivedConstructor.prototype = semanticProto;
derivedConstructor.prototype.constructor = derivedConstructor;
derivedConstructor._RULE_NAMES = ruleNames;
return derivedConstructor;
}
export function createBaseVisitorConstructorWithDefaults(grammarName, ruleNames, baseConstructor) {
var derivedConstructor = function () { };
// can be overwritten according to:
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/
// name?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FGlobal_Objects%2FFunction%2Fname
defineNameProp(derivedConstructor, grammarName + "BaseSemanticsWithDefaults");
var withDefaultsProto = Object.create(baseConstructor.prototype);
forEach(ruleNames, function (ruleName) {
withDefaultsProto[ruleName] = defaultVisit;
});
derivedConstructor.prototype = withDefaultsProto;
derivedConstructor.prototype.constructor = derivedConstructor;
return derivedConstructor;
}
export var CstVisitorDefinitionError;
(function (CstVisitorDefinitionError) {
CstVisitorDefinitionError[CstVisitorDefinitionError["REDUNDANT_METHOD"] = 0] = "REDUNDANT_METHOD";
CstVisitorDefinitionError[CstVisitorDefinitionError["MISSING_METHOD"] = 1] = "MISSING_METHOD";
})(CstVisitorDefinitionError || (CstVisitorDefinitionError = {}));
export function validateVisitor(visitorInstance, ruleNames) {
var missingErrors = validateMissingCstMethods(visitorInstance, ruleNames);
var redundantErrors = validateRedundantMethods(visitorInstance, ruleNames);
return missingErrors.concat(redundantErrors);
}
export function validateMissingCstMethods(visitorInstance, ruleNames) {
var errors = map(ruleNames, function (currRuleName) {
if (!isFunction(visitorInstance[currRuleName])) {
return {
msg: "Missing visitor method: <" + currRuleName + "> on " + functionName(visitorInstance.constructor) + " CST Visitor.",
type: CstVisitorDefinitionError.MISSING_METHOD,
methodName: currRuleName
};
}
});
return compact(errors);
}
var VALID_PROP_NAMES = ["constructor", "visit", "validateVisitor"];
export function validateRedundantMethods(visitorInstance, ruleNames) {
var errors = [];
for (var prop in visitorInstance) {
if (isFunction(visitorInstance[prop]) &&
!contains(VALID_PROP_NAMES, prop) &&
!contains(ruleNames, prop)) {
errors.push({
msg: "Redundant visitor method: <" + prop + "> on " + functionName(visitorInstance.constructor) + " CST Visitor\n" +
"There is no Grammar Rule corresponding to this method's name.\n",
type: CstVisitorDefinitionError.REDUNDANT_METHOD,
methodName: prop
});
}
}
return errors;
}
//# sourceMappingURL=cst_visitor.js.map

View file

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

View file

@ -0,0 +1,186 @@
import { hasTokenLabel, tokenLabel } from "../scan/tokens_public";
import * as utils from "../utils/utils";
import { first, map, reduce } from "../utils/utils";
import { NonTerminal, Rule, Terminal } from "./grammar/gast/gast_public";
import { getProductionDslName } from "./grammar/gast/gast";
export var defaultParserErrorProvider = {
buildMismatchTokenMessage: function (_a) {
var expected = _a.expected, actual = _a.actual, previous = _a.previous, ruleName = _a.ruleName;
var hasLabel = hasTokenLabel(expected);
var expectedMsg = hasLabel
? "--> " + tokenLabel(expected) + " <--"
: "token of type --> " + expected.name + " <--";
var msg = "Expecting " + expectedMsg + " but found --> '" + actual.image + "' <--";
return msg;
},
buildNotAllInputParsedMessage: function (_a) {
var firstRedundant = _a.firstRedundant, ruleName = _a.ruleName;
return "Redundant input, expecting EOF but found: " + firstRedundant.image;
},
buildNoViableAltMessage: function (_a) {
var expectedPathsPerAlt = _a.expectedPathsPerAlt, actual = _a.actual, previous = _a.previous, customUserDescription = _a.customUserDescription, ruleName = _a.ruleName;
var errPrefix = "Expecting: ";
// TODO: issue: No Viable Alternative Error may have incomplete details. #502
var actualText = first(actual).image;
var errSuffix = "\nbut found: '" + actualText + "'";
if (customUserDescription) {
return errPrefix + customUserDescription + errSuffix;
}
else {
var allLookAheadPaths = reduce(expectedPathsPerAlt, function (result, currAltPaths) { return result.concat(currAltPaths); }, []);
var nextValidTokenSequences = map(allLookAheadPaths, function (currPath) {
return "[" + map(currPath, function (currTokenType) { return tokenLabel(currTokenType); }).join(", ") + "]";
});
var nextValidSequenceItems = map(nextValidTokenSequences, function (itemMsg, idx) { return " " + (idx + 1) + ". " + itemMsg; });
var calculatedDescription = "one of these possible Token sequences:\n" + nextValidSequenceItems.join("\n");
return errPrefix + calculatedDescription + errSuffix;
}
},
buildEarlyExitMessage: function (_a) {
var expectedIterationPaths = _a.expectedIterationPaths, actual = _a.actual, customUserDescription = _a.customUserDescription, ruleName = _a.ruleName;
var errPrefix = "Expecting: ";
// TODO: issue: No Viable Alternative Error may have incomplete details. #502
var actualText = first(actual).image;
var errSuffix = "\nbut found: '" + actualText + "'";
if (customUserDescription) {
return errPrefix + customUserDescription + errSuffix;
}
else {
var nextValidTokenSequences = map(expectedIterationPaths, function (currPath) {
return "[" + map(currPath, function (currTokenType) { return tokenLabel(currTokenType); }).join(",") + "]";
});
var calculatedDescription = "expecting at least one iteration which starts with one of these possible Token sequences::\n " +
("<" + nextValidTokenSequences.join(" ,") + ">");
return errPrefix + calculatedDescription + errSuffix;
}
}
};
Object.freeze(defaultParserErrorProvider);
export var defaultGrammarResolverErrorProvider = {
buildRuleNotFoundError: function (topLevelRule, undefinedRule) {
var msg = "Invalid grammar, reference to a rule which is not defined: ->" +
undefinedRule.nonTerminalName +
"<-\n" +
"inside top level rule: ->" +
topLevelRule.name +
"<-";
return msg;
}
};
export var defaultGrammarValidatorErrorProvider = {
buildDuplicateFoundError: function (topLevelRule, duplicateProds) {
function getExtraProductionArgument(prod) {
if (prod instanceof Terminal) {
return prod.terminalType.name;
}
else if (prod instanceof NonTerminal) {
return prod.nonTerminalName;
}
else {
return "";
}
}
var topLevelName = topLevelRule.name;
var duplicateProd = first(duplicateProds);
var index = duplicateProd.idx;
var dslName = getProductionDslName(duplicateProd);
var extraArgument = getExtraProductionArgument(duplicateProd);
var hasExplicitIndex = index > 0;
var msg = "->" + dslName + (hasExplicitIndex ? index : "") + "<- " + (extraArgument ? "with argument: ->" + extraArgument + "<-" : "") + "\n appears more than once (" + duplicateProds.length + " times) in the top level rule: ->" + topLevelName + "<-. \n For further details see: https://sap.github.io/chevrotain/docs/FAQ.html#NUMERICAL_SUFFIXES \n ";
// white space trimming time! better to trim afterwards as it allows to use WELL formatted multi line template strings...
msg = msg.replace(/[ \t]+/g, " ");
msg = msg.replace(/\s\s+/g, "\n");
return msg;
},
buildNamespaceConflictError: function (rule) {
var errMsg = "Namespace conflict found in grammar.\n" +
("The grammar has both a Terminal(Token) and a Non-Terminal(Rule) named: <" + rule.name + ">.\n") +
"To resolve this make sure each Terminal and Non-Terminal names are unique\n" +
"This is easy to accomplish by using the convention that Terminal names start with an uppercase letter\n" +
"and Non-Terminal names start with a lower case letter.";
return errMsg;
},
buildAlternationPrefixAmbiguityError: function (options) {
var pathMsg = map(options.prefixPath, function (currTok) {
return tokenLabel(currTok);
}).join(", ");
var occurrence = options.alternation.idx === 0 ? "" : options.alternation.idx;
var errMsg = "Ambiguous alternatives: <" + options.ambiguityIndices.join(" ,") + "> due to common lookahead prefix\n" +
("in <OR" + occurrence + "> inside <" + options.topLevelRule.name + "> Rule,\n") +
("<" + pathMsg + "> may appears as a prefix path in all these alternatives.\n") +
"See: https://sap.github.io/chevrotain/docs/guide/resolving_grammar_errors.html#COMMON_PREFIX\n" +
"For Further details.";
return errMsg;
},
buildAlternationAmbiguityError: function (options) {
var pathMsg = map(options.prefixPath, function (currtok) {
return tokenLabel(currtok);
}).join(", ");
var occurrence = options.alternation.idx === 0 ? "" : options.alternation.idx;
var currMessage = "Ambiguous Alternatives Detected: <" + options.ambiguityIndices.join(" ,") + "> in <OR" + occurrence + ">" +
(" inside <" + options.topLevelRule.name + "> Rule,\n") +
("<" + pathMsg + "> may appears as a prefix path in all these alternatives.\n");
currMessage =
currMessage +
"See: https://sap.github.io/chevrotain/docs/guide/resolving_grammar_errors.html#AMBIGUOUS_ALTERNATIVES\n" +
"For Further details.";
return currMessage;
},
buildEmptyRepetitionError: function (options) {
var dslName = getProductionDslName(options.repetition);
if (options.repetition.idx !== 0) {
dslName += options.repetition.idx;
}
var errMsg = "The repetition <" + dslName + "> within Rule <" + options.topLevelRule.name + "> can never consume any tokens.\n" +
"This could lead to an infinite loop.";
return errMsg;
},
// TODO: remove - `errors_public` from nyc.config.js exclude
// once this method is fully removed from this file
buildTokenNameError: function (options) {
/* istanbul ignore next */
return "deprecated";
},
buildEmptyAlternationError: function (options) {
var errMsg = "Ambiguous empty alternative: <" + (options.emptyChoiceIdx + 1) + ">" +
(" in <OR" + options.alternation.idx + "> inside <" + options.topLevelRule.name + "> Rule.\n") +
"Only the last alternative may be an empty alternative.";
return errMsg;
},
buildTooManyAlternativesError: function (options) {
var errMsg = "An Alternation cannot have more than 256 alternatives:\n" +
("<OR" + options.alternation.idx + "> inside <" + options.topLevelRule.name + "> Rule.\n has " + (options.alternation.definition.length + 1) + " alternatives.");
return errMsg;
},
buildLeftRecursionError: function (options) {
var ruleName = options.topLevelRule.name;
var pathNames = utils.map(options.leftRecursionPath, function (currRule) { return currRule.name; });
var leftRecursivePath = ruleName + " --> " + pathNames
.concat([ruleName])
.join(" --> ");
var errMsg = "Left Recursion found in grammar.\n" +
("rule: <" + ruleName + "> can be invoked from itself (directly or indirectly)\n") +
("without consuming any Tokens. The grammar path that causes this is: \n " + leftRecursivePath + "\n") +
" To fix this refactor your grammar to remove the left recursion.\n" +
"see: https://en.wikipedia.org/wiki/LL_parser#Left_Factoring.";
return errMsg;
},
// TODO: remove - `errors_public` from nyc.config.js exclude
// once this method is fully removed from this file
buildInvalidRuleNameError: function (options) {
/* istanbul ignore next */
return "deprecated";
},
buildDuplicateRuleNameError: function (options) {
var ruleName;
if (options.topLevelRule instanceof Rule) {
ruleName = options.topLevelRule.name;
}
else {
ruleName = options.topLevelRule;
}
var errMsg = "Duplicate definition, rule: ->" + ruleName + "<- is already defined in the grammar: ->" + options.grammarName + "<-";
return errMsg;
}
};
//# sourceMappingURL=errors_public.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,91 @@
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
import { contains } from "../utils/utils";
var MISMATCHED_TOKEN_EXCEPTION = "MismatchedTokenException";
var NO_VIABLE_ALT_EXCEPTION = "NoViableAltException";
var EARLY_EXIT_EXCEPTION = "EarlyExitException";
var NOT_ALL_INPUT_PARSED_EXCEPTION = "NotAllInputParsedException";
var RECOGNITION_EXCEPTION_NAMES = [
MISMATCHED_TOKEN_EXCEPTION,
NO_VIABLE_ALT_EXCEPTION,
EARLY_EXIT_EXCEPTION,
NOT_ALL_INPUT_PARSED_EXCEPTION
];
Object.freeze(RECOGNITION_EXCEPTION_NAMES);
// hacks to bypass no support for custom Errors in javascript/typescript
export function isRecognitionException(error) {
// can't do instanceof on hacked custom js exceptions
return contains(RECOGNITION_EXCEPTION_NAMES, error.name);
}
var RecognitionException = /** @class */ (function (_super) {
__extends(RecognitionException, _super);
function RecognitionException(message, token) {
var _newTarget = this.constructor;
var _this = _super.call(this, message) || this;
_this.token = token;
_this.resyncedTokens = [];
// fix prototype chain when typescript target is ES5
Object.setPrototypeOf(_this, _newTarget.prototype);
/* istanbul ignore next - V8 workaround to remove constructor from stacktrace when typescript target is ES5 */
if (Error.captureStackTrace) {
Error.captureStackTrace(_this, _this.constructor);
}
return _this;
}
return RecognitionException;
}(Error));
var MismatchedTokenException = /** @class */ (function (_super) {
__extends(MismatchedTokenException, _super);
function MismatchedTokenException(message, token, previousToken) {
var _this = _super.call(this, message, token) || this;
_this.previousToken = previousToken;
_this.name = MISMATCHED_TOKEN_EXCEPTION;
return _this;
}
return MismatchedTokenException;
}(RecognitionException));
export { MismatchedTokenException };
var NoViableAltException = /** @class */ (function (_super) {
__extends(NoViableAltException, _super);
function NoViableAltException(message, token, previousToken) {
var _this = _super.call(this, message, token) || this;
_this.previousToken = previousToken;
_this.name = NO_VIABLE_ALT_EXCEPTION;
return _this;
}
return NoViableAltException;
}(RecognitionException));
export { NoViableAltException };
var NotAllInputParsedException = /** @class */ (function (_super) {
__extends(NotAllInputParsedException, _super);
function NotAllInputParsedException(message, token) {
var _this = _super.call(this, message, token) || this;
_this.name = NOT_ALL_INPUT_PARSED_EXCEPTION;
return _this;
}
return NotAllInputParsedException;
}(RecognitionException));
export { NotAllInputParsedException };
var EarlyExitException = /** @class */ (function (_super) {
__extends(EarlyExitException, _super);
function EarlyExitException(message, token, previousToken) {
var _this = _super.call(this, message, token) || this;
_this.previousToken = previousToken;
_this.name = EARLY_EXIT_EXCEPTION;
return _this;
}
return EarlyExitException;
}(RecognitionException));
export { EarlyExitException };
//# sourceMappingURL=exceptions_public.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"exceptions_public.js","sourceRoot":"","sources":["../../../src/parse/exceptions_public.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAGzC,IAAM,0BAA0B,GAAG,0BAA0B,CAAA;AAC7D,IAAM,uBAAuB,GAAG,sBAAsB,CAAA;AACtD,IAAM,oBAAoB,GAAG,oBAAoB,CAAA;AACjD,IAAM,8BAA8B,GAAG,4BAA4B,CAAA;AAEnE,IAAM,2BAA2B,GAAG;IAClC,0BAA0B;IAC1B,uBAAuB;IACvB,oBAAoB;IACpB,8BAA8B;CAC/B,CAAA;AAED,MAAM,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAAA;AAE1C,wEAAwE;AACxE,MAAM,UAAU,sBAAsB,CAAC,KAAY;IACjD,qDAAqD;IACrD,OAAO,QAAQ,CAAC,2BAA2B,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;AAC1D,CAAC;AAED;IACU,wCAAK;IAKb,8BAAsB,OAAe,EAAS,KAAa;;QAA3D,YACE,kBAAM,OAAO,CAAC,SASf;QAV6C,WAAK,GAAL,KAAK,CAAQ;QAF3D,oBAAc,GAAG,EAAE,CAAA;QAKjB,oDAAoD;QACpD,MAAM,CAAC,cAAc,CAAC,KAAI,EAAE,WAAW,SAAS,CAAC,CAAA;QAEjD,8GAA8G;QAC9G,IAAI,KAAK,CAAC,iBAAiB,EAAE;YAC3B,KAAK,CAAC,iBAAiB,CAAC,KAAI,EAAE,KAAI,CAAC,WAAW,CAAC,CAAA;SAChD;;IACH,CAAC;IACH,2BAAC;AAAD,CAAC,AAjBD,CACU,KAAK,GAgBd;AAED;IAA8C,4CAAoB;IAChE,kCAAY,OAAe,EAAE,KAAa,EAAS,aAAqB;QAAxE,YACE,kBAAM,OAAO,EAAE,KAAK,CAAC,SAEtB;QAHkD,mBAAa,GAAb,aAAa,CAAQ;QAEtE,KAAI,CAAC,IAAI,GAAG,0BAA0B,CAAA;;IACxC,CAAC;IACH,+BAAC;AAAD,CAAC,AALD,CAA8C,oBAAoB,GAKjE;;AAED;IAA0C,wCAAoB;IAC5D,8BAAY,OAAe,EAAE,KAAa,EAAS,aAAqB;QAAxE,YACE,kBAAM,OAAO,EAAE,KAAK,CAAC,SAEtB;QAHkD,mBAAa,GAAb,aAAa,CAAQ;QAEtE,KAAI,CAAC,IAAI,GAAG,uBAAuB,CAAA;;IACrC,CAAC;IACH,2BAAC;AAAD,CAAC,AALD,CAA0C,oBAAoB,GAK7D;;AAED;IAAgD,8CAAoB;IAClE,oCAAY,OAAe,EAAE,KAAa;QAA1C,YACE,kBAAM,OAAO,EAAE,KAAK,CAAC,SAEtB;QADC,KAAI,CAAC,IAAI,GAAG,8BAA8B,CAAA;;IAC5C,CAAC;IACH,iCAAC;AAAD,CAAC,AALD,CAAgD,oBAAoB,GAKnE;;AAED;IAAwC,sCAAoB;IAC1D,4BAAY,OAAe,EAAE,KAAa,EAAS,aAAqB;QAAxE,YACE,kBAAM,OAAO,EAAE,KAAK,CAAC,SAEtB;QAHkD,mBAAa,GAAb,aAAa,CAAQ;QAEtE,KAAI,CAAC,IAAI,GAAG,oBAAoB,CAAA;;IAClC,CAAC;IACH,yBAAC;AAAD,CAAC,AALD,CAAwC,oBAAoB,GAK3D"}

View file

@ -0,0 +1,475 @@
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
import * as utils from "../../utils/utils";
import { contains, every, findAll, flatten, forEach, isEmpty, map, reduce, reject } from "../../utils/utils";
import { ParserDefinitionErrorType } from "../parser/parser";
import { getProductionDslName, isOptionalProd } from "./gast/gast";
import { containsPath, getLookaheadPathsForOptionalProd, getLookaheadPathsForOr, getProdType, isStrictPrefixOfPath } from "./lookahead";
import { nextPossibleTokensAfter } from "./interpreter";
import { Alternation, Alternative as AlternativeGAST, NonTerminal, Option, Repetition, RepetitionMandatory, RepetitionMandatoryWithSeparator, RepetitionWithSeparator, Terminal } from "./gast/gast_public";
import { GAstVisitor } from "./gast/gast_visitor_public";
export function validateGrammar(topLevels, globalMaxLookahead, tokenTypes, errMsgProvider, grammarName) {
var duplicateErrors = utils.map(topLevels, function (currTopLevel) {
return validateDuplicateProductions(currTopLevel, errMsgProvider);
});
var leftRecursionErrors = utils.map(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 (every(leftRecursionErrors, isEmpty)) {
emptyAltErrors = map(topLevels, function (currTopRule) {
return validateEmptyOrAlternative(currTopRule, errMsgProvider);
});
ambiguousAltsErrors = map(topLevels, function (currTopRule) {
return validateAmbiguousAlternationAlternatives(currTopRule, globalMaxLookahead, errMsgProvider);
});
emptyRepetitionErrors = validateSomeNonEmptyLookaheadPath(topLevels, globalMaxLookahead, errMsgProvider);
}
var termsNamespaceConflictErrors = checkTerminalAndNoneTerminalsNameSpace(topLevels, tokenTypes, errMsgProvider);
var tooManyAltsErrors = map(topLevels, function (curRule) {
return validateTooManyAlts(curRule, errMsgProvider);
});
var duplicateRulesError = map(topLevels, function (curRule) {
return validateRuleDoesNotAlreadyExist(curRule, topLevels, grammarName, errMsgProvider);
});
return (utils.flatten(duplicateErrors.concat(emptyRepetitionErrors, leftRecursionErrors, emptyAltErrors, ambiguousAltsErrors, termsNamespaceConflictErrors, tooManyAltsErrors, duplicateRulesError)));
}
function validateDuplicateProductions(topLevelRule, errMsgProvider) {
var collectorVisitor = new OccurrenceValidationCollector();
topLevelRule.accept(collectorVisitor);
var allRuleProductions = collectorVisitor.allProductions;
var productionGroups = utils.groupBy(allRuleProductions, identifyProductionForDuplicates);
var duplicates = utils.pick(productionGroups, function (currGroup) {
return currGroup.length > 1;
});
var errors = utils.map(utils.values(duplicates), function (currDuplicates) {
var firstProd = utils.first(currDuplicates);
var msg = errMsgProvider.buildDuplicateFoundError(topLevelRule, currDuplicates);
var dslName = getProductionDslName(firstProd);
var defError = {
message: msg,
type: ParserDefinitionErrorType.DUPLICATE_PRODUCTIONS,
ruleName: topLevelRule.name,
dslName: dslName,
occurrence: firstProd.idx
};
var param = getExtraProductionArgument(firstProd);
if (param) {
defError.parameter = param;
}
return defError;
});
return errors;
}
export function identifyProductionForDuplicates(prod) {
return getProductionDslName(prod) + "_#_" + prod.idx + "_#_" + getExtraProductionArgument(prod);
}
function getExtraProductionArgument(prod) {
if (prod instanceof Terminal) {
return prod.terminalType.name;
}
else if (prod instanceof NonTerminal) {
return prod.nonTerminalName;
}
else {
return "";
}
}
var OccurrenceValidationCollector = /** @class */ (function (_super) {
__extends(OccurrenceValidationCollector, _super);
function OccurrenceValidationCollector() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.allProductions = [];
return _this;
}
OccurrenceValidationCollector.prototype.visitNonTerminal = function (subrule) {
this.allProductions.push(subrule);
};
OccurrenceValidationCollector.prototype.visitOption = function (option) {
this.allProductions.push(option);
};
OccurrenceValidationCollector.prototype.visitRepetitionWithSeparator = function (manySep) {
this.allProductions.push(manySep);
};
OccurrenceValidationCollector.prototype.visitRepetitionMandatory = function (atLeastOne) {
this.allProductions.push(atLeastOne);
};
OccurrenceValidationCollector.prototype.visitRepetitionMandatoryWithSeparator = function (atLeastOneSep) {
this.allProductions.push(atLeastOneSep);
};
OccurrenceValidationCollector.prototype.visitRepetition = function (many) {
this.allProductions.push(many);
};
OccurrenceValidationCollector.prototype.visitAlternation = function (or) {
this.allProductions.push(or);
};
OccurrenceValidationCollector.prototype.visitTerminal = function (terminal) {
this.allProductions.push(terminal);
};
return OccurrenceValidationCollector;
}(GAstVisitor));
export { OccurrenceValidationCollector };
export function validateRuleDoesNotAlreadyExist(rule, allRules, className, errMsgProvider) {
var errors = [];
var occurrences = reduce(allRules, function (result, curRule) {
if (curRule.name === rule.name) {
return result + 1;
}
return result;
}, 0);
if (occurrences > 1) {
var errMsg = errMsgProvider.buildDuplicateRuleNameError({
topLevelRule: rule,
grammarName: className
});
errors.push({
message: errMsg,
type: ParserDefinitionErrorType.DUPLICATE_RULE_NAME,
ruleName: rule.name
});
}
return errors;
}
// TODO: is there anyway to get only the rule names of rules inherited from the super grammars?
// This is not part of the IGrammarErrorProvider because the validation cannot be performed on
// The grammar structure, only at runtime.
export function validateRuleIsOverridden(ruleName, definedRulesNames, className) {
var errors = [];
var errMsg;
if (!utils.contains(definedRulesNames, ruleName)) {
errMsg =
"Invalid rule override, rule: ->" + ruleName + "<- cannot be overridden in the grammar: ->" + className + "<-" +
"as it is not defined in any of the super grammars ";
errors.push({
message: errMsg,
type: ParserDefinitionErrorType.INVALID_RULE_OVERRIDE,
ruleName: ruleName
});
}
return errors;
}
export function validateNoLeftRecursion(topRule, currRule, errMsgProvider, path) {
if (path === void 0) { path = []; }
var errors = [];
var nextNonTerminals = getFirstNoneTerminal(currRule.definition);
if (utils.isEmpty(nextNonTerminals)) {
return [];
}
else {
var ruleName = topRule.name;
var foundLeftRecursion = utils.contains(nextNonTerminals, topRule);
if (foundLeftRecursion) {
errors.push({
message: errMsgProvider.buildLeftRecursionError({
topLevelRule: topRule,
leftRecursionPath: path
}),
type: ParserDefinitionErrorType.LEFT_RECURSION,
ruleName: ruleName
});
}
// we are only looking for cyclic paths leading back to the specific topRule
// other cyclic paths are ignored, we still need this difference to avoid infinite loops...
var validNextSteps = utils.difference(nextNonTerminals, path.concat([topRule]));
var errorsFromNextSteps = utils.map(validNextSteps, function (currRefRule) {
var newPath = utils.cloneArr(path);
newPath.push(currRefRule);
return validateNoLeftRecursion(topRule, currRefRule, errMsgProvider, newPath);
});
return errors.concat(utils.flatten(errorsFromNextSteps));
}
}
export function getFirstNoneTerminal(definition) {
var result = [];
if (utils.isEmpty(definition)) {
return result;
}
var firstProd = utils.first(definition);
/* istanbul ignore else */
if (firstProd instanceof NonTerminal) {
result.push(firstProd.referencedRule);
}
else if (firstProd instanceof AlternativeGAST ||
firstProd instanceof Option ||
firstProd instanceof RepetitionMandatory ||
firstProd instanceof RepetitionMandatoryWithSeparator ||
firstProd instanceof RepetitionWithSeparator ||
firstProd instanceof Repetition) {
result = result.concat(getFirstNoneTerminal(firstProd.definition));
}
else if (firstProd instanceof Alternation) {
// each sub definition in alternation is a FLAT
result = utils.flatten(utils.map(firstProd.definition, function (currSubDef) {
return getFirstNoneTerminal(currSubDef.definition);
}));
}
else if (firstProd instanceof Terminal) {
// nothing to see, move along
}
else {
throw Error("non exhaustive match");
}
var isFirstOptional = isOptionalProd(firstProd);
var hasMore = definition.length > 1;
if (isFirstOptional && hasMore) {
var rest = utils.drop(definition);
return result.concat(getFirstNoneTerminal(rest));
}
else {
return result;
}
}
var OrCollector = /** @class */ (function (_super) {
__extends(OrCollector, _super);
function OrCollector() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.alternations = [];
return _this;
}
OrCollector.prototype.visitAlternation = function (node) {
this.alternations.push(node);
};
return OrCollector;
}(GAstVisitor));
export function validateEmptyOrAlternative(topLevelRule, errMsgProvider) {
var orCollector = new OrCollector();
topLevelRule.accept(orCollector);
var ors = orCollector.alternations;
var errors = utils.reduce(ors, function (errors, currOr) {
var exceptLast = utils.dropRight(currOr.definition);
var currErrors = utils.map(exceptLast, function (currAlternative, currAltIdx) {
var possibleFirstInAlt = nextPossibleTokensAfter([currAlternative], [], null, 1);
if (utils.isEmpty(possibleFirstInAlt)) {
return {
message: errMsgProvider.buildEmptyAlternationError({
topLevelRule: topLevelRule,
alternation: currOr,
emptyChoiceIdx: currAltIdx
}),
type: ParserDefinitionErrorType.NONE_LAST_EMPTY_ALT,
ruleName: topLevelRule.name,
occurrence: currOr.idx,
alternative: currAltIdx + 1
};
}
else {
return null;
}
});
return errors.concat(utils.compact(currErrors));
}, []);
return errors;
}
export function validateAmbiguousAlternationAlternatives(topLevelRule, globalMaxLookahead, errMsgProvider) {
var orCollector = new OrCollector();
topLevelRule.accept(orCollector);
var ors = orCollector.alternations;
// New Handling of ignoring ambiguities
// - https://github.com/SAP/chevrotain/issues/869
ors = reject(ors, function (currOr) { return currOr.ignoreAmbiguities === true; });
var errors = utils.reduce(ors, function (result, currOr) {
var currOccurrence = currOr.idx;
var actualMaxLookahead = currOr.maxLookahead || globalMaxLookahead;
var alternatives = getLookaheadPathsForOr(currOccurrence, topLevelRule, actualMaxLookahead, currOr);
var altsAmbiguityErrors = checkAlternativesAmbiguities(alternatives, currOr, topLevelRule, errMsgProvider);
var altsPrefixAmbiguityErrors = checkPrefixAlternativesAmbiguities(alternatives, currOr, topLevelRule, errMsgProvider);
return result.concat(altsAmbiguityErrors, altsPrefixAmbiguityErrors);
}, []);
return errors;
}
var RepetionCollector = /** @class */ (function (_super) {
__extends(RepetionCollector, _super);
function RepetionCollector() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.allProductions = [];
return _this;
}
RepetionCollector.prototype.visitRepetitionWithSeparator = function (manySep) {
this.allProductions.push(manySep);
};
RepetionCollector.prototype.visitRepetitionMandatory = function (atLeastOne) {
this.allProductions.push(atLeastOne);
};
RepetionCollector.prototype.visitRepetitionMandatoryWithSeparator = function (atLeastOneSep) {
this.allProductions.push(atLeastOneSep);
};
RepetionCollector.prototype.visitRepetition = function (many) {
this.allProductions.push(many);
};
return RepetionCollector;
}(GAstVisitor));
export { RepetionCollector };
export function validateTooManyAlts(topLevelRule, errMsgProvider) {
var orCollector = new OrCollector();
topLevelRule.accept(orCollector);
var ors = orCollector.alternations;
var errors = utils.reduce(ors, function (errors, currOr) {
if (currOr.definition.length > 255) {
errors.push({
message: errMsgProvider.buildTooManyAlternativesError({
topLevelRule: topLevelRule,
alternation: currOr
}),
type: ParserDefinitionErrorType.TOO_MANY_ALTS,
ruleName: topLevelRule.name,
occurrence: currOr.idx
});
}
return errors;
}, []);
return errors;
}
export function validateSomeNonEmptyLookaheadPath(topLevelRules, maxLookahead, errMsgProvider) {
var errors = [];
forEach(topLevelRules, function (currTopRule) {
var collectorVisitor = new RepetionCollector();
currTopRule.accept(collectorVisitor);
var allRuleProductions = collectorVisitor.allProductions;
forEach(allRuleProductions, function (currProd) {
var prodType = getProdType(currProd);
var actualMaxLookahead = currProd.maxLookahead || maxLookahead;
var currOccurrence = currProd.idx;
var paths = getLookaheadPathsForOptionalProd(currOccurrence, currTopRule, prodType, actualMaxLookahead);
var pathsInsideProduction = paths[0];
if (isEmpty(flatten(pathsInsideProduction))) {
var errMsg = errMsgProvider.buildEmptyRepetitionError({
topLevelRule: currTopRule,
repetition: currProd
});
errors.push({
message: errMsg,
type: ParserDefinitionErrorType.NO_NON_EMPTY_LOOKAHEAD,
ruleName: currTopRule.name
});
}
});
});
return errors;
}
function checkAlternativesAmbiguities(alternatives, alternation, rule, errMsgProvider) {
var foundAmbiguousPaths = [];
var identicalAmbiguities = reduce(alternatives, function (result, currAlt, currAltIdx) {
// ignore (skip) ambiguities with this alternative
if (alternation.definition[currAltIdx].ignoreAmbiguities === true) {
return result;
}
forEach(currAlt, function (currPath) {
var altsCurrPathAppearsIn = [currAltIdx];
forEach(alternatives, function (currOtherAlt, currOtherAltIdx) {
if (currAltIdx !== currOtherAltIdx &&
containsPath(currOtherAlt, currPath) &&
// ignore (skip) ambiguities with this "other" alternative
alternation.definition[currOtherAltIdx].ignoreAmbiguities !== true) {
altsCurrPathAppearsIn.push(currOtherAltIdx);
}
});
if (altsCurrPathAppearsIn.length > 1 &&
!containsPath(foundAmbiguousPaths, currPath)) {
foundAmbiguousPaths.push(currPath);
result.push({
alts: altsCurrPathAppearsIn,
path: currPath
});
}
});
return result;
}, []);
var currErrors = utils.map(identicalAmbiguities, function (currAmbDescriptor) {
var ambgIndices = map(currAmbDescriptor.alts, function (currAltIdx) { return currAltIdx + 1; });
var currMessage = errMsgProvider.buildAlternationAmbiguityError({
topLevelRule: rule,
alternation: alternation,
ambiguityIndices: ambgIndices,
prefixPath: currAmbDescriptor.path
});
return {
message: currMessage,
type: ParserDefinitionErrorType.AMBIGUOUS_ALTS,
ruleName: rule.name,
occurrence: alternation.idx,
alternatives: [currAmbDescriptor.alts]
};
});
return currErrors;
}
export function checkPrefixAlternativesAmbiguities(alternatives, alternation, rule, errMsgProvider) {
var errors = [];
// flatten
var pathsAndIndices = reduce(alternatives, function (result, currAlt, idx) {
var currPathsAndIdx = map(currAlt, function (currPath) {
return { idx: idx, path: currPath };
});
return result.concat(currPathsAndIdx);
}, []);
forEach(pathsAndIndices, function (currPathAndIdx) {
var alternativeGast = alternation.definition[currPathAndIdx.idx];
// ignore (skip) ambiguities with this alternative
if (alternativeGast.ignoreAmbiguities === true) {
return;
}
var targetIdx = currPathAndIdx.idx;
var targetPath = currPathAndIdx.path;
var prefixAmbiguitiesPathsAndIndices = findAll(pathsAndIndices, function (searchPathAndIdx) {
// prefix ambiguity can only be created from lower idx (higher priority) path
return (
// ignore (skip) ambiguities with this "other" alternative
alternation.definition[searchPathAndIdx.idx].ignoreAmbiguities !==
true &&
searchPathAndIdx.idx < targetIdx &&
// checking for strict prefix because identical lookaheads
// will be be detected using a different validation.
isStrictPrefixOfPath(searchPathAndIdx.path, targetPath));
});
var currPathPrefixErrors = map(prefixAmbiguitiesPathsAndIndices, function (currAmbPathAndIdx) {
var ambgIndices = [currAmbPathAndIdx.idx + 1, targetIdx + 1];
var occurrence = alternation.idx === 0 ? "" : alternation.idx;
var message = errMsgProvider.buildAlternationPrefixAmbiguityError({
topLevelRule: rule,
alternation: alternation,
ambiguityIndices: ambgIndices,
prefixPath: currAmbPathAndIdx.path
});
return {
message: message,
type: ParserDefinitionErrorType.AMBIGUOUS_PREFIX_ALTS,
ruleName: rule.name,
occurrence: occurrence,
alternatives: ambgIndices
};
});
errors = errors.concat(currPathPrefixErrors);
});
return errors;
}
function checkTerminalAndNoneTerminalsNameSpace(topLevels, tokenTypes, errMsgProvider) {
var errors = [];
var tokenNames = map(tokenTypes, function (currToken) { return currToken.name; });
forEach(topLevels, function (currRule) {
var currRuleName = currRule.name;
if (contains(tokenNames, currRuleName)) {
var errMsg = errMsgProvider.buildNamespaceConflictError(currRule);
errors.push({
message: errMsg,
type: ParserDefinitionErrorType.CONFLICT_TOKENS_RULES_NAMESPACE,
ruleName: currRuleName
});
}
});
return errors;
}
//# sourceMappingURL=checks.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,57 @@
import { uniq, map, flatten } from "../../utils/utils";
import { NonTerminal, Terminal } from "./gast/gast_public";
import { isBranchingProd, isOptionalProd, isSequenceProd } from "./gast/gast";
export function first(prod) {
/* istanbul ignore else */
if (prod instanceof NonTerminal) {
// this could in theory cause infinite loops if
// (1) prod A refs prod B.
// (2) prod B refs prod A
// (3) AB can match the empty set
// in other words a cycle where everything is optional so the first will keep
// looking ahead for the next optional part and will never exit
// currently there is no safeguard for this unique edge case because
// (1) not sure a grammar in which this can happen is useful for anything (productive)
return first(prod.referencedRule);
}
else if (prod instanceof Terminal) {
return firstForTerminal(prod);
}
else if (isSequenceProd(prod)) {
return firstForSequence(prod);
}
else if (isBranchingProd(prod)) {
return firstForBranching(prod);
}
else {
throw Error("non exhaustive match");
}
}
export function firstForSequence(prod) {
var firstSet = [];
var seq = prod.definition;
var nextSubProdIdx = 0;
var hasInnerProdsRemaining = seq.length > nextSubProdIdx;
var currSubProd;
// so we enter the loop at least once (if the definition is not empty
var isLastInnerProdOptional = true;
// scan a sequence until it's end or until we have found a NONE optional production in it
while (hasInnerProdsRemaining && isLastInnerProdOptional) {
currSubProd = seq[nextSubProdIdx];
isLastInnerProdOptional = isOptionalProd(currSubProd);
firstSet = firstSet.concat(first(currSubProd));
nextSubProdIdx = nextSubProdIdx + 1;
hasInnerProdsRemaining = seq.length > nextSubProdIdx;
}
return uniq(firstSet);
}
export function firstForBranching(prod) {
var allAlternativesFirsts = map(prod.definition, function (innerProd) {
return first(innerProd);
});
return uniq(flatten(allAlternativesFirsts));
}
export function firstForTerminal(terminal) {
return [terminal.terminalType];
}
//# sourceMappingURL=first.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"first.js","sourceRoot":"","sources":["../../../../src/parse/grammar/first.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AACtD,OAAO,EAAsB,WAAW,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC9E,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAG7E,MAAM,UAAU,KAAK,CAAC,IAAiB;IACrC,0BAA0B;IAC1B,IAAI,IAAI,YAAY,WAAW,EAAE;QAC/B,+CAA+C;QAC/C,0BAA0B;QAC1B,yBAAyB;QACzB,iCAAiC;QACjC,6EAA6E;QAC7E,+DAA+D;QAC/D,oEAAoE;QACpE,sFAAsF;QACtF,OAAO,KAAK,CAAe,IAAK,CAAC,cAAc,CAAC,CAAA;KACjD;SAAM,IAAI,IAAI,YAAY,QAAQ,EAAE;QACnC,OAAO,gBAAgB,CAAW,IAAI,CAAC,CAAA;KACxC;SAAM,IAAI,cAAc,CAAC,IAAI,CAAC,EAAE;QAC/B,OAAO,gBAAgB,CAAqB,IAAI,CAAC,CAAA;KAClD;SAAM,IAAI,eAAe,CAAC,IAAI,CAAC,EAAE;QAChC,OAAO,iBAAiB,CAAqB,IAAI,CAAC,CAAA;KACnD;SAAM;QACL,MAAM,KAAK,CAAC,sBAAsB,CAAC,CAAA;KACpC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAwB;IACvD,IAAI,QAAQ,GAAgB,EAAE,CAAA;IAC9B,IAAI,GAAG,GAAG,IAAI,CAAC,UAAU,CAAA;IACzB,IAAI,cAAc,GAAG,CAAC,CAAA;IACtB,IAAI,sBAAsB,GAAG,GAAG,CAAC,MAAM,GAAG,cAAc,CAAA;IACxD,IAAI,WAAW,CAAA;IACf,qEAAqE;IACrE,IAAI,uBAAuB,GAAG,IAAI,CAAA;IAClC,yFAAyF;IACzF,OAAO,sBAAsB,IAAI,uBAAuB,EAAE;QACxD,WAAW,GAAG,GAAG,CAAC,cAAc,CAAC,CAAA;QACjC,uBAAuB,GAAG,cAAc,CAAC,WAAW,CAAC,CAAA;QACrD,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAA;QAC9C,cAAc,GAAG,cAAc,GAAG,CAAC,CAAA;QACnC,sBAAsB,GAAG,GAAG,CAAC,MAAM,GAAG,cAAc,CAAA;KACrD;IAED,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAA;AACvB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAwB;IACxD,IAAI,qBAAqB,GAAkB,GAAG,CAC5C,IAAI,CAAC,UAAU,EACf,UAAC,SAAS;QACR,OAAO,KAAK,CAAC,SAAS,CAAC,CAAA;IACzB,CAAC,CACF,CAAA;IACD,OAAO,IAAI,CAAC,OAAO,CAAY,qBAAqB,CAAC,CAAC,CAAA;AACxD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,QAAkB;IACjD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAA;AAChC,CAAC"}

View file

@ -0,0 +1,62 @@
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
import { RestWalker } from "./rest";
import { first } from "./first";
import { assign, forEach } from "../../utils/utils";
import { IN } from "../constants";
import { Alternative } from "./gast/gast_public";
// This ResyncFollowsWalker computes all of the follows required for RESYNC
// (skipping reference production).
var ResyncFollowsWalker = /** @class */ (function (_super) {
__extends(ResyncFollowsWalker, _super);
function ResyncFollowsWalker(topProd) {
var _this = _super.call(this) || this;
_this.topProd = topProd;
_this.follows = {};
return _this;
}
ResyncFollowsWalker.prototype.startWalking = function () {
this.walk(this.topProd);
return this.follows;
};
ResyncFollowsWalker.prototype.walkTerminal = function (terminal, currRest, prevRest) {
// do nothing! just like in the public sector after 13:00
};
ResyncFollowsWalker.prototype.walkProdRef = function (refProd, currRest, prevRest) {
var followName = buildBetweenProdsFollowPrefix(refProd.referencedRule, refProd.idx) +
this.topProd.name;
var fullRest = currRest.concat(prevRest);
var restProd = new Alternative({ definition: fullRest });
var t_in_topProd_follows = first(restProd);
this.follows[followName] = t_in_topProd_follows;
};
return ResyncFollowsWalker;
}(RestWalker));
export { ResyncFollowsWalker };
export function computeAllProdsFollows(topProductions) {
var reSyncFollows = {};
forEach(topProductions, function (topProd) {
var currRefsFollow = new ResyncFollowsWalker(topProd).startWalking();
assign(reSyncFollows, currRefsFollow);
});
return reSyncFollows;
}
export function buildBetweenProdsFollowPrefix(inner, occurenceInParent) {
return inner.name + occurenceInParent + IN;
}
export function buildInProdFollowPrefix(terminal) {
var terminalName = terminal.terminalType.name;
return terminalName + terminal.idx + IN;
}
//# sourceMappingURL=follow.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"follow.js","sourceRoot":"","sources":["../../../../src/parse/grammar/follow.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AACnC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/B,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAA;AACjC,OAAO,EAAE,WAAW,EAA+B,MAAM,oBAAoB,CAAA;AAG7E,2EAA2E;AAC3E,mCAAmC;AACnC;IAAyC,uCAAU;IAGjD,6BAAoB,OAAa;QAAjC,YACE,iBAAO,SACR;QAFmB,aAAO,GAAP,OAAO,CAAM;QAF1B,aAAO,GAAG,EAAE,CAAA;;IAInB,CAAC;IAED,0CAAY,GAAZ;QACE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACvB,OAAO,IAAI,CAAC,OAAO,CAAA;IACrB,CAAC;IAED,0CAAY,GAAZ,UACE,QAAkB,EAClB,QAAuB,EACvB,QAAuB;QAEvB,yDAAyD;IAC3D,CAAC;IAED,yCAAW,GAAX,UACE,OAAoB,EACpB,QAAuB,EACvB,QAAuB;QAEvB,IAAI,UAAU,GACZ,6BAA6B,CAAC,OAAO,CAAC,cAAc,EAAE,OAAO,CAAC,GAAG,CAAC;YAClE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAA;QACnB,IAAI,QAAQ,GAAkB,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QACvD,IAAI,QAAQ,GAAG,IAAI,WAAW,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAA;QACxD,IAAI,oBAAoB,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAA;QAC1C,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,oBAAoB,CAAA;IACjD,CAAC;IACH,0BAAC;AAAD,CAAC,AAjCD,CAAyC,UAAU,GAiClD;;AAED,MAAM,UAAU,sBAAsB,CACpC,cAAsB;IAEtB,IAAI,aAAa,GAAG,EAAE,CAAA;IAEtB,OAAO,CAAC,cAAc,EAAE,UAAC,OAAO;QAC9B,IAAI,cAAc,GAAG,IAAI,mBAAmB,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE,CAAA;QACpE,MAAM,CAAC,aAAa,EAAE,cAAc,CAAC,CAAA;IACvC,CAAC,CAAC,CAAA;IACF,OAAO,aAAa,CAAA;AACtB,CAAC;AAED,MAAM,UAAU,6BAA6B,CAC3C,KAAW,EACX,iBAAyB;IAEzB,OAAO,KAAK,CAAC,IAAI,GAAG,iBAAiB,GAAG,EAAE,CAAA;AAC5C,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,QAAkB;IACxD,IAAI,YAAY,GAAG,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAA;IAC7C,OAAO,YAAY,GAAG,QAAQ,CAAC,GAAG,GAAG,EAAE,CAAA;AACzC,CAAC"}

View file

@ -0,0 +1,163 @@
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
import { contains, every, has, some } from "../../../utils/utils";
import { AbstractProduction, Alternation, Alternative, NonTerminal, Option, Repetition, RepetitionMandatory, RepetitionMandatoryWithSeparator, RepetitionWithSeparator, Rule, Terminal } from "./gast_public";
import { GAstVisitor } from "./gast_visitor_public";
export function isSequenceProd(prod) {
return (prod instanceof Alternative ||
prod instanceof Option ||
prod instanceof Repetition ||
prod instanceof RepetitionMandatory ||
prod instanceof RepetitionMandatoryWithSeparator ||
prod instanceof RepetitionWithSeparator ||
prod instanceof Terminal ||
prod instanceof Rule);
}
export function isOptionalProd(prod, alreadyVisited) {
if (alreadyVisited === void 0) { alreadyVisited = []; }
var isDirectlyOptional = prod instanceof Option ||
prod instanceof Repetition ||
prod instanceof RepetitionWithSeparator;
if (isDirectlyOptional) {
return true;
}
// note that this can cause infinite loop if one optional empty TOP production has a cyclic dependency with another
// empty optional top rule
// may be indirectly optional ((A?B?C?) | (D?E?F?))
if (prod instanceof Alternation) {
// for OR its enough for just one of the alternatives to be optional
return some(prod.definition, function (subProd) {
return isOptionalProd(subProd, alreadyVisited);
});
}
else if (prod instanceof NonTerminal && contains(alreadyVisited, prod)) {
// avoiding stack overflow due to infinite recursion
return false;
}
else if (prod instanceof AbstractProduction) {
if (prod instanceof NonTerminal) {
alreadyVisited.push(prod);
}
return every(prod.definition, function (subProd) {
return isOptionalProd(subProd, alreadyVisited);
});
}
else {
return false;
}
}
export function isBranchingProd(prod) {
return prod instanceof Alternation;
}
export function getProductionDslName(prod) {
/* istanbul ignore else */
if (prod instanceof NonTerminal) {
return "SUBRULE";
}
else if (prod instanceof Option) {
return "OPTION";
}
else if (prod instanceof Alternation) {
return "OR";
}
else if (prod instanceof RepetitionMandatory) {
return "AT_LEAST_ONE";
}
else if (prod instanceof RepetitionMandatoryWithSeparator) {
return "AT_LEAST_ONE_SEP";
}
else if (prod instanceof RepetitionWithSeparator) {
return "MANY_SEP";
}
else if (prod instanceof Repetition) {
return "MANY";
}
else if (prod instanceof Terminal) {
return "CONSUME";
}
else {
throw Error("non exhaustive match");
}
}
var DslMethodsCollectorVisitor = /** @class */ (function (_super) {
__extends(DslMethodsCollectorVisitor, _super);
function DslMethodsCollectorVisitor() {
var _this = _super !== null && _super.apply(this, arguments) || this;
// A minus is never valid in an identifier name
_this.separator = "-";
_this.dslMethods = {
option: [],
alternation: [],
repetition: [],
repetitionWithSeparator: [],
repetitionMandatory: [],
repetitionMandatoryWithSeparator: []
};
return _this;
}
DslMethodsCollectorVisitor.prototype.reset = function () {
this.dslMethods = {
option: [],
alternation: [],
repetition: [],
repetitionWithSeparator: [],
repetitionMandatory: [],
repetitionMandatoryWithSeparator: []
};
};
DslMethodsCollectorVisitor.prototype.visitTerminal = function (terminal) {
var key = terminal.terminalType.name + this.separator + "Terminal";
if (!has(this.dslMethods, key)) {
this.dslMethods[key] = [];
}
this.dslMethods[key].push(terminal);
};
DslMethodsCollectorVisitor.prototype.visitNonTerminal = function (subrule) {
var key = subrule.nonTerminalName + this.separator + "Terminal";
if (!has(this.dslMethods, key)) {
this.dslMethods[key] = [];
}
this.dslMethods[key].push(subrule);
};
DslMethodsCollectorVisitor.prototype.visitOption = function (option) {
this.dslMethods.option.push(option);
};
DslMethodsCollectorVisitor.prototype.visitRepetitionWithSeparator = function (manySep) {
this.dslMethods.repetitionWithSeparator.push(manySep);
};
DslMethodsCollectorVisitor.prototype.visitRepetitionMandatory = function (atLeastOne) {
this.dslMethods.repetitionMandatory.push(atLeastOne);
};
DslMethodsCollectorVisitor.prototype.visitRepetitionMandatoryWithSeparator = function (atLeastOneSep) {
this.dslMethods.repetitionMandatoryWithSeparator.push(atLeastOneSep);
};
DslMethodsCollectorVisitor.prototype.visitRepetition = function (many) {
this.dslMethods.repetition.push(many);
};
DslMethodsCollectorVisitor.prototype.visitAlternation = function (or) {
this.dslMethods.alternation.push(or);
};
return DslMethodsCollectorVisitor;
}(GAstVisitor));
export { DslMethodsCollectorVisitor };
var collectorVisitor = new DslMethodsCollectorVisitor();
export function collectMethods(rule) {
collectorVisitor.reset();
rule.accept(collectorVisitor);
var dslMethods = collectorVisitor.dslMethods;
// avoid uncleaned references
collectorVisitor.reset();
return dslMethods;
}
//# sourceMappingURL=gast.js.map

View file

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

View file

@ -0,0 +1,270 @@
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
import { assign, forEach, isRegExp, map, pick } from "../../../utils/utils";
import { tokenLabel } from "../../../scan/tokens_public";
var AbstractProduction = /** @class */ (function () {
function AbstractProduction(_definition) {
this._definition = _definition;
}
Object.defineProperty(AbstractProduction.prototype, "definition", {
get: function () {
return this._definition;
},
set: function (value) {
this._definition = value;
},
enumerable: false,
configurable: true
});
AbstractProduction.prototype.accept = function (visitor) {
visitor.visit(this);
forEach(this.definition, function (prod) {
prod.accept(visitor);
});
};
return AbstractProduction;
}());
export { AbstractProduction };
var NonTerminal = /** @class */ (function (_super) {
__extends(NonTerminal, _super);
function NonTerminal(options) {
var _this = _super.call(this, []) || this;
_this.idx = 1;
assign(_this, pick(options, function (v) { return v !== undefined; }));
return _this;
}
Object.defineProperty(NonTerminal.prototype, "definition", {
get: function () {
if (this.referencedRule !== undefined) {
return this.referencedRule.definition;
}
return [];
},
set: function (definition) {
// immutable
},
enumerable: false,
configurable: true
});
NonTerminal.prototype.accept = function (visitor) {
visitor.visit(this);
// don't visit children of a reference, we will get cyclic infinite loops if we do so
};
return NonTerminal;
}(AbstractProduction));
export { NonTerminal };
var Rule = /** @class */ (function (_super) {
__extends(Rule, _super);
function Rule(options) {
var _this = _super.call(this, options.definition) || this;
_this.orgText = "";
assign(_this, pick(options, function (v) { return v !== undefined; }));
return _this;
}
return Rule;
}(AbstractProduction));
export { Rule };
var Alternative = /** @class */ (function (_super) {
__extends(Alternative, _super);
function Alternative(options) {
var _this = _super.call(this, options.definition) || this;
_this.ignoreAmbiguities = false;
assign(_this, pick(options, function (v) { return v !== undefined; }));
return _this;
}
return Alternative;
}(AbstractProduction));
export { Alternative };
var Option = /** @class */ (function (_super) {
__extends(Option, _super);
function Option(options) {
var _this = _super.call(this, options.definition) || this;
_this.idx = 1;
assign(_this, pick(options, function (v) { return v !== undefined; }));
return _this;
}
return Option;
}(AbstractProduction));
export { Option };
var RepetitionMandatory = /** @class */ (function (_super) {
__extends(RepetitionMandatory, _super);
function RepetitionMandatory(options) {
var _this = _super.call(this, options.definition) || this;
_this.idx = 1;
assign(_this, pick(options, function (v) { return v !== undefined; }));
return _this;
}
return RepetitionMandatory;
}(AbstractProduction));
export { RepetitionMandatory };
var RepetitionMandatoryWithSeparator = /** @class */ (function (_super) {
__extends(RepetitionMandatoryWithSeparator, _super);
function RepetitionMandatoryWithSeparator(options) {
var _this = _super.call(this, options.definition) || this;
_this.idx = 1;
assign(_this, pick(options, function (v) { return v !== undefined; }));
return _this;
}
return RepetitionMandatoryWithSeparator;
}(AbstractProduction));
export { RepetitionMandatoryWithSeparator };
var Repetition = /** @class */ (function (_super) {
__extends(Repetition, _super);
function Repetition(options) {
var _this = _super.call(this, options.definition) || this;
_this.idx = 1;
assign(_this, pick(options, function (v) { return v !== undefined; }));
return _this;
}
return Repetition;
}(AbstractProduction));
export { Repetition };
var RepetitionWithSeparator = /** @class */ (function (_super) {
__extends(RepetitionWithSeparator, _super);
function RepetitionWithSeparator(options) {
var _this = _super.call(this, options.definition) || this;
_this.idx = 1;
assign(_this, pick(options, function (v) { return v !== undefined; }));
return _this;
}
return RepetitionWithSeparator;
}(AbstractProduction));
export { RepetitionWithSeparator };
var Alternation = /** @class */ (function (_super) {
__extends(Alternation, _super);
function Alternation(options) {
var _this = _super.call(this, options.definition) || this;
_this.idx = 1;
_this.ignoreAmbiguities = false;
_this.hasPredicates = false;
assign(_this, pick(options, function (v) { return v !== undefined; }));
return _this;
}
Object.defineProperty(Alternation.prototype, "definition", {
get: function () {
return this._definition;
},
set: function (value) {
this._definition = value;
},
enumerable: false,
configurable: true
});
return Alternation;
}(AbstractProduction));
export { Alternation };
var Terminal = /** @class */ (function () {
function Terminal(options) {
this.idx = 1;
assign(this, pick(options, function (v) { return v !== undefined; }));
}
Terminal.prototype.accept = function (visitor) {
visitor.visit(this);
};
return Terminal;
}());
export { Terminal };
export function serializeGrammar(topRules) {
return map(topRules, serializeProduction);
}
export function serializeProduction(node) {
function convertDefinition(definition) {
return map(definition, serializeProduction);
}
/* istanbul ignore else */
if (node instanceof NonTerminal) {
return {
type: "NonTerminal",
name: node.nonTerminalName,
idx: node.idx
};
}
else if (node instanceof Alternative) {
return {
type: "Alternative",
definition: convertDefinition(node.definition)
};
}
else if (node instanceof Option) {
return {
type: "Option",
idx: node.idx,
definition: convertDefinition(node.definition)
};
}
else if (node instanceof RepetitionMandatory) {
return {
type: "RepetitionMandatory",
idx: node.idx,
definition: convertDefinition(node.definition)
};
}
else if (node instanceof RepetitionMandatoryWithSeparator) {
return {
type: "RepetitionMandatoryWithSeparator",
idx: node.idx,
separator: (serializeProduction(new Terminal({ terminalType: node.separator }))),
definition: convertDefinition(node.definition)
};
}
else if (node instanceof RepetitionWithSeparator) {
return {
type: "RepetitionWithSeparator",
idx: node.idx,
separator: (serializeProduction(new Terminal({ terminalType: node.separator }))),
definition: convertDefinition(node.definition)
};
}
else if (node instanceof Repetition) {
return {
type: "Repetition",
idx: node.idx,
definition: convertDefinition(node.definition)
};
}
else if (node instanceof Alternation) {
return {
type: "Alternation",
idx: node.idx,
definition: convertDefinition(node.definition)
};
}
else if (node instanceof Terminal) {
var serializedTerminal = {
type: "Terminal",
name: node.terminalType.name,
label: tokenLabel(node.terminalType),
idx: node.idx
};
var pattern = node.terminalType.PATTERN;
if (node.terminalType.PATTERN) {
serializedTerminal.pattern = isRegExp(pattern)
? pattern.source
: pattern;
}
return serializedTerminal;
}
else if (node instanceof Rule) {
return {
type: "Rule",
name: node.name,
orgText: node.orgText,
definition: convertDefinition(node.definition)
};
}
else {
throw Error("non exhaustive match");
}
}
//# sourceMappingURL=gast_public.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,33 @@
import { defaults, forEach } from "../../../utils/utils";
import { resolveGrammar as orgResolveGrammar } from "../resolver";
import { validateGrammar as orgValidateGrammar } from "../checks";
import { defaultGrammarResolverErrorProvider, defaultGrammarValidatorErrorProvider } from "../../errors_public";
import { DslMethodsCollectorVisitor } from "./gast";
export function resolveGrammar(options) {
options = defaults(options, {
errMsgProvider: defaultGrammarResolverErrorProvider
});
var topRulesTable = {};
forEach(options.rules, function (rule) {
topRulesTable[rule.name] = rule;
});
return orgResolveGrammar(topRulesTable, options.errMsgProvider);
}
export function validateGrammar(options) {
options = defaults(options, {
errMsgProvider: defaultGrammarValidatorErrorProvider
});
return orgValidateGrammar(options.rules, options.maxLookahead, options.tokenTypes, options.errMsgProvider, options.grammarName);
}
export function assignOccurrenceIndices(options) {
forEach(options.rules, function (currRule) {
var methodsCollector = new DslMethodsCollectorVisitor();
currRule.accept(methodsCollector);
forEach(methodsCollector.dslMethods, function (methods) {
forEach(methods, function (currMethod, arrIdx) {
currMethod.idx = arrIdx + 1;
});
});
});
}
//# sourceMappingURL=gast_resolver_public.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"gast_resolver_public.js","sourceRoot":"","sources":["../../../../../src/parse/grammar/gast/gast_resolver_public.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;AACxD,OAAO,EAAE,cAAc,IAAI,iBAAiB,EAAE,MAAM,aAAa,CAAA;AACjE,OAAO,EAAE,eAAe,IAAI,kBAAkB,EAAE,MAAM,WAAW,CAAA;AACjE,OAAO,EACL,mCAAmC,EACnC,oCAAoC,EACrC,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,0BAA0B,EAAE,MAAM,QAAQ,CAAA;AASnD,MAAM,UAAU,cAAc,CAAC,OAG9B;IACC,OAAO,GAAG,QAAQ,CAAC,OAAO,EAAE;QAC1B,cAAc,EAAE,mCAAmC;KACpD,CAAC,CAAA;IAEF,IAAM,aAAa,GAAG,EAAE,CAAA;IACxB,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,UAAC,IAAI;QAC1B,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IACjC,CAAC,CAAC,CAAA;IACF,OAAO,iBAAiB,CAAC,aAAa,EAAE,OAAO,CAAC,cAAc,CAAC,CAAA;AACjE,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAM/B;IACC,OAAO,GAAG,QAAQ,CAAC,OAAO,EAAE;QAC1B,cAAc,EAAE,oCAAoC;KACrD,CAAC,CAAA;IAEF,OAAO,kBAAkB,CACvB,OAAO,CAAC,KAAK,EACb,OAAO,CAAC,YAAY,EACpB,OAAO,CAAC,UAAU,EAClB,OAAO,CAAC,cAAc,EACtB,OAAO,CAAC,WAAW,CACpB,CAAA;AACH,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,OAA0B;IAChE,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,UAAC,QAAQ;QAC9B,IAAM,gBAAgB,GAAG,IAAI,0BAA0B,EAAE,CAAA;QACzD,QAAQ,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAA;QACjC,OAAO,CAAC,gBAAgB,CAAC,UAAU,EAAE,UAAC,OAAO;YAC3C,OAAO,CAAC,OAAO,EAAE,UAAC,UAAqC,EAAE,MAAM;gBAC7D,UAAU,CAAC,GAAG,GAAG,MAAM,GAAG,CAAC,CAAA;YAC7B,CAAC,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC"}

View file

@ -0,0 +1,46 @@
import { Alternation, Alternative, NonTerminal, Option, Repetition, RepetitionMandatory, RepetitionMandatoryWithSeparator, RepetitionWithSeparator, Rule, Terminal } from "./gast_public";
var GAstVisitor = /** @class */ (function () {
function GAstVisitor() {
}
GAstVisitor.prototype.visit = function (node) {
var nodeAny = node;
switch (nodeAny.constructor) {
case NonTerminal:
return this.visitNonTerminal(nodeAny);
case Alternative:
return this.visitAlternative(nodeAny);
case Option:
return this.visitOption(nodeAny);
case RepetitionMandatory:
return this.visitRepetitionMandatory(nodeAny);
case RepetitionMandatoryWithSeparator:
return this.visitRepetitionMandatoryWithSeparator(nodeAny);
case RepetitionWithSeparator:
return this.visitRepetitionWithSeparator(nodeAny);
case Repetition:
return this.visitRepetition(nodeAny);
case Alternation:
return this.visitAlternation(nodeAny);
case Terminal:
return this.visitTerminal(nodeAny);
case Rule:
return this.visitRule(nodeAny);
/* istanbul ignore next */
default:
throw Error("non exhaustive match");
}
};
GAstVisitor.prototype.visitNonTerminal = function (node) { };
GAstVisitor.prototype.visitAlternative = function (node) { };
GAstVisitor.prototype.visitOption = function (node) { };
GAstVisitor.prototype.visitRepetition = function (node) { };
GAstVisitor.prototype.visitRepetitionMandatory = function (node) { };
GAstVisitor.prototype.visitRepetitionMandatoryWithSeparator = function (node) { };
GAstVisitor.prototype.visitRepetitionWithSeparator = function (node) { };
GAstVisitor.prototype.visitAlternation = function (node) { };
GAstVisitor.prototype.visitTerminal = function (node) { };
GAstVisitor.prototype.visitRule = function (node) { };
return GAstVisitor;
}());
export { GAstVisitor };
//# sourceMappingURL=gast_visitor_public.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"gast_visitor_public.js","sourceRoot":"","sources":["../../../../../src/parse/grammar/gast/gast_visitor_public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,WAAW,EACX,WAAW,EACX,MAAM,EACN,UAAU,EACV,mBAAmB,EACnB,gCAAgC,EAChC,uBAAuB,EACvB,IAAI,EACJ,QAAQ,EACT,MAAM,eAAe,CAAA;AAGtB;IAAA;IAmDA,CAAC;IAlDQ,2BAAK,GAAZ,UAAa,IAAiB;QAC5B,IAAM,OAAO,GAAQ,IAAI,CAAA;QACzB,QAAQ,OAAO,CAAC,WAAW,EAAE;YAC3B,KAAK,WAAW;gBACd,OAAO,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAA;YACvC,KAAK,WAAW;gBACd,OAAO,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAA;YACvC,KAAK,MAAM;gBACT,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;YAClC,KAAK,mBAAmB;gBACtB,OAAO,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAA;YAC/C,KAAK,gCAAgC;gBACnC,OAAO,IAAI,CAAC,qCAAqC,CAAC,OAAO,CAAC,CAAA;YAC5D,KAAK,uBAAuB;gBAC1B,OAAO,IAAI,CAAC,4BAA4B,CAAC,OAAO,CAAC,CAAA;YACnD,KAAK,UAAU;gBACb,OAAO,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAA;YACtC,KAAK,WAAW;gBACd,OAAO,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAA;YACvC,KAAK,QAAQ;gBACX,OAAO,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAA;YACpC,KAAK,IAAI;gBACP,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;YAChC,0BAA0B;YAC1B;gBACE,MAAM,KAAK,CAAC,sBAAsB,CAAC,CAAA;SACtC;IACH,CAAC;IAEM,sCAAgB,GAAvB,UAAwB,IAAiB,IAAQ,CAAC;IAE3C,sCAAgB,GAAvB,UAAwB,IAAiB,IAAQ,CAAC;IAE3C,iCAAW,GAAlB,UAAmB,IAAY,IAAQ,CAAC;IAEjC,qCAAe,GAAtB,UAAuB,IAAgB,IAAQ,CAAC;IAEzC,8CAAwB,GAA/B,UAAgC,IAAyB,IAAQ,CAAC;IAE3D,2DAAqC,GAA5C,UACE,IAAsC,IAChC,CAAC;IAEF,kDAA4B,GAAnC,UAAoC,IAA6B,IAAQ,CAAC;IAEnE,sCAAgB,GAAvB,UAAwB,IAAiB,IAAQ,CAAC;IAE3C,mCAAa,GAApB,UAAqB,IAAc,IAAQ,CAAC;IAErC,+BAAS,GAAhB,UAAiB,IAAU,IAAQ,CAAC;IACtC,kBAAC;AAAD,CAAC,AAnDD,IAmDC"}

View file

@ -0,0 +1,543 @@
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
import { RestWalker } from "./rest";
import { cloneArr, drop, dropRight, first as _first, forEach, isEmpty, last } from "../../utils/utils";
import { first } from "./first";
import { Alternation, Alternative, NonTerminal, Option, Repetition, RepetitionMandatory, RepetitionMandatoryWithSeparator, RepetitionWithSeparator, Rule, Terminal } from "./gast/gast_public";
var AbstractNextPossibleTokensWalker = /** @class */ (function (_super) {
__extends(AbstractNextPossibleTokensWalker, _super);
function AbstractNextPossibleTokensWalker(topProd, path) {
var _this = _super.call(this) || this;
_this.topProd = topProd;
_this.path = path;
_this.possibleTokTypes = [];
_this.nextProductionName = "";
_this.nextProductionOccurrence = 0;
_this.found = false;
_this.isAtEndOfPath = false;
return _this;
}
AbstractNextPossibleTokensWalker.prototype.startWalking = function () {
this.found = false;
if (this.path.ruleStack[0] !== this.topProd.name) {
throw Error("The path does not start with the walker's top Rule!");
}
// immutable for the win
this.ruleStack = cloneArr(this.path.ruleStack).reverse(); // intelij bug requires assertion
this.occurrenceStack = cloneArr(this.path.occurrenceStack).reverse(); // intelij bug requires assertion
// already verified that the first production is valid, we now seek the 2nd production
this.ruleStack.pop();
this.occurrenceStack.pop();
this.updateExpectedNext();
this.walk(this.topProd);
return this.possibleTokTypes;
};
AbstractNextPossibleTokensWalker.prototype.walk = function (prod, prevRest) {
if (prevRest === void 0) { prevRest = []; }
// stop scanning once we found the path
if (!this.found) {
_super.prototype.walk.call(this, prod, prevRest);
}
};
AbstractNextPossibleTokensWalker.prototype.walkProdRef = function (refProd, currRest, prevRest) {
// found the next production, need to keep walking in it
if (refProd.referencedRule.name === this.nextProductionName &&
refProd.idx === this.nextProductionOccurrence) {
var fullRest = currRest.concat(prevRest);
this.updateExpectedNext();
this.walk(refProd.referencedRule, fullRest);
}
};
AbstractNextPossibleTokensWalker.prototype.updateExpectedNext = function () {
// need to consume the Terminal
if (isEmpty(this.ruleStack)) {
// must reset nextProductionXXX to avoid walking down another Top Level production while what we are
// really seeking is the last Terminal...
this.nextProductionName = "";
this.nextProductionOccurrence = 0;
this.isAtEndOfPath = true;
}
else {
this.nextProductionName = this.ruleStack.pop();
this.nextProductionOccurrence = this.occurrenceStack.pop();
}
};
return AbstractNextPossibleTokensWalker;
}(RestWalker));
export { AbstractNextPossibleTokensWalker };
var NextAfterTokenWalker = /** @class */ (function (_super) {
__extends(NextAfterTokenWalker, _super);
function NextAfterTokenWalker(topProd, path) {
var _this = _super.call(this, topProd, path) || this;
_this.path = path;
_this.nextTerminalName = "";
_this.nextTerminalOccurrence = 0;
_this.nextTerminalName = _this.path.lastTok.name;
_this.nextTerminalOccurrence = _this.path.lastTokOccurrence;
return _this;
}
NextAfterTokenWalker.prototype.walkTerminal = function (terminal, currRest, prevRest) {
if (this.isAtEndOfPath &&
terminal.terminalType.name === this.nextTerminalName &&
terminal.idx === this.nextTerminalOccurrence &&
!this.found) {
var fullRest = currRest.concat(prevRest);
var restProd = new Alternative({ definition: fullRest });
this.possibleTokTypes = first(restProd);
this.found = true;
}
};
return NextAfterTokenWalker;
}(AbstractNextPossibleTokensWalker));
export { NextAfterTokenWalker };
/**
* This walker only "walks" a single "TOP" level in the Grammar Ast, this means
* it never "follows" production refs
*/
var AbstractNextTerminalAfterProductionWalker = /** @class */ (function (_super) {
__extends(AbstractNextTerminalAfterProductionWalker, _super);
function AbstractNextTerminalAfterProductionWalker(topRule, occurrence) {
var _this = _super.call(this) || this;
_this.topRule = topRule;
_this.occurrence = occurrence;
_this.result = {
token: undefined,
occurrence: undefined,
isEndOfRule: undefined
};
return _this;
}
AbstractNextTerminalAfterProductionWalker.prototype.startWalking = function () {
this.walk(this.topRule);
return this.result;
};
return AbstractNextTerminalAfterProductionWalker;
}(RestWalker));
export { AbstractNextTerminalAfterProductionWalker };
var NextTerminalAfterManyWalker = /** @class */ (function (_super) {
__extends(NextTerminalAfterManyWalker, _super);
function NextTerminalAfterManyWalker() {
return _super !== null && _super.apply(this, arguments) || this;
}
NextTerminalAfterManyWalker.prototype.walkMany = function (manyProd, currRest, prevRest) {
if (manyProd.idx === this.occurrence) {
var firstAfterMany = _first(currRest.concat(prevRest));
this.result.isEndOfRule = firstAfterMany === undefined;
if (firstAfterMany instanceof Terminal) {
this.result.token = firstAfterMany.terminalType;
this.result.occurrence = firstAfterMany.idx;
}
}
else {
_super.prototype.walkMany.call(this, manyProd, currRest, prevRest);
}
};
return NextTerminalAfterManyWalker;
}(AbstractNextTerminalAfterProductionWalker));
export { NextTerminalAfterManyWalker };
var NextTerminalAfterManySepWalker = /** @class */ (function (_super) {
__extends(NextTerminalAfterManySepWalker, _super);
function NextTerminalAfterManySepWalker() {
return _super !== null && _super.apply(this, arguments) || this;
}
NextTerminalAfterManySepWalker.prototype.walkManySep = function (manySepProd, currRest, prevRest) {
if (manySepProd.idx === this.occurrence) {
var firstAfterManySep = _first(currRest.concat(prevRest));
this.result.isEndOfRule = firstAfterManySep === undefined;
if (firstAfterManySep instanceof Terminal) {
this.result.token = firstAfterManySep.terminalType;
this.result.occurrence = firstAfterManySep.idx;
}
}
else {
_super.prototype.walkManySep.call(this, manySepProd, currRest, prevRest);
}
};
return NextTerminalAfterManySepWalker;
}(AbstractNextTerminalAfterProductionWalker));
export { NextTerminalAfterManySepWalker };
var NextTerminalAfterAtLeastOneWalker = /** @class */ (function (_super) {
__extends(NextTerminalAfterAtLeastOneWalker, _super);
function NextTerminalAfterAtLeastOneWalker() {
return _super !== null && _super.apply(this, arguments) || this;
}
NextTerminalAfterAtLeastOneWalker.prototype.walkAtLeastOne = function (atLeastOneProd, currRest, prevRest) {
if (atLeastOneProd.idx === this.occurrence) {
var firstAfterAtLeastOne = _first(currRest.concat(prevRest));
this.result.isEndOfRule = firstAfterAtLeastOne === undefined;
if (firstAfterAtLeastOne instanceof Terminal) {
this.result.token = firstAfterAtLeastOne.terminalType;
this.result.occurrence = firstAfterAtLeastOne.idx;
}
}
else {
_super.prototype.walkAtLeastOne.call(this, atLeastOneProd, currRest, prevRest);
}
};
return NextTerminalAfterAtLeastOneWalker;
}(AbstractNextTerminalAfterProductionWalker));
export { NextTerminalAfterAtLeastOneWalker };
// TODO: reduce code duplication in the AfterWalkers
var NextTerminalAfterAtLeastOneSepWalker = /** @class */ (function (_super) {
__extends(NextTerminalAfterAtLeastOneSepWalker, _super);
function NextTerminalAfterAtLeastOneSepWalker() {
return _super !== null && _super.apply(this, arguments) || this;
}
NextTerminalAfterAtLeastOneSepWalker.prototype.walkAtLeastOneSep = function (atleastOneSepProd, currRest, prevRest) {
if (atleastOneSepProd.idx === this.occurrence) {
var firstAfterfirstAfterAtLeastOneSep = _first(currRest.concat(prevRest));
this.result.isEndOfRule = firstAfterfirstAfterAtLeastOneSep === undefined;
if (firstAfterfirstAfterAtLeastOneSep instanceof Terminal) {
this.result.token = firstAfterfirstAfterAtLeastOneSep.terminalType;
this.result.occurrence = firstAfterfirstAfterAtLeastOneSep.idx;
}
}
else {
_super.prototype.walkAtLeastOneSep.call(this, atleastOneSepProd, currRest, prevRest);
}
};
return NextTerminalAfterAtLeastOneSepWalker;
}(AbstractNextTerminalAfterProductionWalker));
export { NextTerminalAfterAtLeastOneSepWalker };
export function possiblePathsFrom(targetDef, maxLength, currPath) {
if (currPath === void 0) { currPath = []; }
// avoid side effects
currPath = cloneArr(currPath);
var result = [];
var i = 0;
// TODO: avoid inner funcs
function remainingPathWith(nextDef) {
return nextDef.concat(drop(targetDef, i + 1));
}
// TODO: avoid inner funcs
function getAlternativesForProd(definition) {
var alternatives = possiblePathsFrom(remainingPathWith(definition), maxLength, currPath);
return result.concat(alternatives);
}
/**
* Mandatory productions will halt the loop as the paths computed from their recursive calls will already contain the
* following (rest) of the targetDef.
*
* For optional productions (Option/Repetition/...) the loop will continue to represent the paths that do not include the
* the optional production.
*/
while (currPath.length < maxLength && i < targetDef.length) {
var prod = targetDef[i];
/* istanbul ignore else */
if (prod instanceof Alternative) {
return getAlternativesForProd(prod.definition);
}
else if (prod instanceof NonTerminal) {
return getAlternativesForProd(prod.definition);
}
else if (prod instanceof Option) {
result = getAlternativesForProd(prod.definition);
}
else if (prod instanceof RepetitionMandatory) {
var newDef = prod.definition.concat([
new Repetition({
definition: prod.definition
})
]);
return getAlternativesForProd(newDef);
}
else if (prod instanceof RepetitionMandatoryWithSeparator) {
var newDef = [
new Alternative({ definition: prod.definition }),
new Repetition({
definition: [new Terminal({ terminalType: prod.separator })].concat(prod.definition)
})
];
return getAlternativesForProd(newDef);
}
else if (prod instanceof RepetitionWithSeparator) {
var newDef = prod.definition.concat([
new Repetition({
definition: [new Terminal({ terminalType: prod.separator })].concat(prod.definition)
})
]);
result = getAlternativesForProd(newDef);
}
else if (prod instanceof Repetition) {
var newDef = prod.definition.concat([
new Repetition({
definition: prod.definition
})
]);
result = getAlternativesForProd(newDef);
}
else if (prod instanceof Alternation) {
forEach(prod.definition, function (currAlt) {
// TODO: this is a limited check for empty alternatives
// It would prevent a common case of infinite loops during parser initialization.
// However **in-directly** empty alternatives may still cause issues.
if (isEmpty(currAlt.definition) === false) {
result = getAlternativesForProd(currAlt.definition);
}
});
return result;
}
else if (prod instanceof Terminal) {
currPath.push(prod.terminalType);
}
else {
throw Error("non exhaustive match");
}
i++;
}
result.push({
partialPath: currPath,
suffixDef: drop(targetDef, i)
});
return result;
}
export function nextPossibleTokensAfter(initialDef, tokenVector, tokMatcher, maxLookAhead) {
var EXIT_NON_TERMINAL = "EXIT_NONE_TERMINAL";
// to avoid creating a new Array each time.
var EXIT_NON_TERMINAL_ARR = [EXIT_NON_TERMINAL];
var EXIT_ALTERNATIVE = "EXIT_ALTERNATIVE";
var foundCompletePath = false;
var tokenVectorLength = tokenVector.length;
var minimalAlternativesIndex = tokenVectorLength - maxLookAhead - 1;
var result = [];
var possiblePaths = [];
possiblePaths.push({
idx: -1,
def: initialDef,
ruleStack: [],
occurrenceStack: []
});
while (!isEmpty(possiblePaths)) {
var currPath = possiblePaths.pop();
// skip alternatives if no more results can be found (assuming deterministic grammar with fixed lookahead)
if (currPath === EXIT_ALTERNATIVE) {
if (foundCompletePath &&
last(possiblePaths).idx <= minimalAlternativesIndex) {
// remove irrelevant alternative
possiblePaths.pop();
}
continue;
}
var currDef = currPath.def;
var currIdx = currPath.idx;
var currRuleStack = currPath.ruleStack;
var currOccurrenceStack = currPath.occurrenceStack;
// For Example: an empty path could exist in a valid grammar in the case of an EMPTY_ALT
if (isEmpty(currDef)) {
continue;
}
var prod = currDef[0];
/* istanbul ignore else */
if (prod === EXIT_NON_TERMINAL) {
var nextPath = {
idx: currIdx,
def: drop(currDef),
ruleStack: dropRight(currRuleStack),
occurrenceStack: dropRight(currOccurrenceStack)
};
possiblePaths.push(nextPath);
}
else if (prod instanceof Terminal) {
/* istanbul ignore else */
if (currIdx < tokenVectorLength - 1) {
var nextIdx = currIdx + 1;
var actualToken = tokenVector[nextIdx];
if (tokMatcher(actualToken, prod.terminalType)) {
var nextPath = {
idx: nextIdx,
def: drop(currDef),
ruleStack: currRuleStack,
occurrenceStack: currOccurrenceStack
};
possiblePaths.push(nextPath);
}
// end of the line
}
else if (currIdx === tokenVectorLength - 1) {
// IGNORE ABOVE ELSE
result.push({
nextTokenType: prod.terminalType,
nextTokenOccurrence: prod.idx,
ruleStack: currRuleStack,
occurrenceStack: currOccurrenceStack
});
foundCompletePath = true;
}
else {
throw Error("non exhaustive match");
}
}
else if (prod instanceof NonTerminal) {
var newRuleStack = cloneArr(currRuleStack);
newRuleStack.push(prod.nonTerminalName);
var newOccurrenceStack = cloneArr(currOccurrenceStack);
newOccurrenceStack.push(prod.idx);
var nextPath = {
idx: currIdx,
def: prod.definition.concat(EXIT_NON_TERMINAL_ARR, drop(currDef)),
ruleStack: newRuleStack,
occurrenceStack: newOccurrenceStack
};
possiblePaths.push(nextPath);
}
else if (prod instanceof Option) {
// the order of alternatives is meaningful, FILO (Last path will be traversed first).
var nextPathWithout = {
idx: currIdx,
def: drop(currDef),
ruleStack: currRuleStack,
occurrenceStack: currOccurrenceStack
};
possiblePaths.push(nextPathWithout);
// required marker to avoid backtracking paths whose higher priority alternatives already matched
possiblePaths.push(EXIT_ALTERNATIVE);
var nextPathWith = {
idx: currIdx,
def: prod.definition.concat(drop(currDef)),
ruleStack: currRuleStack,
occurrenceStack: currOccurrenceStack
};
possiblePaths.push(nextPathWith);
}
else if (prod instanceof RepetitionMandatory) {
// TODO:(THE NEW operators here take a while...) (convert once?)
var secondIteration = new Repetition({
definition: prod.definition,
idx: prod.idx
});
var nextDef = prod.definition.concat([secondIteration], drop(currDef));
var nextPath = {
idx: currIdx,
def: nextDef,
ruleStack: currRuleStack,
occurrenceStack: currOccurrenceStack
};
possiblePaths.push(nextPath);
}
else if (prod instanceof RepetitionMandatoryWithSeparator) {
// TODO:(THE NEW operators here take a while...) (convert once?)
var separatorGast = new Terminal({
terminalType: prod.separator
});
var secondIteration = new Repetition({
definition: [separatorGast].concat(prod.definition),
idx: prod.idx
});
var nextDef = prod.definition.concat([secondIteration], drop(currDef));
var nextPath = {
idx: currIdx,
def: nextDef,
ruleStack: currRuleStack,
occurrenceStack: currOccurrenceStack
};
possiblePaths.push(nextPath);
}
else if (prod instanceof RepetitionWithSeparator) {
// the order of alternatives is meaningful, FILO (Last path will be traversed first).
var nextPathWithout = {
idx: currIdx,
def: drop(currDef),
ruleStack: currRuleStack,
occurrenceStack: currOccurrenceStack
};
possiblePaths.push(nextPathWithout);
// required marker to avoid backtracking paths whose higher priority alternatives already matched
possiblePaths.push(EXIT_ALTERNATIVE);
var separatorGast = new Terminal({
terminalType: prod.separator
});
var nthRepetition = new Repetition({
definition: [separatorGast].concat(prod.definition),
idx: prod.idx
});
var nextDef = prod.definition.concat([nthRepetition], drop(currDef));
var nextPathWith = {
idx: currIdx,
def: nextDef,
ruleStack: currRuleStack,
occurrenceStack: currOccurrenceStack
};
possiblePaths.push(nextPathWith);
}
else if (prod instanceof Repetition) {
// the order of alternatives is meaningful, FILO (Last path will be traversed first).
var nextPathWithout = {
idx: currIdx,
def: drop(currDef),
ruleStack: currRuleStack,
occurrenceStack: currOccurrenceStack
};
possiblePaths.push(nextPathWithout);
// required marker to avoid backtracking paths whose higher priority alternatives already matched
possiblePaths.push(EXIT_ALTERNATIVE);
// TODO: an empty repetition will cause infinite loops here, will the parser detect this in selfAnalysis?
var nthRepetition = new Repetition({
definition: prod.definition,
idx: prod.idx
});
var nextDef = prod.definition.concat([nthRepetition], drop(currDef));
var nextPathWith = {
idx: currIdx,
def: nextDef,
ruleStack: currRuleStack,
occurrenceStack: currOccurrenceStack
};
possiblePaths.push(nextPathWith);
}
else if (prod instanceof Alternation) {
// the order of alternatives is meaningful, FILO (Last path will be traversed first).
for (var i = prod.definition.length - 1; i >= 0; i--) {
var currAlt = prod.definition[i];
var currAltPath = {
idx: currIdx,
def: currAlt.definition.concat(drop(currDef)),
ruleStack: currRuleStack,
occurrenceStack: currOccurrenceStack
};
possiblePaths.push(currAltPath);
possiblePaths.push(EXIT_ALTERNATIVE);
}
}
else if (prod instanceof Alternative) {
possiblePaths.push({
idx: currIdx,
def: prod.definition.concat(drop(currDef)),
ruleStack: currRuleStack,
occurrenceStack: currOccurrenceStack
});
}
else if (prod instanceof Rule) {
// last because we should only encounter at most a single one of these per invocation.
possiblePaths.push(expandTopLevelRule(prod, currIdx, currRuleStack, currOccurrenceStack));
}
else {
throw Error("non exhaustive match");
}
}
return result;
}
function expandTopLevelRule(topRule, currIdx, currRuleStack, currOccurrenceStack) {
var newRuleStack = cloneArr(currRuleStack);
newRuleStack.push(topRule.name);
var newCurrOccurrenceStack = cloneArr(currOccurrenceStack);
// top rule is always assumed to have been called with occurrence index 1
newCurrOccurrenceStack.push(1);
return {
idx: currIdx,
def: topRule.definition,
ruleStack: newRuleStack,
occurrenceStack: newCurrOccurrenceStack
};
}
//# sourceMappingURL=interpreter.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,30 @@
// Lookahead keys are 32Bit integers in the form
// TTTTTTTT-ZZZZZZZZZZZZ-YYYY-XXXXXXXX
// XXXX -> Occurrence Index bitmap.
// YYYY -> DSL Method Type bitmap.
// ZZZZZZZZZZZZZZZ -> Rule short Index bitmap.
// TTTTTTTTT -> alternation alternative index bitmap
export var BITS_FOR_METHOD_TYPE = 4;
export var BITS_FOR_OCCURRENCE_IDX = 8;
export var BITS_FOR_RULE_IDX = 12;
// TODO: validation, this means that there may at most 2^8 --> 256 alternatives for an alternation.
export var BITS_FOR_ALT_IDX = 8;
// short string used as part of mapping keys.
// being short improves the performance when composing KEYS for maps out of these
// The 5 - 8 bits (16 possible values, are reserved for the DSL method indices)
/* tslint:disable */
export var OR_IDX = 1 << BITS_FOR_OCCURRENCE_IDX;
export var OPTION_IDX = 2 << BITS_FOR_OCCURRENCE_IDX;
export var MANY_IDX = 3 << BITS_FOR_OCCURRENCE_IDX;
export var AT_LEAST_ONE_IDX = 4 << BITS_FOR_OCCURRENCE_IDX;
export var MANY_SEP_IDX = 5 << BITS_FOR_OCCURRENCE_IDX;
export var AT_LEAST_ONE_SEP_IDX = 6 << BITS_FOR_OCCURRENCE_IDX;
/* tslint:enable */
// this actually returns a number, but it is always used as a string (object prop key)
export function getKeyForAutomaticLookahead(ruleIdx, dslMethodIdx, occurrence) {
/* tslint:disable */
return occurrence | dslMethodIdx | ruleIdx;
/* tslint:enable */
}
var BITS_START_FOR_ALT_IDX = 32 - BITS_FOR_ALT_IDX;
//# sourceMappingURL=keys.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"keys.js","sourceRoot":"","sources":["../../../../src/parse/grammar/keys.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,sCAAsC;AACtC,mCAAmC;AACnC,kCAAkC;AAClC,8CAA8C;AAC9C,oDAAoD;AAEpD,MAAM,CAAC,IAAM,oBAAoB,GAAG,CAAC,CAAA;AACrC,MAAM,CAAC,IAAM,uBAAuB,GAAG,CAAC,CAAA;AACxC,MAAM,CAAC,IAAM,iBAAiB,GAAG,EAAE,CAAA;AACnC,mGAAmG;AACnG,MAAM,CAAC,IAAM,gBAAgB,GAAG,CAAC,CAAA;AAEjC,6CAA6C;AAC7C,iFAAiF;AACjF,+EAA+E;AAC/E,oBAAoB;AACpB,MAAM,CAAC,IAAM,MAAM,GAAG,CAAC,IAAI,uBAAuB,CAAA;AAClD,MAAM,CAAC,IAAM,UAAU,GAAG,CAAC,IAAI,uBAAuB,CAAA;AACtD,MAAM,CAAC,IAAM,QAAQ,GAAG,CAAC,IAAI,uBAAuB,CAAA;AACpD,MAAM,CAAC,IAAM,gBAAgB,GAAG,CAAC,IAAI,uBAAuB,CAAA;AAC5D,MAAM,CAAC,IAAM,YAAY,GAAG,CAAC,IAAI,uBAAuB,CAAA;AACxD,MAAM,CAAC,IAAM,oBAAoB,GAAG,CAAC,IAAI,uBAAuB,CAAA;AAChE,mBAAmB;AAEnB,sFAAsF;AACtF,MAAM,UAAU,2BAA2B,CACzC,OAAe,EACf,YAAoB,EACpB,UAAkB;IAElB,oBAAoB;IACpB,OAAO,UAAU,GAAG,YAAY,GAAG,OAAO,CAAA;IAC1C,mBAAmB;AACrB,CAAC;AAED,IAAM,sBAAsB,GAAG,EAAE,GAAG,gBAAgB,CAAA"}

View file

@ -0,0 +1,485 @@
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
import { map, reduce, every, isEmpty, flatten, forEach, has } from "../../utils/utils";
import { possiblePathsFrom } from "./interpreter";
import { RestWalker } from "./rest";
import { tokenStructuredMatcher, tokenStructuredMatcherNoCategories } from "../../scan/tokens";
import { Alternation, Alternative as AlternativeGAST, Option, Repetition, RepetitionMandatory, RepetitionMandatoryWithSeparator, RepetitionWithSeparator } from "./gast/gast_public";
import { GAstVisitor } from "./gast/gast_visitor_public";
export var PROD_TYPE;
(function (PROD_TYPE) {
PROD_TYPE[PROD_TYPE["OPTION"] = 0] = "OPTION";
PROD_TYPE[PROD_TYPE["REPETITION"] = 1] = "REPETITION";
PROD_TYPE[PROD_TYPE["REPETITION_MANDATORY"] = 2] = "REPETITION_MANDATORY";
PROD_TYPE[PROD_TYPE["REPETITION_MANDATORY_WITH_SEPARATOR"] = 3] = "REPETITION_MANDATORY_WITH_SEPARATOR";
PROD_TYPE[PROD_TYPE["REPETITION_WITH_SEPARATOR"] = 4] = "REPETITION_WITH_SEPARATOR";
PROD_TYPE[PROD_TYPE["ALTERNATION"] = 5] = "ALTERNATION";
})(PROD_TYPE || (PROD_TYPE = {}));
export function getProdType(prod) {
/* istanbul ignore else */
if (prod instanceof Option) {
return PROD_TYPE.OPTION;
}
else if (prod instanceof Repetition) {
return PROD_TYPE.REPETITION;
}
else if (prod instanceof RepetitionMandatory) {
return PROD_TYPE.REPETITION_MANDATORY;
}
else if (prod instanceof RepetitionMandatoryWithSeparator) {
return PROD_TYPE.REPETITION_MANDATORY_WITH_SEPARATOR;
}
else if (prod instanceof RepetitionWithSeparator) {
return PROD_TYPE.REPETITION_WITH_SEPARATOR;
}
else if (prod instanceof Alternation) {
return PROD_TYPE.ALTERNATION;
}
else {
throw Error("non exhaustive match");
}
}
export function buildLookaheadFuncForOr(occurrence, ruleGrammar, maxLookahead, hasPredicates, dynamicTokensEnabled, laFuncBuilder) {
var lookAheadPaths = getLookaheadPathsForOr(occurrence, ruleGrammar, maxLookahead);
var tokenMatcher = areTokenCategoriesNotUsed(lookAheadPaths)
? tokenStructuredMatcherNoCategories
: tokenStructuredMatcher;
return laFuncBuilder(lookAheadPaths, hasPredicates, tokenMatcher, dynamicTokensEnabled);
}
/**
* When dealing with an Optional production (OPTION/MANY/2nd iteration of AT_LEAST_ONE/...) we need to compare
* the lookahead "inside" the production and the lookahead immediately "after" it in the same top level rule (context free).
*
* Example: given a production:
* ABC(DE)?DF
*
* The optional '(DE)?' should only be entered if we see 'DE'. a single Token 'D' is not sufficient to distinguish between the two
* alternatives.
*
* @returns A Lookahead function which will return true IFF the parser should parse the Optional production.
*/
export function buildLookaheadFuncForOptionalProd(occurrence, ruleGrammar, k, dynamicTokensEnabled, prodType, lookaheadBuilder) {
var lookAheadPaths = getLookaheadPathsForOptionalProd(occurrence, ruleGrammar, prodType, k);
var tokenMatcher = areTokenCategoriesNotUsed(lookAheadPaths)
? tokenStructuredMatcherNoCategories
: tokenStructuredMatcher;
return lookaheadBuilder(lookAheadPaths[0], tokenMatcher, dynamicTokensEnabled);
}
export function buildAlternativesLookAheadFunc(alts, hasPredicates, tokenMatcher, dynamicTokensEnabled) {
var numOfAlts = alts.length;
var areAllOneTokenLookahead = every(alts, function (currAlt) {
return every(currAlt, function (currPath) {
return currPath.length === 1;
});
});
// This version takes into account the predicates as well.
if (hasPredicates) {
/**
* @returns {number} - The chosen alternative index
*/
return function (orAlts) {
// unfortunately the predicates must be extracted every single time
// as they cannot be cached due to references to parameters(vars) which are no longer valid.
// note that in the common case of no predicates, no cpu time will be wasted on this (see else block)
var predicates = map(orAlts, function (currAlt) { return currAlt.GATE; });
for (var t = 0; t < numOfAlts; t++) {
var currAlt = alts[t];
var currNumOfPaths = currAlt.length;
var currPredicate = predicates[t];
if (currPredicate !== undefined && currPredicate.call(this) === false) {
// if the predicate does not match there is no point in checking the paths
continue;
}
nextPath: for (var j = 0; j < currNumOfPaths; j++) {
var currPath = currAlt[j];
var currPathLength = currPath.length;
for (var i = 0; i < currPathLength; i++) {
var nextToken = this.LA(i + 1);
if (tokenMatcher(nextToken, currPath[i]) === false) {
// mismatch in current path
// try the next pth
continue nextPath;
}
}
// found a full path that matches.
// this will also work for an empty ALT as the loop will be skipped
return t;
}
// none of the paths for the current alternative matched
// try the next alternative
}
// none of the alternatives could be matched
return undefined;
};
}
else if (areAllOneTokenLookahead && !dynamicTokensEnabled) {
// optimized (common) case of all the lookaheads paths requiring only
// a single token lookahead. These Optimizations cannot work if dynamically defined Tokens are used.
var singleTokenAlts = map(alts, function (currAlt) {
return flatten(currAlt);
});
var choiceToAlt_1 = reduce(singleTokenAlts, function (result, currAlt, idx) {
forEach(currAlt, function (currTokType) {
if (!has(result, currTokType.tokenTypeIdx)) {
result[currTokType.tokenTypeIdx] = idx;
}
forEach(currTokType.categoryMatches, function (currExtendingType) {
if (!has(result, currExtendingType)) {
result[currExtendingType] = idx;
}
});
});
return result;
}, []);
/**
* @returns {number} - The chosen alternative index
*/
return function () {
var nextToken = this.LA(1);
return choiceToAlt_1[nextToken.tokenTypeIdx];
};
}
else {
// optimized lookahead without needing to check the predicates at all.
// this causes code duplication which is intentional to improve performance.
/**
* @returns {number} - The chosen alternative index
*/
return function () {
for (var t = 0; t < numOfAlts; t++) {
var currAlt = alts[t];
var currNumOfPaths = currAlt.length;
nextPath: for (var j = 0; j < currNumOfPaths; j++) {
var currPath = currAlt[j];
var currPathLength = currPath.length;
for (var i = 0; i < currPathLength; i++) {
var nextToken = this.LA(i + 1);
if (tokenMatcher(nextToken, currPath[i]) === false) {
// mismatch in current path
// try the next pth
continue nextPath;
}
}
// found a full path that matches.
// this will also work for an empty ALT as the loop will be skipped
return t;
}
// none of the paths for the current alternative matched
// try the next alternative
}
// none of the alternatives could be matched
return undefined;
};
}
}
export function buildSingleAlternativeLookaheadFunction(alt, tokenMatcher, dynamicTokensEnabled) {
var areAllOneTokenLookahead = every(alt, function (currPath) {
return currPath.length === 1;
});
var numOfPaths = alt.length;
// optimized (common) case of all the lookaheads paths requiring only
// a single token lookahead.
if (areAllOneTokenLookahead && !dynamicTokensEnabled) {
var singleTokensTypes = flatten(alt);
if (singleTokensTypes.length === 1 &&
isEmpty(singleTokensTypes[0].categoryMatches)) {
var expectedTokenType = singleTokensTypes[0];
var expectedTokenUniqueKey_1 = expectedTokenType.tokenTypeIdx;
return function () {
return this.LA(1).tokenTypeIdx === expectedTokenUniqueKey_1;
};
}
else {
var choiceToAlt_2 = reduce(singleTokensTypes, function (result, currTokType, idx) {
result[currTokType.tokenTypeIdx] = true;
forEach(currTokType.categoryMatches, function (currExtendingType) {
result[currExtendingType] = true;
});
return result;
}, []);
return function () {
var nextToken = this.LA(1);
return choiceToAlt_2[nextToken.tokenTypeIdx] === true;
};
}
}
else {
return function () {
nextPath: for (var j = 0; j < numOfPaths; j++) {
var currPath = alt[j];
var currPathLength = currPath.length;
for (var i = 0; i < currPathLength; i++) {
var nextToken = this.LA(i + 1);
if (tokenMatcher(nextToken, currPath[i]) === false) {
// mismatch in current path
// try the next pth
continue nextPath;
}
}
// found a full path that matches.
return true;
}
// none of the paths matched
return false;
};
}
}
var RestDefinitionFinderWalker = /** @class */ (function (_super) {
__extends(RestDefinitionFinderWalker, _super);
function RestDefinitionFinderWalker(topProd, targetOccurrence, targetProdType) {
var _this = _super.call(this) || this;
_this.topProd = topProd;
_this.targetOccurrence = targetOccurrence;
_this.targetProdType = targetProdType;
return _this;
}
RestDefinitionFinderWalker.prototype.startWalking = function () {
this.walk(this.topProd);
return this.restDef;
};
RestDefinitionFinderWalker.prototype.checkIsTarget = function (node, expectedProdType, currRest, prevRest) {
if (node.idx === this.targetOccurrence &&
this.targetProdType === expectedProdType) {
this.restDef = currRest.concat(prevRest);
return true;
}
// performance optimization, do not iterate over the entire Grammar ast after we have found the target
return false;
};
RestDefinitionFinderWalker.prototype.walkOption = function (optionProd, currRest, prevRest) {
if (!this.checkIsTarget(optionProd, PROD_TYPE.OPTION, currRest, prevRest)) {
_super.prototype.walkOption.call(this, optionProd, currRest, prevRest);
}
};
RestDefinitionFinderWalker.prototype.walkAtLeastOne = function (atLeastOneProd, currRest, prevRest) {
if (!this.checkIsTarget(atLeastOneProd, PROD_TYPE.REPETITION_MANDATORY, currRest, prevRest)) {
_super.prototype.walkOption.call(this, atLeastOneProd, currRest, prevRest);
}
};
RestDefinitionFinderWalker.prototype.walkAtLeastOneSep = function (atLeastOneSepProd, currRest, prevRest) {
if (!this.checkIsTarget(atLeastOneSepProd, PROD_TYPE.REPETITION_MANDATORY_WITH_SEPARATOR, currRest, prevRest)) {
_super.prototype.walkOption.call(this, atLeastOneSepProd, currRest, prevRest);
}
};
RestDefinitionFinderWalker.prototype.walkMany = function (manyProd, currRest, prevRest) {
if (!this.checkIsTarget(manyProd, PROD_TYPE.REPETITION, currRest, prevRest)) {
_super.prototype.walkOption.call(this, manyProd, currRest, prevRest);
}
};
RestDefinitionFinderWalker.prototype.walkManySep = function (manySepProd, currRest, prevRest) {
if (!this.checkIsTarget(manySepProd, PROD_TYPE.REPETITION_WITH_SEPARATOR, currRest, prevRest)) {
_super.prototype.walkOption.call(this, manySepProd, currRest, prevRest);
}
};
return RestDefinitionFinderWalker;
}(RestWalker));
/**
* Returns the definition of a target production in a top level level rule.
*/
var InsideDefinitionFinderVisitor = /** @class */ (function (_super) {
__extends(InsideDefinitionFinderVisitor, _super);
function InsideDefinitionFinderVisitor(targetOccurrence, targetProdType, targetRef) {
var _this = _super.call(this) || this;
_this.targetOccurrence = targetOccurrence;
_this.targetProdType = targetProdType;
_this.targetRef = targetRef;
_this.result = [];
return _this;
}
InsideDefinitionFinderVisitor.prototype.checkIsTarget = function (node, expectedProdName) {
if (node.idx === this.targetOccurrence &&
this.targetProdType === expectedProdName &&
(this.targetRef === undefined || node === this.targetRef)) {
this.result = node.definition;
}
};
InsideDefinitionFinderVisitor.prototype.visitOption = function (node) {
this.checkIsTarget(node, PROD_TYPE.OPTION);
};
InsideDefinitionFinderVisitor.prototype.visitRepetition = function (node) {
this.checkIsTarget(node, PROD_TYPE.REPETITION);
};
InsideDefinitionFinderVisitor.prototype.visitRepetitionMandatory = function (node) {
this.checkIsTarget(node, PROD_TYPE.REPETITION_MANDATORY);
};
InsideDefinitionFinderVisitor.prototype.visitRepetitionMandatoryWithSeparator = function (node) {
this.checkIsTarget(node, PROD_TYPE.REPETITION_MANDATORY_WITH_SEPARATOR);
};
InsideDefinitionFinderVisitor.prototype.visitRepetitionWithSeparator = function (node) {
this.checkIsTarget(node, PROD_TYPE.REPETITION_WITH_SEPARATOR);
};
InsideDefinitionFinderVisitor.prototype.visitAlternation = function (node) {
this.checkIsTarget(node, PROD_TYPE.ALTERNATION);
};
return InsideDefinitionFinderVisitor;
}(GAstVisitor));
function initializeArrayOfArrays(size) {
var result = new Array(size);
for (var i = 0; i < size; i++) {
result[i] = [];
}
return result;
}
/**
* A sort of hash function between a Path in the grammar and a string.
* Note that this returns multiple "hashes" to support the scenario of token categories.
* - A single path with categories may match multiple **actual** paths.
*/
function pathToHashKeys(path) {
var keys = [""];
for (var i = 0; i < path.length; i++) {
var tokType = path[i];
var longerKeys = [];
for (var j = 0; j < keys.length; j++) {
var currShorterKey = keys[j];
longerKeys.push(currShorterKey + "_" + tokType.tokenTypeIdx);
for (var t = 0; t < tokType.categoryMatches.length; t++) {
var categoriesKeySuffix = "_" + tokType.categoryMatches[t];
longerKeys.push(currShorterKey + categoriesKeySuffix);
}
}
keys = longerKeys;
}
return keys;
}
/**
* Imperative style due to being called from a hot spot
*/
function isUniquePrefixHash(altKnownPathsKeys, searchPathKeys, idx) {
for (var currAltIdx = 0; currAltIdx < altKnownPathsKeys.length; currAltIdx++) {
// We only want to test vs the other alternatives
if (currAltIdx === idx) {
continue;
}
var otherAltKnownPathsKeys = altKnownPathsKeys[currAltIdx];
for (var searchIdx = 0; searchIdx < searchPathKeys.length; searchIdx++) {
var searchKey = searchPathKeys[searchIdx];
if (otherAltKnownPathsKeys[searchKey] === true) {
return false;
}
}
}
// None of the SearchPathKeys were found in any of the other alternatives
return true;
}
export function lookAheadSequenceFromAlternatives(altsDefs, k) {
var partialAlts = map(altsDefs, function (currAlt) { return possiblePathsFrom([currAlt], 1); });
var finalResult = initializeArrayOfArrays(partialAlts.length);
var altsHashes = map(partialAlts, function (currAltPaths) {
var dict = {};
forEach(currAltPaths, function (item) {
var keys = pathToHashKeys(item.partialPath);
forEach(keys, function (currKey) {
dict[currKey] = true;
});
});
return dict;
});
var newData = partialAlts;
// maxLookahead loop
for (var pathLength = 1; pathLength <= k; pathLength++) {
var currDataset = newData;
newData = initializeArrayOfArrays(currDataset.length);
var _loop_1 = function (altIdx) {
var currAltPathsAndSuffixes = currDataset[altIdx];
// paths in current alternative loop
for (var currPathIdx = 0; currPathIdx < currAltPathsAndSuffixes.length; currPathIdx++) {
var currPathPrefix = currAltPathsAndSuffixes[currPathIdx].partialPath;
var suffixDef = currAltPathsAndSuffixes[currPathIdx].suffixDef;
var prefixKeys = pathToHashKeys(currPathPrefix);
var isUnique = isUniquePrefixHash(altsHashes, prefixKeys, altIdx);
// End of the line for this path.
if (isUnique || isEmpty(suffixDef) || currPathPrefix.length === k) {
var currAltResult = finalResult[altIdx];
// TODO: Can we implement a containsPath using Maps/Dictionaries?
if (containsPath(currAltResult, currPathPrefix) === false) {
currAltResult.push(currPathPrefix);
// Update all new keys for the current path.
for (var j = 0; j < prefixKeys.length; j++) {
var currKey = prefixKeys[j];
altsHashes[altIdx][currKey] = true;
}
}
}
// Expand longer paths
else {
var newPartialPathsAndSuffixes = possiblePathsFrom(suffixDef, pathLength + 1, currPathPrefix);
newData[altIdx] = newData[altIdx].concat(newPartialPathsAndSuffixes);
// Update keys for new known paths
forEach(newPartialPathsAndSuffixes, function (item) {
var prefixKeys = pathToHashKeys(item.partialPath);
forEach(prefixKeys, function (key) {
altsHashes[altIdx][key] = true;
});
});
}
}
};
// alternatives loop
for (var altIdx = 0; altIdx < currDataset.length; altIdx++) {
_loop_1(altIdx);
}
}
return finalResult;
}
export function getLookaheadPathsForOr(occurrence, ruleGrammar, k, orProd) {
var visitor = new InsideDefinitionFinderVisitor(occurrence, PROD_TYPE.ALTERNATION, orProd);
ruleGrammar.accept(visitor);
return lookAheadSequenceFromAlternatives(visitor.result, k);
}
export function getLookaheadPathsForOptionalProd(occurrence, ruleGrammar, prodType, k) {
var insideDefVisitor = new InsideDefinitionFinderVisitor(occurrence, prodType);
ruleGrammar.accept(insideDefVisitor);
var insideDef = insideDefVisitor.result;
var afterDefWalker = new RestDefinitionFinderWalker(ruleGrammar, occurrence, prodType);
var afterDef = afterDefWalker.startWalking();
var insideFlat = new AlternativeGAST({ definition: insideDef });
var afterFlat = new AlternativeGAST({ definition: afterDef });
return lookAheadSequenceFromAlternatives([insideFlat, afterFlat], k);
}
export function containsPath(alternative, searchPath) {
compareOtherPath: for (var i = 0; i < alternative.length; i++) {
var otherPath = alternative[i];
if (otherPath.length !== searchPath.length) {
continue;
}
for (var j = 0; j < otherPath.length; j++) {
var searchTok = searchPath[j];
var otherTok = otherPath[j];
var matchingTokens = searchTok === otherTok ||
otherTok.categoryMatchesMap[searchTok.tokenTypeIdx] !== undefined;
if (matchingTokens === false) {
continue compareOtherPath;
}
}
return true;
}
return false;
}
export function isStrictPrefixOfPath(prefix, other) {
return (prefix.length < other.length &&
every(prefix, function (tokType, idx) {
var otherTokType = other[idx];
return (tokType === otherTokType ||
otherTokType.categoryMatchesMap[tokType.tokenTypeIdx]);
}));
}
export function areTokenCategoriesNotUsed(lookAheadPaths) {
return every(lookAheadPaths, function (singleAltPaths) {
return every(singleAltPaths, function (singlePath) {
return every(singlePath, function (token) { return isEmpty(token.categoryMatches); });
});
});
}
//# sourceMappingURL=lookahead.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,56 @@
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
import { ParserDefinitionErrorType } from "../parser/parser";
import { forEach, values } from "../../utils/utils";
import { GAstVisitor } from "./gast/gast_visitor_public";
export function resolveGrammar(topLevels, errMsgProvider) {
var refResolver = new GastRefResolverVisitor(topLevels, errMsgProvider);
refResolver.resolveRefs();
return refResolver.errors;
}
var GastRefResolverVisitor = /** @class */ (function (_super) {
__extends(GastRefResolverVisitor, _super);
function GastRefResolverVisitor(nameToTopRule, errMsgProvider) {
var _this = _super.call(this) || this;
_this.nameToTopRule = nameToTopRule;
_this.errMsgProvider = errMsgProvider;
_this.errors = [];
return _this;
}
GastRefResolverVisitor.prototype.resolveRefs = function () {
var _this = this;
forEach(values(this.nameToTopRule), function (prod) {
_this.currTopLevel = prod;
prod.accept(_this);
});
};
GastRefResolverVisitor.prototype.visitNonTerminal = function (node) {
var ref = this.nameToTopRule[node.nonTerminalName];
if (!ref) {
var msg = this.errMsgProvider.buildRuleNotFoundError(this.currTopLevel, node);
this.errors.push({
message: msg,
type: ParserDefinitionErrorType.UNRESOLVED_SUBRULE_REF,
ruleName: this.currTopLevel.name,
unresolvedRefName: node.nonTerminalName
});
}
else {
node.referencedRule = ref;
}
};
return GastRefResolverVisitor;
}(GAstVisitor));
export { GastRefResolverVisitor };
//# sourceMappingURL=resolver.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"resolver.js","sourceRoot":"","sources":["../../../../src/parse/grammar/resolver.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,OAAO,EAEL,yBAAyB,EAC1B,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAEnD,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AAMxD,MAAM,UAAU,cAAc,CAC5B,SAA+B,EAC/B,cAAoD;IAEpD,IAAI,WAAW,GAAG,IAAI,sBAAsB,CAAC,SAAS,EAAE,cAAc,CAAC,CAAA;IACvE,WAAW,CAAC,WAAW,EAAE,CAAA;IACzB,OAAO,WAAW,CAAC,MAAM,CAAA;AAC3B,CAAC;AAED;IAA4C,0CAAW;IAIrD,gCACU,aAAmC,EACnC,cAAoD;QAF9D,YAIE,iBAAO,SACR;QAJS,mBAAa,GAAb,aAAa,CAAsB;QACnC,oBAAc,GAAd,cAAc,CAAsC;QALvD,YAAM,GAA0C,EAAE,CAAA;;IAQzD,CAAC;IAEM,4CAAW,GAAlB;QAAA,iBAKC;QAJC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,UAAC,IAAI;YACvC,KAAI,CAAC,YAAY,GAAG,IAAI,CAAA;YACxB,IAAI,CAAC,MAAM,CAAC,KAAI,CAAC,CAAA;QACnB,CAAC,CAAC,CAAA;IACJ,CAAC;IAEM,iDAAgB,GAAvB,UAAwB,IAAiB;QACvC,IAAI,GAAG,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA;QAElD,IAAI,CAAC,GAAG,EAAE;YACR,IAAI,GAAG,GAAG,IAAI,CAAC,cAAc,CAAC,sBAAsB,CAClD,IAAI,CAAC,YAAY,EACjB,IAAI,CACL,CAAA;YACD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;gBACf,OAAO,EAAE,GAAG;gBACZ,IAAI,EAAE,yBAAyB,CAAC,sBAAsB;gBACtD,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC,IAAI;gBAChC,iBAAiB,EAAE,IAAI,CAAC,eAAe;aACxC,CAAC,CAAA;SACH;aAAM;YACL,IAAI,CAAC,cAAc,GAAG,GAAG,CAAA;SAC1B;IACH,CAAC;IACH,6BAAC;AAAD,CAAC,AApCD,CAA4C,WAAW,GAoCtD"}

View file

@ -0,0 +1,108 @@
import { drop, forEach } from "../../utils/utils";
import { Alternation, Alternative, NonTerminal, Option, Repetition, RepetitionMandatory, RepetitionMandatoryWithSeparator, RepetitionWithSeparator, Terminal } from "./gast/gast_public";
/**
* A Grammar Walker that computes the "remaining" grammar "after" a productions in the grammar.
*/
var RestWalker = /** @class */ (function () {
function RestWalker() {
}
RestWalker.prototype.walk = function (prod, prevRest) {
var _this = this;
if (prevRest === void 0) { prevRest = []; }
forEach(prod.definition, function (subProd, index) {
var currRest = drop(prod.definition, index + 1);
/* istanbul ignore else */
if (subProd instanceof NonTerminal) {
_this.walkProdRef(subProd, currRest, prevRest);
}
else if (subProd instanceof Terminal) {
_this.walkTerminal(subProd, currRest, prevRest);
}
else if (subProd instanceof Alternative) {
_this.walkFlat(subProd, currRest, prevRest);
}
else if (subProd instanceof Option) {
_this.walkOption(subProd, currRest, prevRest);
}
else if (subProd instanceof RepetitionMandatory) {
_this.walkAtLeastOne(subProd, currRest, prevRest);
}
else if (subProd instanceof RepetitionMandatoryWithSeparator) {
_this.walkAtLeastOneSep(subProd, currRest, prevRest);
}
else if (subProd instanceof RepetitionWithSeparator) {
_this.walkManySep(subProd, currRest, prevRest);
}
else if (subProd instanceof Repetition) {
_this.walkMany(subProd, currRest, prevRest);
}
else if (subProd instanceof Alternation) {
_this.walkOr(subProd, currRest, prevRest);
}
else {
throw Error("non exhaustive match");
}
});
};
RestWalker.prototype.walkTerminal = function (terminal, currRest, prevRest) { };
RestWalker.prototype.walkProdRef = function (refProd, currRest, prevRest) { };
RestWalker.prototype.walkFlat = function (flatProd, currRest, prevRest) {
// ABCDEF => after the D the rest is EF
var fullOrRest = currRest.concat(prevRest);
this.walk(flatProd, fullOrRest);
};
RestWalker.prototype.walkOption = function (optionProd, currRest, prevRest) {
// ABC(DE)?F => after the (DE)? the rest is F
var fullOrRest = currRest.concat(prevRest);
this.walk(optionProd, fullOrRest);
};
RestWalker.prototype.walkAtLeastOne = function (atLeastOneProd, currRest, prevRest) {
// ABC(DE)+F => after the (DE)+ the rest is (DE)?F
var fullAtLeastOneRest = [
new Option({ definition: atLeastOneProd.definition })
].concat(currRest, prevRest);
this.walk(atLeastOneProd, fullAtLeastOneRest);
};
RestWalker.prototype.walkAtLeastOneSep = function (atLeastOneSepProd, currRest, prevRest) {
// ABC DE(,DE)* F => after the (,DE)+ the rest is (,DE)?F
var fullAtLeastOneSepRest = restForRepetitionWithSeparator(atLeastOneSepProd, currRest, prevRest);
this.walk(atLeastOneSepProd, fullAtLeastOneSepRest);
};
RestWalker.prototype.walkMany = function (manyProd, currRest, prevRest) {
// ABC(DE)*F => after the (DE)* the rest is (DE)?F
var fullManyRest = [
new Option({ definition: manyProd.definition })
].concat(currRest, prevRest);
this.walk(manyProd, fullManyRest);
};
RestWalker.prototype.walkManySep = function (manySepProd, currRest, prevRest) {
// ABC (DE(,DE)*)? F => after the (,DE)* the rest is (,DE)?F
var fullManySepRest = restForRepetitionWithSeparator(manySepProd, currRest, prevRest);
this.walk(manySepProd, fullManySepRest);
};
RestWalker.prototype.walkOr = function (orProd, currRest, prevRest) {
var _this = this;
// ABC(D|E|F)G => when finding the (D|E|F) the rest is G
var fullOrRest = currRest.concat(prevRest);
// walk all different alternatives
forEach(orProd.definition, function (alt) {
// wrapping each alternative in a single definition wrapper
// to avoid errors in computing the rest of that alternative in the invocation to computeInProdFollows
// (otherwise for OR([alt1,alt2]) alt2 will be considered in 'rest' of alt1
var prodWrapper = new Alternative({ definition: [alt] });
_this.walk(prodWrapper, fullOrRest);
});
};
return RestWalker;
}());
export { RestWalker };
function restForRepetitionWithSeparator(repSepProd, currRest, prevRest) {
var repSepRest = [
new Option({
definition: [new Terminal({ terminalType: repSepProd.separator })].concat(repSepProd.definition)
})
];
var fullRepSepRest = repSepRest.concat(currRest, prevRest);
return fullRepSepRest;
}
//# sourceMappingURL=rest.js.map

View file

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

View file

@ -0,0 +1,217 @@
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
import { applyMixins, cloneObj, forEach, has, isEmpty, map, toFastProperties, values } from "../../utils/utils";
import { computeAllProdsFollows } from "../grammar/follow";
import { createTokenInstance, EOF } from "../../scan/tokens_public";
import { defaultGrammarValidatorErrorProvider, defaultParserErrorProvider } from "../errors_public";
import { resolveGrammar, validateGrammar } from "../grammar/gast/gast_resolver_public";
import { Recoverable } from "./traits/recoverable";
import { LooksAhead } from "./traits/looksahead";
import { TreeBuilder } from "./traits/tree_builder";
import { LexerAdapter } from "./traits/lexer_adapter";
import { RecognizerApi } from "./traits/recognizer_api";
import { RecognizerEngine } from "./traits/recognizer_engine";
import { ErrorHandler } from "./traits/error_handler";
import { ContentAssist } from "./traits/context_assist";
import { GastRecorder } from "./traits/gast_recorder";
import { PerformanceTracer } from "./traits/perf_tracer";
export var END_OF_FILE = createTokenInstance(EOF, "", NaN, NaN, NaN, NaN, NaN, NaN);
Object.freeze(END_OF_FILE);
export var DEFAULT_PARSER_CONFIG = Object.freeze({
recoveryEnabled: false,
maxLookahead: 3,
dynamicTokensEnabled: false,
outputCst: true,
errorMessageProvider: defaultParserErrorProvider,
nodeLocationTracking: "none",
traceInitPerf: false,
skipValidations: false
});
export var DEFAULT_RULE_CONFIG = Object.freeze({
recoveryValueFunc: function () { return undefined; },
resyncEnabled: true
});
export var ParserDefinitionErrorType;
(function (ParserDefinitionErrorType) {
ParserDefinitionErrorType[ParserDefinitionErrorType["INVALID_RULE_NAME"] = 0] = "INVALID_RULE_NAME";
ParserDefinitionErrorType[ParserDefinitionErrorType["DUPLICATE_RULE_NAME"] = 1] = "DUPLICATE_RULE_NAME";
ParserDefinitionErrorType[ParserDefinitionErrorType["INVALID_RULE_OVERRIDE"] = 2] = "INVALID_RULE_OVERRIDE";
ParserDefinitionErrorType[ParserDefinitionErrorType["DUPLICATE_PRODUCTIONS"] = 3] = "DUPLICATE_PRODUCTIONS";
ParserDefinitionErrorType[ParserDefinitionErrorType["UNRESOLVED_SUBRULE_REF"] = 4] = "UNRESOLVED_SUBRULE_REF";
ParserDefinitionErrorType[ParserDefinitionErrorType["LEFT_RECURSION"] = 5] = "LEFT_RECURSION";
ParserDefinitionErrorType[ParserDefinitionErrorType["NONE_LAST_EMPTY_ALT"] = 6] = "NONE_LAST_EMPTY_ALT";
ParserDefinitionErrorType[ParserDefinitionErrorType["AMBIGUOUS_ALTS"] = 7] = "AMBIGUOUS_ALTS";
ParserDefinitionErrorType[ParserDefinitionErrorType["CONFLICT_TOKENS_RULES_NAMESPACE"] = 8] = "CONFLICT_TOKENS_RULES_NAMESPACE";
ParserDefinitionErrorType[ParserDefinitionErrorType["INVALID_TOKEN_NAME"] = 9] = "INVALID_TOKEN_NAME";
ParserDefinitionErrorType[ParserDefinitionErrorType["NO_NON_EMPTY_LOOKAHEAD"] = 10] = "NO_NON_EMPTY_LOOKAHEAD";
ParserDefinitionErrorType[ParserDefinitionErrorType["AMBIGUOUS_PREFIX_ALTS"] = 11] = "AMBIGUOUS_PREFIX_ALTS";
ParserDefinitionErrorType[ParserDefinitionErrorType["TOO_MANY_ALTS"] = 12] = "TOO_MANY_ALTS";
})(ParserDefinitionErrorType || (ParserDefinitionErrorType = {}));
export function EMPTY_ALT(value) {
if (value === void 0) { value = undefined; }
return function () {
return value;
};
}
var Parser = /** @class */ (function () {
function Parser(tokenVocabulary, config) {
this.definitionErrors = [];
this.selfAnalysisDone = false;
var that = this;
that.initErrorHandler(config);
that.initLexerAdapter();
that.initLooksAhead(config);
that.initRecognizerEngine(tokenVocabulary, config);
that.initRecoverable(config);
that.initTreeBuilder(config);
that.initContentAssist();
that.initGastRecorder(config);
that.initPerformanceTracer(config);
if (has(config, "ignoredIssues")) {
throw new Error("The <ignoredIssues> IParserConfig property has been deprecated.\n\t" +
"Please use the <IGNORE_AMBIGUITIES> flag on the relevant DSL method instead.\n\t" +
"See: https://sap.github.io/chevrotain/docs/guide/resolving_grammar_errors.html#IGNORING_AMBIGUITIES\n\t" +
"For further details.");
}
this.skipValidations = has(config, "skipValidations")
? config.skipValidations
: DEFAULT_PARSER_CONFIG.skipValidations;
}
/**
* @deprecated use the **instance** method with the same name instead
*/
Parser.performSelfAnalysis = function (parserInstance) {
throw Error("The **static** `performSelfAnalysis` method has been deprecated." +
"\t\nUse the **instance** method with the same name instead.");
};
Parser.prototype.performSelfAnalysis = function () {
var _this = this;
this.TRACE_INIT("performSelfAnalysis", function () {
var defErrorsMsgs;
_this.selfAnalysisDone = true;
var className = _this.className;
_this.TRACE_INIT("toFastProps", function () {
// Without this voodoo magic the parser would be x3-x4 slower
// It seems it is better to invoke `toFastProperties` **before**
// Any manipulations of the `this` object done during the recording phase.
toFastProperties(_this);
});
_this.TRACE_INIT("Grammar Recording", function () {
try {
_this.enableRecording();
// Building the GAST
forEach(_this.definedRulesNames, function (currRuleName) {
var wrappedRule = _this[currRuleName];
var originalGrammarAction = wrappedRule["originalGrammarAction"];
var recordedRuleGast = undefined;
_this.TRACE_INIT(currRuleName + " Rule", function () {
recordedRuleGast = _this.topLevelRuleRecord(currRuleName, originalGrammarAction);
});
_this.gastProductionsCache[currRuleName] = recordedRuleGast;
});
}
finally {
_this.disableRecording();
}
});
var resolverErrors = [];
_this.TRACE_INIT("Grammar Resolving", function () {
resolverErrors = resolveGrammar({
rules: values(_this.gastProductionsCache)
});
_this.definitionErrors.push.apply(_this.definitionErrors, resolverErrors); // mutability for the win?
});
_this.TRACE_INIT("Grammar Validations", function () {
// only perform additional grammar validations IFF no resolving errors have occurred.
// as unresolved grammar may lead to unhandled runtime exceptions in the follow up validations.
if (isEmpty(resolverErrors) && _this.skipValidations === false) {
var validationErrors = validateGrammar({
rules: values(_this.gastProductionsCache),
maxLookahead: _this.maxLookahead,
tokenTypes: values(_this.tokensMap),
errMsgProvider: defaultGrammarValidatorErrorProvider,
grammarName: className
});
_this.definitionErrors.push.apply(_this.definitionErrors, validationErrors); // mutability for the win?
}
});
// this analysis may fail if the grammar is not perfectly valid
if (isEmpty(_this.definitionErrors)) {
// The results of these computations are not needed unless error recovery is enabled.
if (_this.recoveryEnabled) {
_this.TRACE_INIT("computeAllProdsFollows", function () {
var allFollows = computeAllProdsFollows(values(_this.gastProductionsCache));
_this.resyncFollows = allFollows;
});
}
_this.TRACE_INIT("ComputeLookaheadFunctions", function () {
_this.preComputeLookaheadFunctions(values(_this.gastProductionsCache));
});
}
if (!Parser.DEFER_DEFINITION_ERRORS_HANDLING &&
!isEmpty(_this.definitionErrors)) {
defErrorsMsgs = map(_this.definitionErrors, function (defError) { return defError.message; });
throw new Error("Parser Definition Errors detected:\n " + defErrorsMsgs.join("\n-------------------------------\n"));
}
});
};
// Set this flag to true if you don't want the Parser to throw error when problems in it's definition are detected.
// (normally during the parser's constructor).
// This is a design time flag, it will not affect the runtime error handling of the parser, just design time errors,
// for example: duplicate rule names, referencing an unresolved subrule, ect...
// This flag should not be enabled during normal usage, it is used in special situations, for example when
// needing to display the parser definition errors in some GUI(online playground).
Parser.DEFER_DEFINITION_ERRORS_HANDLING = false;
return Parser;
}());
export { Parser };
applyMixins(Parser, [
Recoverable,
LooksAhead,
TreeBuilder,
LexerAdapter,
RecognizerEngine,
RecognizerApi,
ErrorHandler,
ContentAssist,
GastRecorder,
PerformanceTracer
]);
var CstParser = /** @class */ (function (_super) {
__extends(CstParser, _super);
function CstParser(tokenVocabulary, config) {
if (config === void 0) { config = DEFAULT_PARSER_CONFIG; }
var _this = this;
var configClone = cloneObj(config);
configClone.outputCst = true;
_this = _super.call(this, tokenVocabulary, configClone) || this;
return _this;
}
return CstParser;
}(Parser));
export { CstParser };
var EmbeddedActionsParser = /** @class */ (function (_super) {
__extends(EmbeddedActionsParser, _super);
function EmbeddedActionsParser(tokenVocabulary, config) {
if (config === void 0) { config = DEFAULT_PARSER_CONFIG; }
var _this = this;
var configClone = cloneObj(config);
configClone.outputCst = false;
_this = _super.call(this, tokenVocabulary, configClone) || this;
return _this;
}
return EmbeddedActionsParser;
}(Parser));
export { EmbeddedActionsParser };
//# sourceMappingURL=parser.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,26 @@
import { NextAfterTokenWalker, nextPossibleTokensAfter } from "../../grammar/interpreter";
import { first, isUndefined } from "../../../utils/utils";
var ContentAssist = /** @class */ (function () {
function ContentAssist() {
}
ContentAssist.prototype.initContentAssist = function () { };
ContentAssist.prototype.computeContentAssist = function (startRuleName, precedingInput) {
var startRuleGast = this.gastProductionsCache[startRuleName];
if (isUndefined(startRuleGast)) {
throw Error("Rule ->" + startRuleName + "<- does not exist in this grammar.");
}
return nextPossibleTokensAfter([startRuleGast], precedingInput, this.tokenMatcher, this.maxLookahead);
};
// TODO: should this be a member method or a utility? it does not have any state or usage of 'this'...
// TODO: should this be more explicitly part of the public API?
ContentAssist.prototype.getNextPossibleTokenTypes = function (grammarPath) {
var topRuleName = first(grammarPath.ruleStack);
var gastProductions = this.getGAstProductions();
var topProduction = gastProductions[topRuleName];
var nextPossibleTokenTypes = new NextAfterTokenWalker(topProduction, grammarPath).startWalking();
return nextPossibleTokenTypes;
};
return ContentAssist;
}());
export { ContentAssist };
//# sourceMappingURL=context_assist.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"context_assist.js","sourceRoot":"","sources":["../../../../../src/parse/parser/traits/context_assist.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACxB,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAGzD;IAAA;IAqCA,CAAC;IApCC,yCAAiB,GAAjB,cAAqB,CAAC;IAEf,4CAAoB,GAA3B,UAEE,aAAqB,EACrB,cAAwB;QAExB,IAAI,aAAa,GAAG,IAAI,CAAC,oBAAoB,CAAC,aAAa,CAAC,CAAA;QAE5D,IAAI,WAAW,CAAC,aAAa,CAAC,EAAE;YAC9B,MAAM,KAAK,CAAC,YAAU,aAAa,uCAAoC,CAAC,CAAA;SACzE;QAED,OAAO,uBAAuB,CAC5B,CAAC,aAAa,CAAC,EACf,cAAc,EACd,IAAI,CAAC,YAAY,EACjB,IAAI,CAAC,YAAY,CAClB,CAAA;IACH,CAAC;IAED,sGAAsG;IACtG,+DAA+D;IACxD,iDAAyB,GAAhC,UAEE,WAA8B;QAE9B,IAAI,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,CAAA;QAC9C,IAAI,eAAe,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAA;QAC/C,IAAI,aAAa,GAAG,eAAe,CAAC,WAAW,CAAC,CAAA;QAChD,IAAI,sBAAsB,GAAG,IAAI,oBAAoB,CACnD,aAAa,EACb,WAAW,CACZ,CAAC,YAAY,EAAE,CAAA;QAChB,OAAO,sBAAsB,CAAA;IAC/B,CAAC;IACH,oBAAC;AAAD,CAAC,AArCD,IAqCC"}

View file

@ -0,0 +1,82 @@
import { EarlyExitException, isRecognitionException, NoViableAltException } from "../../exceptions_public";
import { cloneArr, has } from "../../../utils/utils";
import { getLookaheadPathsForOptionalProd, getLookaheadPathsForOr } from "../../grammar/lookahead";
import { DEFAULT_PARSER_CONFIG } from "../parser";
/**
* Trait responsible for runtime parsing errors.
*/
var ErrorHandler = /** @class */ (function () {
function ErrorHandler() {
}
ErrorHandler.prototype.initErrorHandler = function (config) {
this._errors = [];
this.errorMessageProvider = has(config, "errorMessageProvider")
? config.errorMessageProvider
: DEFAULT_PARSER_CONFIG.errorMessageProvider;
};
ErrorHandler.prototype.SAVE_ERROR = function (error) {
if (isRecognitionException(error)) {
error.context = {
ruleStack: this.getHumanReadableRuleStack(),
ruleOccurrenceStack: cloneArr(this.RULE_OCCURRENCE_STACK)
};
this._errors.push(error);
return error;
}
else {
throw Error("Trying to save an Error which is not a RecognitionException");
}
};
Object.defineProperty(ErrorHandler.prototype, "errors", {
get: function () {
return cloneArr(this._errors);
},
set: function (newErrors) {
this._errors = newErrors;
},
enumerable: false,
configurable: true
});
// TODO: consider caching the error message computed information
ErrorHandler.prototype.raiseEarlyExitException = function (occurrence, prodType, userDefinedErrMsg) {
var ruleName = this.getCurrRuleFullName();
var ruleGrammar = this.getGAstProductions()[ruleName];
var lookAheadPathsPerAlternative = getLookaheadPathsForOptionalProd(occurrence, ruleGrammar, prodType, this.maxLookahead);
var insideProdPaths = lookAheadPathsPerAlternative[0];
var actualTokens = [];
for (var i = 1; i <= this.maxLookahead; i++) {
actualTokens.push(this.LA(i));
}
var msg = this.errorMessageProvider.buildEarlyExitMessage({
expectedIterationPaths: insideProdPaths,
actual: actualTokens,
previous: this.LA(0),
customUserDescription: userDefinedErrMsg,
ruleName: ruleName
});
throw this.SAVE_ERROR(new EarlyExitException(msg, this.LA(1), this.LA(0)));
};
// TODO: consider caching the error message computed information
ErrorHandler.prototype.raiseNoAltException = function (occurrence, errMsgTypes) {
var ruleName = this.getCurrRuleFullName();
var ruleGrammar = this.getGAstProductions()[ruleName];
// TODO: getLookaheadPathsForOr can be slow for large enough maxLookahead and certain grammars, consider caching ?
var lookAheadPathsPerAlternative = getLookaheadPathsForOr(occurrence, ruleGrammar, this.maxLookahead);
var actualTokens = [];
for (var i = 1; i <= this.maxLookahead; i++) {
actualTokens.push(this.LA(i));
}
var previousToken = this.LA(0);
var errMsg = this.errorMessageProvider.buildNoViableAltMessage({
expectedPathsPerAlt: lookAheadPathsPerAlternative,
actual: actualTokens,
previous: previousToken,
customUserDescription: errMsgTypes,
ruleName: this.getCurrRuleFullName()
});
throw this.SAVE_ERROR(new NoViableAltException(errMsg, this.LA(1), previousToken));
};
return ErrorHandler;
}());
export { ErrorHandler };
//# sourceMappingURL=error_handler.js.map

View file

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

View file

@ -0,0 +1,302 @@
import { forEach, has, isArray, isFunction, peek, some } from "../../../utils/utils";
import { Alternation, Alternative, NonTerminal, Option, Repetition, RepetitionMandatory, RepetitionMandatoryWithSeparator, RepetitionWithSeparator, Rule, Terminal } from "../../grammar/gast/gast_public";
import { Lexer } from "../../../scan/lexer_public";
import { augmentTokenTypes, hasShortKeyProperty } from "../../../scan/tokens";
import { createToken, createTokenInstance } from "../../../scan/tokens_public";
import { END_OF_FILE } from "../parser";
import { BITS_FOR_OCCURRENCE_IDX } from "../../grammar/keys";
var RECORDING_NULL_OBJECT = {
description: "This Object indicates the Parser is during Recording Phase"
};
Object.freeze(RECORDING_NULL_OBJECT);
var HANDLE_SEPARATOR = true;
var MAX_METHOD_IDX = Math.pow(2, BITS_FOR_OCCURRENCE_IDX) - 1;
var RFT = createToken({ name: "RECORDING_PHASE_TOKEN", pattern: Lexer.NA });
augmentTokenTypes([RFT]);
var RECORDING_PHASE_TOKEN = createTokenInstance(RFT, "This IToken indicates the Parser is in Recording Phase\n\t" +
"" +
"See: https://sap.github.io/chevrotain/docs/guide/internals.html#grammar-recording for details",
// Using "-1" instead of NaN (as in EOF) because an actual number is less likely to
// cause errors if the output of LA or CONSUME would be (incorrectly) used during the recording phase.
-1, -1, -1, -1, -1, -1);
Object.freeze(RECORDING_PHASE_TOKEN);
var RECORDING_PHASE_CSTNODE = {
name: "This CSTNode indicates the Parser is in Recording Phase\n\t" +
"See: https://sap.github.io/chevrotain/docs/guide/internals.html#grammar-recording for details",
children: {}
};
/**
* This trait handles the creation of the GAST structure for Chevrotain Grammars
*/
var GastRecorder = /** @class */ (function () {
function GastRecorder() {
}
GastRecorder.prototype.initGastRecorder = function (config) {
this.recordingProdStack = [];
this.RECORDING_PHASE = false;
};
GastRecorder.prototype.enableRecording = function () {
var _this = this;
this.RECORDING_PHASE = true;
this.TRACE_INIT("Enable Recording", function () {
var _loop_1 = function (i) {
var idx = i > 0 ? i : "";
_this["CONSUME" + idx] = function (arg1, arg2) {
return this.consumeInternalRecord(arg1, i, arg2);
};
_this["SUBRULE" + idx] = function (arg1, arg2) {
return this.subruleInternalRecord(arg1, i, arg2);
};
_this["OPTION" + idx] = function (arg1) {
return this.optionInternalRecord(arg1, i);
};
_this["OR" + idx] = function (arg1) {
return this.orInternalRecord(arg1, i);
};
_this["MANY" + idx] = function (arg1) {
this.manyInternalRecord(i, arg1);
};
_this["MANY_SEP" + idx] = function (arg1) {
this.manySepFirstInternalRecord(i, arg1);
};
_this["AT_LEAST_ONE" + idx] = function (arg1) {
this.atLeastOneInternalRecord(i, arg1);
};
_this["AT_LEAST_ONE_SEP" + idx] = function (arg1) {
this.atLeastOneSepFirstInternalRecord(i, arg1);
};
};
/**
* Warning Dark Voodoo Magic upcoming!
* We are "replacing" the public parsing DSL methods API
* With **new** alternative implementations on the Parser **instance**
*
* So far this is the only way I've found to avoid performance regressions during parsing time.
* - Approx 30% performance regression was measured on Chrome 75 Canary when attempting to replace the "internal"
* implementations directly instead.
*/
for (var i = 0; i < 10; i++) {
_loop_1(i);
}
// DSL methods with the idx(suffix) as an argument
_this["consume"] = function (idx, arg1, arg2) {
return this.consumeInternalRecord(arg1, idx, arg2);
};
_this["subrule"] = function (idx, arg1, arg2) {
return this.subruleInternalRecord(arg1, idx, arg2);
};
_this["option"] = function (idx, arg1) {
return this.optionInternalRecord(arg1, idx);
};
_this["or"] = function (idx, arg1) {
return this.orInternalRecord(arg1, idx);
};
_this["many"] = function (idx, arg1) {
this.manyInternalRecord(idx, arg1);
};
_this["atLeastOne"] = function (idx, arg1) {
this.atLeastOneInternalRecord(idx, arg1);
};
_this.ACTION = _this.ACTION_RECORD;
_this.BACKTRACK = _this.BACKTRACK_RECORD;
_this.LA = _this.LA_RECORD;
});
};
GastRecorder.prototype.disableRecording = function () {
var _this = this;
this.RECORDING_PHASE = false;
// By deleting these **instance** properties, any future invocation
// will be deferred to the original methods on the **prototype** object
// This seems to get rid of any incorrect optimizations that V8 may
// do during the recording phase.
this.TRACE_INIT("Deleting Recording methods", function () {
for (var i = 0; i < 10; i++) {
var idx = i > 0 ? i : "";
delete _this["CONSUME" + idx];
delete _this["SUBRULE" + idx];
delete _this["OPTION" + idx];
delete _this["OR" + idx];
delete _this["MANY" + idx];
delete _this["MANY_SEP" + idx];
delete _this["AT_LEAST_ONE" + idx];
delete _this["AT_LEAST_ONE_SEP" + idx];
}
delete _this["consume"];
delete _this["subrule"];
delete _this["option"];
delete _this["or"];
delete _this["many"];
delete _this["atLeastOne"];
delete _this.ACTION;
delete _this.BACKTRACK;
delete _this.LA;
});
};
// TODO: is there any way to use this method to check no
// Parser methods are called inside an ACTION?
// Maybe try/catch/finally on ACTIONS while disabling the recorders state changes?
GastRecorder.prototype.ACTION_RECORD = function (impl) {
// NO-OP during recording
return;
};
// Executing backtracking logic will break our recording logic assumptions
GastRecorder.prototype.BACKTRACK_RECORD = function (grammarRule, args) {
return function () { return true; };
};
// LA is part of the official API and may be used for custom lookahead logic
// by end users who may forget to wrap it in ACTION or inside a GATE
GastRecorder.prototype.LA_RECORD = function (howMuch) {
// We cannot use the RECORD_PHASE_TOKEN here because someone may depend
// On LA return EOF at the end of the input so an infinite loop may occur.
return END_OF_FILE;
};
GastRecorder.prototype.topLevelRuleRecord = function (name, def) {
try {
var newTopLevelRule = new Rule({ definition: [], name: name });
newTopLevelRule.name = name;
this.recordingProdStack.push(newTopLevelRule);
def.call(this);
this.recordingProdStack.pop();
return newTopLevelRule;
}
catch (originalError) {
if (originalError.KNOWN_RECORDER_ERROR !== true) {
try {
originalError.message =
originalError.message +
'\n\t This error was thrown during the "grammar recording phase" For more info see:\n\t' +
"https://sap.github.io/chevrotain/docs/guide/internals.html#grammar-recording";
}
catch (mutabilityError) {
// We may not be able to modify the original error object
throw originalError;
}
}
throw originalError;
}
};
// Implementation of parsing DSL
GastRecorder.prototype.optionInternalRecord = function (actionORMethodDef, occurrence) {
return recordProd.call(this, Option, actionORMethodDef, occurrence);
};
GastRecorder.prototype.atLeastOneInternalRecord = function (occurrence, actionORMethodDef) {
recordProd.call(this, RepetitionMandatory, actionORMethodDef, occurrence);
};
GastRecorder.prototype.atLeastOneSepFirstInternalRecord = function (occurrence, options) {
recordProd.call(this, RepetitionMandatoryWithSeparator, options, occurrence, HANDLE_SEPARATOR);
};
GastRecorder.prototype.manyInternalRecord = function (occurrence, actionORMethodDef) {
recordProd.call(this, Repetition, actionORMethodDef, occurrence);
};
GastRecorder.prototype.manySepFirstInternalRecord = function (occurrence, options) {
recordProd.call(this, RepetitionWithSeparator, options, occurrence, HANDLE_SEPARATOR);
};
GastRecorder.prototype.orInternalRecord = function (altsOrOpts, occurrence) {
return recordOrProd.call(this, altsOrOpts, occurrence);
};
GastRecorder.prototype.subruleInternalRecord = function (ruleToCall, occurrence, options) {
assertMethodIdxIsValid(occurrence);
if (!ruleToCall || has(ruleToCall, "ruleName") === false) {
var error = new Error("<SUBRULE" + getIdxSuffix(occurrence) + "> argument is invalid" +
(" expecting a Parser method reference but got: <" + JSON.stringify(ruleToCall) + ">") +
("\n inside top level rule: <" + this.recordingProdStack[0].name + ">"));
error.KNOWN_RECORDER_ERROR = true;
throw error;
}
var prevProd = peek(this.recordingProdStack);
var ruleName = ruleToCall["ruleName"];
var newNoneTerminal = new NonTerminal({
idx: occurrence,
nonTerminalName: ruleName,
// The resolving of the `referencedRule` property will be done once all the Rule's GASTs have been created
referencedRule: undefined
});
prevProd.definition.push(newNoneTerminal);
return this.outputCst ? RECORDING_PHASE_CSTNODE : RECORDING_NULL_OBJECT;
};
GastRecorder.prototype.consumeInternalRecord = function (tokType, occurrence, options) {
assertMethodIdxIsValid(occurrence);
if (!hasShortKeyProperty(tokType)) {
var error = new Error("<CONSUME" + getIdxSuffix(occurrence) + "> argument is invalid" +
(" expecting a TokenType reference but got: <" + JSON.stringify(tokType) + ">") +
("\n inside top level rule: <" + this.recordingProdStack[0].name + ">"));
error.KNOWN_RECORDER_ERROR = true;
throw error;
}
var prevProd = peek(this.recordingProdStack);
var newNoneTerminal = new Terminal({
idx: occurrence,
terminalType: tokType
});
prevProd.definition.push(newNoneTerminal);
return RECORDING_PHASE_TOKEN;
};
return GastRecorder;
}());
export { GastRecorder };
function recordProd(prodConstructor, mainProdArg, occurrence, handleSep) {
if (handleSep === void 0) { handleSep = false; }
assertMethodIdxIsValid(occurrence);
var prevProd = peek(this.recordingProdStack);
var grammarAction = isFunction(mainProdArg) ? mainProdArg : mainProdArg.DEF;
var newProd = new prodConstructor({ definition: [], idx: occurrence });
if (handleSep) {
newProd.separator = mainProdArg.SEP;
}
if (has(mainProdArg, "MAX_LOOKAHEAD")) {
newProd.maxLookahead = mainProdArg.MAX_LOOKAHEAD;
}
this.recordingProdStack.push(newProd);
grammarAction.call(this);
prevProd.definition.push(newProd);
this.recordingProdStack.pop();
return RECORDING_NULL_OBJECT;
}
function recordOrProd(mainProdArg, occurrence) {
var _this = this;
assertMethodIdxIsValid(occurrence);
var prevProd = peek(this.recordingProdStack);
// Only an array of alternatives
var hasOptions = isArray(mainProdArg) === false;
var alts = hasOptions === false ? mainProdArg : mainProdArg.DEF;
var newOrProd = new Alternation({
definition: [],
idx: occurrence,
ignoreAmbiguities: hasOptions && mainProdArg.IGNORE_AMBIGUITIES === true
});
if (has(mainProdArg, "MAX_LOOKAHEAD")) {
newOrProd.maxLookahead = mainProdArg.MAX_LOOKAHEAD;
}
var hasPredicates = some(alts, function (currAlt) { return isFunction(currAlt.GATE); });
newOrProd.hasPredicates = hasPredicates;
prevProd.definition.push(newOrProd);
forEach(alts, function (currAlt) {
var currAltFlat = new Alternative({ definition: [] });
newOrProd.definition.push(currAltFlat);
if (has(currAlt, "IGNORE_AMBIGUITIES")) {
currAltFlat.ignoreAmbiguities = currAlt.IGNORE_AMBIGUITIES;
}
// **implicit** ignoreAmbiguities due to usage of gate
else if (has(currAlt, "GATE")) {
currAltFlat.ignoreAmbiguities = true;
}
_this.recordingProdStack.push(currAltFlat);
currAlt.ALT.call(_this);
_this.recordingProdStack.pop();
});
return RECORDING_NULL_OBJECT;
}
function getIdxSuffix(idx) {
return idx === 0 ? "" : "" + idx;
}
function assertMethodIdxIsValid(idx) {
if (idx < 0 || idx > MAX_METHOD_IDX) {
var error = new Error(
// The stack trace will contain all the needed details
"Invalid DSL Method idx value: <" + idx + ">\n\t" +
("Idx value must be a none negative value smaller than " + (MAX_METHOD_IDX + 1)));
error.KNOWN_RECORDER_ERROR = true;
throw error;
}
}
//# sourceMappingURL=gast_recorder.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,78 @@
import { END_OF_FILE } from "../parser";
/**
* Trait responsible abstracting over the interaction with Lexer output (Token vector).
*
* This could be generalized to support other kinds of lexers, e.g.
* - Just in Time Lexing / Lexer-Less parsing.
* - Streaming Lexer.
*/
var LexerAdapter = /** @class */ (function () {
function LexerAdapter() {
}
LexerAdapter.prototype.initLexerAdapter = function () {
this.tokVector = [];
this.tokVectorLength = 0;
this.currIdx = -1;
};
Object.defineProperty(LexerAdapter.prototype, "input", {
get: function () {
return this.tokVector;
},
set: function (newInput) {
// @ts-ignore - `this parameter` not supported in setters/getters
// - https://www.typescriptlang.org/docs/handbook/functions.html#this-parameters
if (this.selfAnalysisDone !== true) {
throw Error("Missing <performSelfAnalysis> invocation at the end of the Parser's constructor.");
}
// @ts-ignore - `this parameter` not supported in setters/getters
// - https://www.typescriptlang.org/docs/handbook/functions.html#this-parameters
this.reset();
this.tokVector = newInput;
this.tokVectorLength = newInput.length;
},
enumerable: false,
configurable: true
});
// skips a token and returns the next token
LexerAdapter.prototype.SKIP_TOKEN = function () {
if (this.currIdx <= this.tokVector.length - 2) {
this.consumeToken();
return this.LA(1);
}
else {
return END_OF_FILE;
}
};
// Lexer (accessing Token vector) related methods which can be overridden to implement lazy lexers
// or lexers dependent on parser context.
LexerAdapter.prototype.LA = function (howMuch) {
var soughtIdx = this.currIdx + howMuch;
if (soughtIdx < 0 || this.tokVectorLength <= soughtIdx) {
return END_OF_FILE;
}
else {
return this.tokVector[soughtIdx];
}
};
LexerAdapter.prototype.consumeToken = function () {
this.currIdx++;
};
LexerAdapter.prototype.exportLexerState = function () {
return this.currIdx;
};
LexerAdapter.prototype.importLexerState = function (newState) {
this.currIdx = newState;
};
LexerAdapter.prototype.resetLexerState = function () {
this.currIdx = -1;
};
LexerAdapter.prototype.moveToTerminatedState = function () {
this.currIdx = this.tokVector.length - 1;
};
LexerAdapter.prototype.getLexerPosition = function () {
return this.exportLexerState();
};
return LexerAdapter;
}());
export { LexerAdapter };
//# sourceMappingURL=lexer_adapter.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"lexer_adapter.js","sourceRoot":"","sources":["../../../../../src/parse/parser/traits/lexer_adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAIvC;;;;;;GAMG;AACH;IAAA;IA0EA,CAAC;IArEC,uCAAgB,GAAhB;QACE,IAAI,CAAC,SAAS,GAAG,EAAE,CAAA;QACnB,IAAI,CAAC,eAAe,GAAG,CAAC,CAAA;QACxB,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAA;IACnB,CAAC;IAED,sBAAI,+BAAK;aAeT;YACE,OAAO,IAAI,CAAC,SAAS,CAAA;QACvB,CAAC;aAjBD,UAAU,QAAkB;YAC1B,iEAAiE;YACjE,kFAAkF;YAClF,IAAI,IAAI,CAAC,gBAAgB,KAAK,IAAI,EAAE;gBAClC,MAAM,KAAK,CACT,kFAAkF,CACnF,CAAA;aACF;YACD,iEAAiE;YACjE,kFAAkF;YAClF,IAAI,CAAC,KAAK,EAAE,CAAA;YACZ,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAA;YACzB,IAAI,CAAC,eAAe,GAAG,QAAQ,CAAC,MAAM,CAAA;QACxC,CAAC;;;OAAA;IAMD,2CAA2C;IAC3C,iCAAU,GAAV;QACE,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;YAC7C,IAAI,CAAC,YAAY,EAAE,CAAA;YACnB,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;SAClB;aAAM;YACL,OAAO,WAAW,CAAA;SACnB;IACH,CAAC;IAED,kGAAkG;IAClG,yCAAyC;IACzC,yBAAE,GAAF,UAAwB,OAAe;QACrC,IAAM,SAAS,GAAG,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QACxC,IAAI,SAAS,GAAG,CAAC,IAAI,IAAI,CAAC,eAAe,IAAI,SAAS,EAAE;YACtD,OAAO,WAAW,CAAA;SACnB;aAAM;YACL,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAA;SACjC;IACH,CAAC;IAED,mCAAY,GAAZ;QACE,IAAI,CAAC,OAAO,EAAE,CAAA;IAChB,CAAC;IAED,uCAAgB,GAAhB;QACE,OAAO,IAAI,CAAC,OAAO,CAAA;IACrB,CAAC;IAED,uCAAgB,GAAhB,UAAsC,QAAgB;QACpD,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAA;IACzB,CAAC;IAED,sCAAe,GAAf;QACE,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAA;IACnB,CAAC;IAED,4CAAqB,GAArB;QACE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAA;IAC1C,CAAC;IAED,uCAAgB,GAAhB;QACE,OAAO,IAAI,CAAC,gBAAgB,EAAE,CAAA;IAChC,CAAC;IACH,mBAAC;AAAD,CAAC,AA1ED,IA0EC"}

View file

@ -0,0 +1,106 @@
import { buildAlternativesLookAheadFunc, buildLookaheadFuncForOptionalProd, buildLookaheadFuncForOr, buildSingleAlternativeLookaheadFunction, PROD_TYPE } from "../../grammar/lookahead";
import { forEach, has, isES2015MapSupported } from "../../../utils/utils";
import { DEFAULT_PARSER_CONFIG } from "../parser";
import { AT_LEAST_ONE_IDX, AT_LEAST_ONE_SEP_IDX, getKeyForAutomaticLookahead, MANY_IDX, MANY_SEP_IDX, OPTION_IDX, OR_IDX } from "../../grammar/keys";
import { collectMethods, getProductionDslName } from "../../grammar/gast/gast";
/**
* Trait responsible for the lookahead related utilities and optimizations.
*/
var LooksAhead = /** @class */ (function () {
function LooksAhead() {
}
LooksAhead.prototype.initLooksAhead = function (config) {
this.dynamicTokensEnabled = has(config, "dynamicTokensEnabled")
? config.dynamicTokensEnabled
: DEFAULT_PARSER_CONFIG.dynamicTokensEnabled;
this.maxLookahead = has(config, "maxLookahead")
? config.maxLookahead
: DEFAULT_PARSER_CONFIG.maxLookahead;
/* istanbul ignore next - Using plain array as dictionary will be tested on older node.js versions and IE11 */
this.lookAheadFuncsCache = isES2015MapSupported() ? new Map() : [];
// Performance optimization on newer engines that support ES6 Map
// For larger Maps this is slightly faster than using a plain object (array in our case).
/* istanbul ignore else - The else branch will be tested on older node.js versions and IE11 */
if (isES2015MapSupported()) {
this.getLaFuncFromCache = this.getLaFuncFromMap;
this.setLaFuncCache = this.setLaFuncCacheUsingMap;
}
else {
this.getLaFuncFromCache = this.getLaFuncFromObj;
this.setLaFuncCache = this.setLaFuncUsingObj;
}
};
LooksAhead.prototype.preComputeLookaheadFunctions = function (rules) {
var _this = this;
forEach(rules, function (currRule) {
_this.TRACE_INIT(currRule.name + " Rule Lookahead", function () {
var _a = collectMethods(currRule), alternation = _a.alternation, repetition = _a.repetition, option = _a.option, repetitionMandatory = _a.repetitionMandatory, repetitionMandatoryWithSeparator = _a.repetitionMandatoryWithSeparator, repetitionWithSeparator = _a.repetitionWithSeparator;
forEach(alternation, function (currProd) {
var prodIdx = currProd.idx === 0 ? "" : currProd.idx;
_this.TRACE_INIT("" + getProductionDslName(currProd) + prodIdx, function () {
var laFunc = buildLookaheadFuncForOr(currProd.idx, currRule, currProd.maxLookahead || _this.maxLookahead, currProd.hasPredicates, _this.dynamicTokensEnabled, _this.lookAheadBuilderForAlternatives);
var key = getKeyForAutomaticLookahead(_this.fullRuleNameToShort[currRule.name], OR_IDX, currProd.idx);
_this.setLaFuncCache(key, laFunc);
});
});
forEach(repetition, function (currProd) {
_this.computeLookaheadFunc(currRule, currProd.idx, MANY_IDX, PROD_TYPE.REPETITION, currProd.maxLookahead, getProductionDslName(currProd));
});
forEach(option, function (currProd) {
_this.computeLookaheadFunc(currRule, currProd.idx, OPTION_IDX, PROD_TYPE.OPTION, currProd.maxLookahead, getProductionDslName(currProd));
});
forEach(repetitionMandatory, function (currProd) {
_this.computeLookaheadFunc(currRule, currProd.idx, AT_LEAST_ONE_IDX, PROD_TYPE.REPETITION_MANDATORY, currProd.maxLookahead, getProductionDslName(currProd));
});
forEach(repetitionMandatoryWithSeparator, function (currProd) {
_this.computeLookaheadFunc(currRule, currProd.idx, AT_LEAST_ONE_SEP_IDX, PROD_TYPE.REPETITION_MANDATORY_WITH_SEPARATOR, currProd.maxLookahead, getProductionDslName(currProd));
});
forEach(repetitionWithSeparator, function (currProd) {
_this.computeLookaheadFunc(currRule, currProd.idx, MANY_SEP_IDX, PROD_TYPE.REPETITION_WITH_SEPARATOR, currProd.maxLookahead, getProductionDslName(currProd));
});
});
});
};
LooksAhead.prototype.computeLookaheadFunc = function (rule, prodOccurrence, prodKey, prodType, prodMaxLookahead, dslMethodName) {
var _this = this;
this.TRACE_INIT("" + dslMethodName + (prodOccurrence === 0 ? "" : prodOccurrence), function () {
var laFunc = buildLookaheadFuncForOptionalProd(prodOccurrence, rule, prodMaxLookahead || _this.maxLookahead, _this.dynamicTokensEnabled, prodType, _this.lookAheadBuilderForOptional);
var key = getKeyForAutomaticLookahead(_this.fullRuleNameToShort[rule.name], prodKey, prodOccurrence);
_this.setLaFuncCache(key, laFunc);
});
};
LooksAhead.prototype.lookAheadBuilderForOptional = function (alt, tokenMatcher, dynamicTokensEnabled) {
return buildSingleAlternativeLookaheadFunction(alt, tokenMatcher, dynamicTokensEnabled);
};
LooksAhead.prototype.lookAheadBuilderForAlternatives = function (alts, hasPredicates, tokenMatcher, dynamicTokensEnabled) {
return buildAlternativesLookAheadFunc(alts, hasPredicates, tokenMatcher, dynamicTokensEnabled);
};
// this actually returns a number, but it is always used as a string (object prop key)
LooksAhead.prototype.getKeyForAutomaticLookahead = function (dslMethodIdx, occurrence) {
var currRuleShortName = this.getLastExplicitRuleShortName();
return getKeyForAutomaticLookahead(currRuleShortName, dslMethodIdx, occurrence);
};
/* istanbul ignore next */
LooksAhead.prototype.getLaFuncFromCache = function (key) {
return undefined;
};
LooksAhead.prototype.getLaFuncFromMap = function (key) {
return this.lookAheadFuncsCache.get(key);
};
/* istanbul ignore next - Using plain array as dictionary will be tested on older node.js versions and IE11 */
LooksAhead.prototype.getLaFuncFromObj = function (key) {
return this.lookAheadFuncsCache[key];
};
/* istanbul ignore next */
LooksAhead.prototype.setLaFuncCache = function (key, value) { };
LooksAhead.prototype.setLaFuncCacheUsingMap = function (key, value) {
this.lookAheadFuncsCache.set(key, value);
};
/* istanbul ignore next - Using plain array as dictionary will be tested on older node.js versions and IE11 */
LooksAhead.prototype.setLaFuncUsingObj = function (key, value) {
this.lookAheadFuncsCache[key] = value;
};
return LooksAhead;
}());
export { LooksAhead };
//# sourceMappingURL=looksahead.js.map

View file

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

View file

@ -0,0 +1,4 @@
import { CstParser as CstParserConstructorImpel, EmbeddedActionsParser as EmbeddedActionsParserConstructorImpel } from "../parser";
export var CstParser = (CstParserConstructorImpel);
export var EmbeddedActionsParser = EmbeddedActionsParserConstructorImpel;
//# sourceMappingURL=parser_traits.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"parser_traits.js","sourceRoot":"","sources":["../../../../../src/parse/parser/traits/parser_traits.ts"],"names":[],"mappings":"AAOA,OAAO,EAEL,SAAS,IAAI,yBAAyB,EACtC,qBAAqB,IAAI,qCAAqC,EAC/D,MAAM,WAAW,CAAA;AAiClB,MAAM,CAAC,IAAM,SAAS,GAAqC,CACzD,yBAAyB,CAC1B,CAAA;AASD,MAAM,CAAC,IAAM,qBAAqB,GAEjC,qCAAqC,CAAA"}

View file

@ -0,0 +1,51 @@
import { has, timer } from "../../../utils/utils";
import { DEFAULT_PARSER_CONFIG } from "../parser";
/**
* Trait responsible for runtime parsing errors.
*/
var PerformanceTracer = /** @class */ (function () {
function PerformanceTracer() {
}
PerformanceTracer.prototype.initPerformanceTracer = function (config) {
if (has(config, "traceInitPerf")) {
var userTraceInitPerf = config.traceInitPerf;
var traceIsNumber = typeof userTraceInitPerf === "number";
this.traceInitMaxIdent = traceIsNumber
? userTraceInitPerf
: Infinity;
this.traceInitPerf = traceIsNumber
? userTraceInitPerf > 0
: userTraceInitPerf;
}
else {
this.traceInitMaxIdent = 0;
this.traceInitPerf = DEFAULT_PARSER_CONFIG.traceInitPerf;
}
this.traceInitIndent = -1;
};
PerformanceTracer.prototype.TRACE_INIT = function (phaseDesc, phaseImpl) {
// No need to optimize this using NOOP pattern because
// It is not called in a hot spot...
if (this.traceInitPerf === true) {
this.traceInitIndent++;
var indent = new Array(this.traceInitIndent + 1).join("\t");
if (this.traceInitIndent < this.traceInitMaxIdent) {
console.log(indent + "--> <" + phaseDesc + ">");
}
var _a = timer(phaseImpl), time = _a.time, value = _a.value;
/* istanbul ignore next - Difficult to reproduce specific performance behavior (>10ms) in tests */
var traceMethod = time > 10 ? console.warn : console.log;
if (this.traceInitIndent < this.traceInitMaxIdent) {
traceMethod(indent + "<-- <" + phaseDesc + "> time: " + time + "ms");
}
this.traceInitIndent--;
return value;
}
else {
return phaseImpl();
}
};
return PerformanceTracer;
}());
export { PerformanceTracer };
//# sourceMappingURL=perf_tracer.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"perf_tracer.js","sourceRoot":"","sources":["../../../../../src/parse/parser/traits/perf_tracer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAA;AAEjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAA;AAEjD;;GAEG;AACH;IAAA;IA4CA,CAAC;IAvCC,iDAAqB,GAArB,UAAsB,MAAqB;QACzC,IAAI,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,EAAE;YAChC,IAAM,iBAAiB,GAAG,MAAM,CAAC,aAAa,CAAA;YAC9C,IAAM,aAAa,GAAG,OAAO,iBAAiB,KAAK,QAAQ,CAAA;YAC3D,IAAI,CAAC,iBAAiB,GAAG,aAAa;gBACpC,CAAC,CAAS,iBAAiB;gBAC3B,CAAC,CAAC,QAAQ,CAAA;YACZ,IAAI,CAAC,aAAa,GAAG,aAAa;gBAChC,CAAC,CAAC,iBAAiB,GAAG,CAAC;gBACvB,CAAC,CAAC,iBAAiB,CAAA;SACtB;aAAM;YACL,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAA;YAC1B,IAAI,CAAC,aAAa,GAAG,qBAAqB,CAAC,aAAa,CAAA;SACzD;QAED,IAAI,CAAC,eAAe,GAAG,CAAC,CAAC,CAAA;IAC3B,CAAC;IAED,sCAAU,GAAV,UAAmC,SAAiB,EAAE,SAAkB;QACtE,sDAAsD;QACtD,oCAAoC;QACpC,IAAI,IAAI,CAAC,aAAa,KAAK,IAAI,EAAE;YAC/B,IAAI,CAAC,eAAe,EAAE,CAAA;YACtB,IAAM,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,eAAe,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAC7D,IAAI,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,iBAAiB,EAAE;gBACjD,OAAO,CAAC,GAAG,CAAI,MAAM,aAAQ,SAAS,MAAG,CAAC,CAAA;aAC3C;YACK,IAAA,KAAkB,KAAK,CAAC,SAAS,CAAC,EAAhC,IAAI,UAAA,EAAE,KAAK,WAAqB,CAAA;YACxC,kGAAkG;YAClG,IAAM,WAAW,GAAG,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAA;YAC1D,IAAI,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,iBAAiB,EAAE;gBACjD,WAAW,CAAI,MAAM,aAAQ,SAAS,gBAAW,IAAI,OAAI,CAAC,CAAA;aAC3D;YACD,IAAI,CAAC,eAAe,EAAE,CAAA;YACtB,OAAO,KAAK,CAAA;SACb;aAAM;YACL,OAAO,SAAS,EAAE,CAAA;SACnB;IACH,CAAC;IACH,wBAAC;AAAD,CAAC,AA5CD,IA4CC"}

View file

@ -0,0 +1,341 @@
import { contains, values } from "../../../utils/utils";
import { isRecognitionException } from "../../exceptions_public";
import { DEFAULT_RULE_CONFIG, ParserDefinitionErrorType } from "../parser";
import { defaultGrammarValidatorErrorProvider } from "../../errors_public";
import { validateRuleIsOverridden } from "../../grammar/checks";
import { serializeGrammar } from "../../grammar/gast/gast_public";
/**
* This trait is responsible for implementing the public API
* for defining Chevrotain parsers, i.e:
* - CONSUME
* - RULE
* - OPTION
* - ...
*/
var RecognizerApi = /** @class */ (function () {
function RecognizerApi() {
}
RecognizerApi.prototype.ACTION = function (impl) {
return impl.call(this);
};
RecognizerApi.prototype.consume = function (idx, tokType, options) {
return this.consumeInternal(tokType, idx, options);
};
RecognizerApi.prototype.subrule = function (idx, ruleToCall, options) {
return this.subruleInternal(ruleToCall, idx, options);
};
RecognizerApi.prototype.option = function (idx, actionORMethodDef) {
return this.optionInternal(actionORMethodDef, idx);
};
RecognizerApi.prototype.or = function (idx, altsOrOpts) {
return this.orInternal(altsOrOpts, idx);
};
RecognizerApi.prototype.many = function (idx, actionORMethodDef) {
return this.manyInternal(idx, actionORMethodDef);
};
RecognizerApi.prototype.atLeastOne = function (idx, actionORMethodDef) {
return this.atLeastOneInternal(idx, actionORMethodDef);
};
RecognizerApi.prototype.CONSUME = function (tokType, options) {
return this.consumeInternal(tokType, 0, options);
};
RecognizerApi.prototype.CONSUME1 = function (tokType, options) {
return this.consumeInternal(tokType, 1, options);
};
RecognizerApi.prototype.CONSUME2 = function (tokType, options) {
return this.consumeInternal(tokType, 2, options);
};
RecognizerApi.prototype.CONSUME3 = function (tokType, options) {
return this.consumeInternal(tokType, 3, options);
};
RecognizerApi.prototype.CONSUME4 = function (tokType, options) {
return this.consumeInternal(tokType, 4, options);
};
RecognizerApi.prototype.CONSUME5 = function (tokType, options) {
return this.consumeInternal(tokType, 5, options);
};
RecognizerApi.prototype.CONSUME6 = function (tokType, options) {
return this.consumeInternal(tokType, 6, options);
};
RecognizerApi.prototype.CONSUME7 = function (tokType, options) {
return this.consumeInternal(tokType, 7, options);
};
RecognizerApi.prototype.CONSUME8 = function (tokType, options) {
return this.consumeInternal(tokType, 8, options);
};
RecognizerApi.prototype.CONSUME9 = function (tokType, options) {
return this.consumeInternal(tokType, 9, options);
};
RecognizerApi.prototype.SUBRULE = function (ruleToCall, options) {
return this.subruleInternal(ruleToCall, 0, options);
};
RecognizerApi.prototype.SUBRULE1 = function (ruleToCall, options) {
return this.subruleInternal(ruleToCall, 1, options);
};
RecognizerApi.prototype.SUBRULE2 = function (ruleToCall, options) {
return this.subruleInternal(ruleToCall, 2, options);
};
RecognizerApi.prototype.SUBRULE3 = function (ruleToCall, options) {
return this.subruleInternal(ruleToCall, 3, options);
};
RecognizerApi.prototype.SUBRULE4 = function (ruleToCall, options) {
return this.subruleInternal(ruleToCall, 4, options);
};
RecognizerApi.prototype.SUBRULE5 = function (ruleToCall, options) {
return this.subruleInternal(ruleToCall, 5, options);
};
RecognizerApi.prototype.SUBRULE6 = function (ruleToCall, options) {
return this.subruleInternal(ruleToCall, 6, options);
};
RecognizerApi.prototype.SUBRULE7 = function (ruleToCall, options) {
return this.subruleInternal(ruleToCall, 7, options);
};
RecognizerApi.prototype.SUBRULE8 = function (ruleToCall, options) {
return this.subruleInternal(ruleToCall, 8, options);
};
RecognizerApi.prototype.SUBRULE9 = function (ruleToCall, options) {
return this.subruleInternal(ruleToCall, 9, options);
};
RecognizerApi.prototype.OPTION = function (actionORMethodDef) {
return this.optionInternal(actionORMethodDef, 0);
};
RecognizerApi.prototype.OPTION1 = function (actionORMethodDef) {
return this.optionInternal(actionORMethodDef, 1);
};
RecognizerApi.prototype.OPTION2 = function (actionORMethodDef) {
return this.optionInternal(actionORMethodDef, 2);
};
RecognizerApi.prototype.OPTION3 = function (actionORMethodDef) {
return this.optionInternal(actionORMethodDef, 3);
};
RecognizerApi.prototype.OPTION4 = function (actionORMethodDef) {
return this.optionInternal(actionORMethodDef, 4);
};
RecognizerApi.prototype.OPTION5 = function (actionORMethodDef) {
return this.optionInternal(actionORMethodDef, 5);
};
RecognizerApi.prototype.OPTION6 = function (actionORMethodDef) {
return this.optionInternal(actionORMethodDef, 6);
};
RecognizerApi.prototype.OPTION7 = function (actionORMethodDef) {
return this.optionInternal(actionORMethodDef, 7);
};
RecognizerApi.prototype.OPTION8 = function (actionORMethodDef) {
return this.optionInternal(actionORMethodDef, 8);
};
RecognizerApi.prototype.OPTION9 = function (actionORMethodDef) {
return this.optionInternal(actionORMethodDef, 9);
};
RecognizerApi.prototype.OR = function (altsOrOpts) {
return this.orInternal(altsOrOpts, 0);
};
RecognizerApi.prototype.OR1 = function (altsOrOpts) {
return this.orInternal(altsOrOpts, 1);
};
RecognizerApi.prototype.OR2 = function (altsOrOpts) {
return this.orInternal(altsOrOpts, 2);
};
RecognizerApi.prototype.OR3 = function (altsOrOpts) {
return this.orInternal(altsOrOpts, 3);
};
RecognizerApi.prototype.OR4 = function (altsOrOpts) {
return this.orInternal(altsOrOpts, 4);
};
RecognizerApi.prototype.OR5 = function (altsOrOpts) {
return this.orInternal(altsOrOpts, 5);
};
RecognizerApi.prototype.OR6 = function (altsOrOpts) {
return this.orInternal(altsOrOpts, 6);
};
RecognizerApi.prototype.OR7 = function (altsOrOpts) {
return this.orInternal(altsOrOpts, 7);
};
RecognizerApi.prototype.OR8 = function (altsOrOpts) {
return this.orInternal(altsOrOpts, 8);
};
RecognizerApi.prototype.OR9 = function (altsOrOpts) {
return this.orInternal(altsOrOpts, 9);
};
RecognizerApi.prototype.MANY = function (actionORMethodDef) {
this.manyInternal(0, actionORMethodDef);
};
RecognizerApi.prototype.MANY1 = function (actionORMethodDef) {
this.manyInternal(1, actionORMethodDef);
};
RecognizerApi.prototype.MANY2 = function (actionORMethodDef) {
this.manyInternal(2, actionORMethodDef);
};
RecognizerApi.prototype.MANY3 = function (actionORMethodDef) {
this.manyInternal(3, actionORMethodDef);
};
RecognizerApi.prototype.MANY4 = function (actionORMethodDef) {
this.manyInternal(4, actionORMethodDef);
};
RecognizerApi.prototype.MANY5 = function (actionORMethodDef) {
this.manyInternal(5, actionORMethodDef);
};
RecognizerApi.prototype.MANY6 = function (actionORMethodDef) {
this.manyInternal(6, actionORMethodDef);
};
RecognizerApi.prototype.MANY7 = function (actionORMethodDef) {
this.manyInternal(7, actionORMethodDef);
};
RecognizerApi.prototype.MANY8 = function (actionORMethodDef) {
this.manyInternal(8, actionORMethodDef);
};
RecognizerApi.prototype.MANY9 = function (actionORMethodDef) {
this.manyInternal(9, actionORMethodDef);
};
RecognizerApi.prototype.MANY_SEP = function (options) {
this.manySepFirstInternal(0, options);
};
RecognizerApi.prototype.MANY_SEP1 = function (options) {
this.manySepFirstInternal(1, options);
};
RecognizerApi.prototype.MANY_SEP2 = function (options) {
this.manySepFirstInternal(2, options);
};
RecognizerApi.prototype.MANY_SEP3 = function (options) {
this.manySepFirstInternal(3, options);
};
RecognizerApi.prototype.MANY_SEP4 = function (options) {
this.manySepFirstInternal(4, options);
};
RecognizerApi.prototype.MANY_SEP5 = function (options) {
this.manySepFirstInternal(5, options);
};
RecognizerApi.prototype.MANY_SEP6 = function (options) {
this.manySepFirstInternal(6, options);
};
RecognizerApi.prototype.MANY_SEP7 = function (options) {
this.manySepFirstInternal(7, options);
};
RecognizerApi.prototype.MANY_SEP8 = function (options) {
this.manySepFirstInternal(8, options);
};
RecognizerApi.prototype.MANY_SEP9 = function (options) {
this.manySepFirstInternal(9, options);
};
RecognizerApi.prototype.AT_LEAST_ONE = function (actionORMethodDef) {
this.atLeastOneInternal(0, actionORMethodDef);
};
RecognizerApi.prototype.AT_LEAST_ONE1 = function (actionORMethodDef) {
return this.atLeastOneInternal(1, actionORMethodDef);
};
RecognizerApi.prototype.AT_LEAST_ONE2 = function (actionORMethodDef) {
this.atLeastOneInternal(2, actionORMethodDef);
};
RecognizerApi.prototype.AT_LEAST_ONE3 = function (actionORMethodDef) {
this.atLeastOneInternal(3, actionORMethodDef);
};
RecognizerApi.prototype.AT_LEAST_ONE4 = function (actionORMethodDef) {
this.atLeastOneInternal(4, actionORMethodDef);
};
RecognizerApi.prototype.AT_LEAST_ONE5 = function (actionORMethodDef) {
this.atLeastOneInternal(5, actionORMethodDef);
};
RecognizerApi.prototype.AT_LEAST_ONE6 = function (actionORMethodDef) {
this.atLeastOneInternal(6, actionORMethodDef);
};
RecognizerApi.prototype.AT_LEAST_ONE7 = function (actionORMethodDef) {
this.atLeastOneInternal(7, actionORMethodDef);
};
RecognizerApi.prototype.AT_LEAST_ONE8 = function (actionORMethodDef) {
this.atLeastOneInternal(8, actionORMethodDef);
};
RecognizerApi.prototype.AT_LEAST_ONE9 = function (actionORMethodDef) {
this.atLeastOneInternal(9, actionORMethodDef);
};
RecognizerApi.prototype.AT_LEAST_ONE_SEP = function (options) {
this.atLeastOneSepFirstInternal(0, options);
};
RecognizerApi.prototype.AT_LEAST_ONE_SEP1 = function (options) {
this.atLeastOneSepFirstInternal(1, options);
};
RecognizerApi.prototype.AT_LEAST_ONE_SEP2 = function (options) {
this.atLeastOneSepFirstInternal(2, options);
};
RecognizerApi.prototype.AT_LEAST_ONE_SEP3 = function (options) {
this.atLeastOneSepFirstInternal(3, options);
};
RecognizerApi.prototype.AT_LEAST_ONE_SEP4 = function (options) {
this.atLeastOneSepFirstInternal(4, options);
};
RecognizerApi.prototype.AT_LEAST_ONE_SEP5 = function (options) {
this.atLeastOneSepFirstInternal(5, options);
};
RecognizerApi.prototype.AT_LEAST_ONE_SEP6 = function (options) {
this.atLeastOneSepFirstInternal(6, options);
};
RecognizerApi.prototype.AT_LEAST_ONE_SEP7 = function (options) {
this.atLeastOneSepFirstInternal(7, options);
};
RecognizerApi.prototype.AT_LEAST_ONE_SEP8 = function (options) {
this.atLeastOneSepFirstInternal(8, options);
};
RecognizerApi.prototype.AT_LEAST_ONE_SEP9 = function (options) {
this.atLeastOneSepFirstInternal(9, options);
};
RecognizerApi.prototype.RULE = function (name, implementation, config) {
if (config === void 0) { config = DEFAULT_RULE_CONFIG; }
if (contains(this.definedRulesNames, name)) {
var errMsg = defaultGrammarValidatorErrorProvider.buildDuplicateRuleNameError({
topLevelRule: name,
grammarName: this.className
});
var error = {
message: errMsg,
type: ParserDefinitionErrorType.DUPLICATE_RULE_NAME,
ruleName: name
};
this.definitionErrors.push(error);
}
this.definedRulesNames.push(name);
var ruleImplementation = this.defineRule(name, implementation, config);
this[name] = ruleImplementation;
return ruleImplementation;
};
RecognizerApi.prototype.OVERRIDE_RULE = function (name, impl, config) {
if (config === void 0) { config = DEFAULT_RULE_CONFIG; }
var ruleErrors = [];
ruleErrors = ruleErrors.concat(validateRuleIsOverridden(name, this.definedRulesNames, this.className));
this.definitionErrors.push.apply(this.definitionErrors, ruleErrors); // mutability for the win
var ruleImplementation = this.defineRule(name, impl, config);
this[name] = ruleImplementation;
return ruleImplementation;
};
RecognizerApi.prototype.BACKTRACK = function (grammarRule, args) {
return function () {
// save org state
this.isBackTrackingStack.push(1);
var orgState = this.saveRecogState();
try {
grammarRule.apply(this, args);
// if no exception was thrown we have succeed parsing the rule.
return true;
}
catch (e) {
if (isRecognitionException(e)) {
return false;
}
else {
throw e;
}
}
finally {
this.reloadRecogState(orgState);
this.isBackTrackingStack.pop();
}
};
};
// GAST export APIs
RecognizerApi.prototype.getGAstProductions = function () {
return this.gastProductionsCache;
};
RecognizerApi.prototype.getSerializedGastProductions = function () {
return serializeGrammar(values(this.gastProductionsCache));
};
return RecognizerApi;
}());
export { RecognizerApi };
//# sourceMappingURL=recognizer_api.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,548 @@
import { cloneArr, cloneObj, every, flatten, has, isArray, isEmpty, isObject, reduce, uniq, values } from "../../../utils/utils";
import { AT_LEAST_ONE_IDX, AT_LEAST_ONE_SEP_IDX, BITS_FOR_METHOD_TYPE, BITS_FOR_OCCURRENCE_IDX, MANY_IDX, MANY_SEP_IDX, OPTION_IDX, OR_IDX } from "../../grammar/keys";
import { isRecognitionException, MismatchedTokenException, NotAllInputParsedException } from "../../exceptions_public";
import { PROD_TYPE } from "../../grammar/lookahead";
import { NextTerminalAfterAtLeastOneSepWalker, NextTerminalAfterAtLeastOneWalker, NextTerminalAfterManySepWalker, NextTerminalAfterManyWalker } from "../../grammar/interpreter";
import { DEFAULT_RULE_CONFIG } from "../parser";
import { IN_RULE_RECOVERY_EXCEPTION } from "./recoverable";
import { EOF } from "../../../scan/tokens_public";
import { augmentTokenTypes, isTokenType, tokenStructuredMatcher, tokenStructuredMatcherNoCategories } from "../../../scan/tokens";
import { classNameFromInstance } from "../../../lang/lang_extensions";
/**
* This trait is responsible for the runtime parsing engine
* Used by the official API (recognizer_api.ts)
*/
var RecognizerEngine = /** @class */ (function () {
function RecognizerEngine() {
}
RecognizerEngine.prototype.initRecognizerEngine = function (tokenVocabulary, config) {
this.className = classNameFromInstance(this);
// TODO: would using an ES6 Map or plain object be faster (CST building scenario)
this.shortRuleNameToFull = {};
this.fullRuleNameToShort = {};
this.ruleShortNameIdx = 256;
this.tokenMatcher = tokenStructuredMatcherNoCategories;
this.definedRulesNames = [];
this.tokensMap = {};
this.isBackTrackingStack = [];
this.RULE_STACK = [];
this.RULE_OCCURRENCE_STACK = [];
this.gastProductionsCache = {};
if (has(config, "serializedGrammar")) {
throw Error("The Parser's configuration can no longer contain a <serializedGrammar> property.\n" +
"\tSee: https://sap.github.io/chevrotain/docs/changes/BREAKING_CHANGES.html#_6-0-0\n" +
"\tFor Further details.");
}
if (isArray(tokenVocabulary)) {
// This only checks for Token vocabularies provided as arrays.
// That is good enough because the main objective is to detect users of pre-V4.0 APIs
// rather than all edge cases of empty Token vocabularies.
if (isEmpty(tokenVocabulary)) {
throw Error("A Token Vocabulary cannot be empty.\n" +
"\tNote that the first argument for the parser constructor\n" +
"\tis no longer a Token vector (since v4.0).");
}
if (typeof tokenVocabulary[0].startOffset === "number") {
throw Error("The Parser constructor no longer accepts a token vector as the first argument.\n" +
"\tSee: https://sap.github.io/chevrotain/docs/changes/BREAKING_CHANGES.html#_4-0-0\n" +
"\tFor Further details.");
}
}
if (isArray(tokenVocabulary)) {
this.tokensMap = reduce(tokenVocabulary, function (acc, tokType) {
acc[tokType.name] = tokType;
return acc;
}, {});
}
else if (has(tokenVocabulary, "modes") &&
every(flatten(values(tokenVocabulary.modes)), isTokenType)) {
var allTokenTypes = flatten(values(tokenVocabulary.modes));
var uniqueTokens = uniq(allTokenTypes);
this.tokensMap = reduce(uniqueTokens, function (acc, tokType) {
acc[tokType.name] = tokType;
return acc;
}, {});
}
else if (isObject(tokenVocabulary)) {
this.tokensMap = cloneObj(tokenVocabulary);
}
else {
throw new Error("<tokensDictionary> argument must be An Array of Token constructors," +
" A dictionary of Token constructors or an IMultiModeLexerDefinition");
}
// always add EOF to the tokenNames -> constructors map. it is useful to assure all the input has been
// parsed with a clear error message ("expecting EOF but found ...")
/* tslint:disable */
this.tokensMap["EOF"] = EOF;
// TODO: This check may not be accurate for multi mode lexers
var noTokenCategoriesUsed = every(values(tokenVocabulary), function (tokenConstructor) { return isEmpty(tokenConstructor.categoryMatches); });
this.tokenMatcher = noTokenCategoriesUsed
? tokenStructuredMatcherNoCategories
: tokenStructuredMatcher;
// Because ES2015+ syntax should be supported for creating Token classes
// We cannot assume that the Token classes were created using the "extendToken" utilities
// Therefore we must augment the Token classes both on Lexer initialization and on Parser initialization
augmentTokenTypes(values(this.tokensMap));
};
RecognizerEngine.prototype.defineRule = function (ruleName, impl, config) {
if (this.selfAnalysisDone) {
throw Error("Grammar rule <" + ruleName + "> may not be defined after the 'performSelfAnalysis' method has been called'\n" +
"Make sure that all grammar rule definitions are done before 'performSelfAnalysis' is called.");
}
var resyncEnabled = has(config, "resyncEnabled")
? config.resyncEnabled
: DEFAULT_RULE_CONFIG.resyncEnabled;
var recoveryValueFunc = has(config, "recoveryValueFunc")
? config.recoveryValueFunc
: DEFAULT_RULE_CONFIG.recoveryValueFunc;
// performance optimization: Use small integers as keys for the longer human readable "full" rule names.
// this greatly improves Map access time (as much as 8% for some performance benchmarks).
/* tslint:disable */
var shortName = this.ruleShortNameIdx << (BITS_FOR_METHOD_TYPE + BITS_FOR_OCCURRENCE_IDX);
/* tslint:enable */
this.ruleShortNameIdx++;
this.shortRuleNameToFull[shortName] = ruleName;
this.fullRuleNameToShort[ruleName] = shortName;
function invokeRuleWithTry(args) {
try {
if (this.outputCst === true) {
impl.apply(this, args);
var cst = this.CST_STACK[this.CST_STACK.length - 1];
this.cstPostRule(cst);
return cst;
}
else {
return impl.apply(this, args);
}
}
catch (e) {
return this.invokeRuleCatch(e, resyncEnabled, recoveryValueFunc);
}
finally {
this.ruleFinallyStateUpdate();
}
}
var wrappedGrammarRule;
wrappedGrammarRule = function (idxInCallingRule, args) {
if (idxInCallingRule === void 0) { idxInCallingRule = 0; }
this.ruleInvocationStateUpdate(shortName, ruleName, idxInCallingRule);
return invokeRuleWithTry.call(this, args);
};
var ruleNamePropName = "ruleName";
wrappedGrammarRule[ruleNamePropName] = ruleName;
wrappedGrammarRule["originalGrammarAction"] = impl;
return wrappedGrammarRule;
};
RecognizerEngine.prototype.invokeRuleCatch = function (e, resyncEnabledConfig, recoveryValueFunc) {
var isFirstInvokedRule = this.RULE_STACK.length === 1;
// note the reSync is always enabled for the first rule invocation, because we must always be able to
// reSync with EOF and just output some INVALID ParseTree
// during backtracking reSync recovery is disabled, otherwise we can't be certain the backtracking
// path is really the most valid one
var reSyncEnabled = resyncEnabledConfig && !this.isBackTracking() && this.recoveryEnabled;
if (isRecognitionException(e)) {
var recogError = e;
if (reSyncEnabled) {
var reSyncTokType = this.findReSyncTokenType();
if (this.isInCurrentRuleReSyncSet(reSyncTokType)) {
recogError.resyncedTokens = this.reSyncTo(reSyncTokType);
if (this.outputCst) {
var partialCstResult = this.CST_STACK[this.CST_STACK.length - 1];
partialCstResult.recoveredNode = true;
return partialCstResult;
}
else {
return recoveryValueFunc();
}
}
else {
if (this.outputCst) {
var partialCstResult = this.CST_STACK[this.CST_STACK.length - 1];
partialCstResult.recoveredNode = true;
recogError.partialCstResult = partialCstResult;
}
// to be handled Further up the call stack
throw recogError;
}
}
else if (isFirstInvokedRule) {
// otherwise a Redundant input error will be created as well and we cannot guarantee that this is indeed the case
this.moveToTerminatedState();
// the parser should never throw one of its own errors outside its flow.
// even if error recovery is disabled
return recoveryValueFunc();
}
else {
// to be recovered Further up the call stack
throw recogError;
}
}
else {
// some other Error type which we don't know how to handle (for example a built in JavaScript Error)
throw e;
}
};
// Implementation of parsing DSL
RecognizerEngine.prototype.optionInternal = function (actionORMethodDef, occurrence) {
var key = this.getKeyForAutomaticLookahead(OPTION_IDX, occurrence);
return this.optionInternalLogic(actionORMethodDef, occurrence, key);
};
RecognizerEngine.prototype.optionInternalLogic = function (actionORMethodDef, occurrence, key) {
var _this = this;
var lookAheadFunc = this.getLaFuncFromCache(key);
var action;
var predicate;
if (actionORMethodDef.DEF !== undefined) {
action = actionORMethodDef.DEF;
predicate = actionORMethodDef.GATE;
// predicate present
if (predicate !== undefined) {
var orgLookaheadFunction_1 = lookAheadFunc;
lookAheadFunc = function () {
return predicate.call(_this) && orgLookaheadFunction_1.call(_this);
};
}
}
else {
action = actionORMethodDef;
}
if (lookAheadFunc.call(this) === true) {
return action.call(this);
}
return undefined;
};
RecognizerEngine.prototype.atLeastOneInternal = function (prodOccurrence, actionORMethodDef) {
var laKey = this.getKeyForAutomaticLookahead(AT_LEAST_ONE_IDX, prodOccurrence);
return this.atLeastOneInternalLogic(prodOccurrence, actionORMethodDef, laKey);
};
RecognizerEngine.prototype.atLeastOneInternalLogic = function (prodOccurrence, actionORMethodDef, key) {
var _this = this;
var lookAheadFunc = this.getLaFuncFromCache(key);
var action;
var predicate;
if (actionORMethodDef.DEF !== undefined) {
action = actionORMethodDef.DEF;
predicate = actionORMethodDef.GATE;
// predicate present
if (predicate !== undefined) {
var orgLookaheadFunction_2 = lookAheadFunc;
lookAheadFunc = function () {
return predicate.call(_this) && orgLookaheadFunction_2.call(_this);
};
}
}
else {
action = actionORMethodDef;
}
if (lookAheadFunc.call(this) === true) {
var notStuck = this.doSingleRepetition(action);
while (lookAheadFunc.call(this) === true &&
notStuck === true) {
notStuck = this.doSingleRepetition(action);
}
}
else {
throw this.raiseEarlyExitException(prodOccurrence, PROD_TYPE.REPETITION_MANDATORY, actionORMethodDef.ERR_MSG);
}
// note that while it may seem that this can cause an error because by using a recursive call to
// AT_LEAST_ONE we change the grammar to AT_LEAST_TWO, AT_LEAST_THREE ... , the possible recursive call
// from the tryInRepetitionRecovery(...) will only happen IFF there really are TWO/THREE/.... items.
// Performance optimization: "attemptInRepetitionRecovery" will be defined as NOOP unless recovery is enabled
this.attemptInRepetitionRecovery(this.atLeastOneInternal, [prodOccurrence, actionORMethodDef], lookAheadFunc, AT_LEAST_ONE_IDX, prodOccurrence, NextTerminalAfterAtLeastOneWalker);
};
RecognizerEngine.prototype.atLeastOneSepFirstInternal = function (prodOccurrence, options) {
var laKey = this.getKeyForAutomaticLookahead(AT_LEAST_ONE_SEP_IDX, prodOccurrence);
this.atLeastOneSepFirstInternalLogic(prodOccurrence, options, laKey);
};
RecognizerEngine.prototype.atLeastOneSepFirstInternalLogic = function (prodOccurrence, options, key) {
var _this = this;
var action = options.DEF;
var separator = options.SEP;
var firstIterationLookaheadFunc = this.getLaFuncFromCache(key);
// 1st iteration
if (firstIterationLookaheadFunc.call(this) === true) {
;
action.call(this);
// TODO: Optimization can move this function construction into "attemptInRepetitionRecovery"
// because it is only needed in error recovery scenarios.
var separatorLookAheadFunc = function () {
return _this.tokenMatcher(_this.LA(1), separator);
};
// 2nd..nth iterations
while (this.tokenMatcher(this.LA(1), separator) === true) {
// note that this CONSUME will never enter recovery because
// the separatorLookAheadFunc checks that the separator really does exist.
this.CONSUME(separator);
action.call(this);
}
// Performance optimization: "attemptInRepetitionRecovery" will be defined as NOOP unless recovery is enabled
this.attemptInRepetitionRecovery(this.repetitionSepSecondInternal, [
prodOccurrence,
separator,
separatorLookAheadFunc,
action,
NextTerminalAfterAtLeastOneSepWalker
], separatorLookAheadFunc, AT_LEAST_ONE_SEP_IDX, prodOccurrence, NextTerminalAfterAtLeastOneSepWalker);
}
else {
throw this.raiseEarlyExitException(prodOccurrence, PROD_TYPE.REPETITION_MANDATORY_WITH_SEPARATOR, options.ERR_MSG);
}
};
RecognizerEngine.prototype.manyInternal = function (prodOccurrence, actionORMethodDef) {
var laKey = this.getKeyForAutomaticLookahead(MANY_IDX, prodOccurrence);
return this.manyInternalLogic(prodOccurrence, actionORMethodDef, laKey);
};
RecognizerEngine.prototype.manyInternalLogic = function (prodOccurrence, actionORMethodDef, key) {
var _this = this;
var lookaheadFunction = this.getLaFuncFromCache(key);
var action;
var predicate;
if (actionORMethodDef.DEF !== undefined) {
action = actionORMethodDef.DEF;
predicate = actionORMethodDef.GATE;
// predicate present
if (predicate !== undefined) {
var orgLookaheadFunction_3 = lookaheadFunction;
lookaheadFunction = function () {
return predicate.call(_this) && orgLookaheadFunction_3.call(_this);
};
}
}
else {
action = actionORMethodDef;
}
var notStuck = true;
while (lookaheadFunction.call(this) === true && notStuck === true) {
notStuck = this.doSingleRepetition(action);
}
// Performance optimization: "attemptInRepetitionRecovery" will be defined as NOOP unless recovery is enabled
this.attemptInRepetitionRecovery(this.manyInternal, [prodOccurrence, actionORMethodDef], lookaheadFunction, MANY_IDX, prodOccurrence, NextTerminalAfterManyWalker,
// The notStuck parameter is only relevant when "attemptInRepetitionRecovery"
// is invoked from manyInternal, in the MANY_SEP case and AT_LEAST_ONE[_SEP]
// An infinite loop cannot occur as:
// - Either the lookahead is guaranteed to consume something (Single Token Separator)
// - AT_LEAST_ONE by definition is guaranteed to consume something (or error out).
notStuck);
};
RecognizerEngine.prototype.manySepFirstInternal = function (prodOccurrence, options) {
var laKey = this.getKeyForAutomaticLookahead(MANY_SEP_IDX, prodOccurrence);
this.manySepFirstInternalLogic(prodOccurrence, options, laKey);
};
RecognizerEngine.prototype.manySepFirstInternalLogic = function (prodOccurrence, options, key) {
var _this = this;
var action = options.DEF;
var separator = options.SEP;
var firstIterationLaFunc = this.getLaFuncFromCache(key);
// 1st iteration
if (firstIterationLaFunc.call(this) === true) {
action.call(this);
var separatorLookAheadFunc = function () {
return _this.tokenMatcher(_this.LA(1), separator);
};
// 2nd..nth iterations
while (this.tokenMatcher(this.LA(1), separator) === true) {
// note that this CONSUME will never enter recovery because
// the separatorLookAheadFunc checks that the separator really does exist.
this.CONSUME(separator);
// No need for checking infinite loop here due to consuming the separator.
action.call(this);
}
// Performance optimization: "attemptInRepetitionRecovery" will be defined as NOOP unless recovery is enabled
this.attemptInRepetitionRecovery(this.repetitionSepSecondInternal, [
prodOccurrence,
separator,
separatorLookAheadFunc,
action,
NextTerminalAfterManySepWalker
], separatorLookAheadFunc, MANY_SEP_IDX, prodOccurrence, NextTerminalAfterManySepWalker);
}
};
RecognizerEngine.prototype.repetitionSepSecondInternal = function (prodOccurrence, separator, separatorLookAheadFunc, action, nextTerminalAfterWalker) {
while (separatorLookAheadFunc()) {
// note that this CONSUME will never enter recovery because
// the separatorLookAheadFunc checks that the separator really does exist.
this.CONSUME(separator);
action.call(this);
}
// we can only arrive to this function after an error
// has occurred (hence the name 'second') so the following
// IF will always be entered, its possible to remove it...
// however it is kept to avoid confusion and be consistent.
// Performance optimization: "attemptInRepetitionRecovery" will be defined as NOOP unless recovery is enabled
/* istanbul ignore else */
this.attemptInRepetitionRecovery(this.repetitionSepSecondInternal, [
prodOccurrence,
separator,
separatorLookAheadFunc,
action,
nextTerminalAfterWalker
], separatorLookAheadFunc, AT_LEAST_ONE_SEP_IDX, prodOccurrence, nextTerminalAfterWalker);
};
RecognizerEngine.prototype.doSingleRepetition = function (action) {
var beforeIteration = this.getLexerPosition();
action.call(this);
var afterIteration = this.getLexerPosition();
// This boolean will indicate if this repetition progressed
// or if we are "stuck" (potential infinite loop in the repetition).
return afterIteration > beforeIteration;
};
RecognizerEngine.prototype.orInternal = function (altsOrOpts, occurrence) {
var laKey = this.getKeyForAutomaticLookahead(OR_IDX, occurrence);
var alts = isArray(altsOrOpts)
? altsOrOpts
: altsOrOpts.DEF;
var laFunc = this.getLaFuncFromCache(laKey);
var altIdxToTake = laFunc.call(this, alts);
if (altIdxToTake !== undefined) {
var chosenAlternative = alts[altIdxToTake];
return chosenAlternative.ALT.call(this);
}
this.raiseNoAltException(occurrence, altsOrOpts.ERR_MSG);
};
RecognizerEngine.prototype.ruleFinallyStateUpdate = function () {
this.RULE_STACK.pop();
this.RULE_OCCURRENCE_STACK.pop();
// NOOP when cst is disabled
this.cstFinallyStateUpdate();
if (this.RULE_STACK.length === 0 && this.isAtEndOfInput() === false) {
var firstRedundantTok = this.LA(1);
var errMsg = this.errorMessageProvider.buildNotAllInputParsedMessage({
firstRedundant: firstRedundantTok,
ruleName: this.getCurrRuleFullName()
});
this.SAVE_ERROR(new NotAllInputParsedException(errMsg, firstRedundantTok));
}
};
RecognizerEngine.prototype.subruleInternal = function (ruleToCall, idx, options) {
var ruleResult;
try {
var args = options !== undefined ? options.ARGS : undefined;
ruleResult = ruleToCall.call(this, idx, args);
this.cstPostNonTerminal(ruleResult, options !== undefined && options.LABEL !== undefined
? options.LABEL
: ruleToCall.ruleName);
return ruleResult;
}
catch (e) {
this.subruleInternalError(e, options, ruleToCall.ruleName);
}
};
RecognizerEngine.prototype.subruleInternalError = function (e, options, ruleName) {
if (isRecognitionException(e) && e.partialCstResult !== undefined) {
this.cstPostNonTerminal(e.partialCstResult, options !== undefined && options.LABEL !== undefined
? options.LABEL
: ruleName);
delete e.partialCstResult;
}
throw e;
};
RecognizerEngine.prototype.consumeInternal = function (tokType, idx, options) {
var consumedToken;
try {
var nextToken = this.LA(1);
if (this.tokenMatcher(nextToken, tokType) === true) {
this.consumeToken();
consumedToken = nextToken;
}
else {
this.consumeInternalError(tokType, nextToken, options);
}
}
catch (eFromConsumption) {
consumedToken = this.consumeInternalRecovery(tokType, idx, eFromConsumption);
}
this.cstPostTerminal(options !== undefined && options.LABEL !== undefined
? options.LABEL
: tokType.name, consumedToken);
return consumedToken;
};
RecognizerEngine.prototype.consumeInternalError = function (tokType, nextToken, options) {
var msg;
var previousToken = this.LA(0);
if (options !== undefined && options.ERR_MSG) {
msg = options.ERR_MSG;
}
else {
msg = this.errorMessageProvider.buildMismatchTokenMessage({
expected: tokType,
actual: nextToken,
previous: previousToken,
ruleName: this.getCurrRuleFullName()
});
}
throw this.SAVE_ERROR(new MismatchedTokenException(msg, nextToken, previousToken));
};
RecognizerEngine.prototype.consumeInternalRecovery = function (tokType, idx, eFromConsumption) {
// no recovery allowed during backtracking, otherwise backtracking may recover invalid syntax and accept it
// but the original syntax could have been parsed successfully without any backtracking + recovery
if (this.recoveryEnabled &&
// TODO: more robust checking of the exception type. Perhaps Typescript extending expressions?
eFromConsumption.name === "MismatchedTokenException" &&
!this.isBackTracking()) {
var follows = this.getFollowsForInRuleRecovery(tokType, idx);
try {
return this.tryInRuleRecovery(tokType, follows);
}
catch (eFromInRuleRecovery) {
if (eFromInRuleRecovery.name === IN_RULE_RECOVERY_EXCEPTION) {
// failed in RuleRecovery.
// throw the original error in order to trigger reSync error recovery
throw eFromConsumption;
}
else {
throw eFromInRuleRecovery;
}
}
}
else {
throw eFromConsumption;
}
};
RecognizerEngine.prototype.saveRecogState = function () {
// errors is a getter which will clone the errors array
var savedErrors = this.errors;
var savedRuleStack = cloneArr(this.RULE_STACK);
return {
errors: savedErrors,
lexerState: this.exportLexerState(),
RULE_STACK: savedRuleStack,
CST_STACK: this.CST_STACK
};
};
RecognizerEngine.prototype.reloadRecogState = function (newState) {
this.errors = newState.errors;
this.importLexerState(newState.lexerState);
this.RULE_STACK = newState.RULE_STACK;
};
RecognizerEngine.prototype.ruleInvocationStateUpdate = function (shortName, fullName, idxInCallingRule) {
this.RULE_OCCURRENCE_STACK.push(idxInCallingRule);
this.RULE_STACK.push(shortName);
// NOOP when cst is disabled
this.cstInvocationStateUpdate(fullName, shortName);
};
RecognizerEngine.prototype.isBackTracking = function () {
return this.isBackTrackingStack.length !== 0;
};
RecognizerEngine.prototype.getCurrRuleFullName = function () {
var shortName = this.getLastExplicitRuleShortName();
return this.shortRuleNameToFull[shortName];
};
RecognizerEngine.prototype.shortRuleNameToFullName = function (shortName) {
return this.shortRuleNameToFull[shortName];
};
RecognizerEngine.prototype.isAtEndOfInput = function () {
return this.tokenMatcher(this.LA(1), EOF);
};
RecognizerEngine.prototype.reset = function () {
this.resetLexerState();
this.isBackTrackingStack = [];
this.errors = [];
this.RULE_STACK = [];
// TODO: extract a specific reset for TreeBuilder trait
this.CST_STACK = [];
this.RULE_OCCURRENCE_STACK = [];
};
return RecognizerEngine;
}());
export { RecognizerEngine };
//# sourceMappingURL=recognizer_engine.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,290 @@
import { createTokenInstance, EOF } from "../../../scan/tokens_public";
import { cloneArr, contains, dropRight, find, flatten, has, isEmpty, map } from "../../../utils/utils";
import { MismatchedTokenException } from "../../exceptions_public";
import { IN } from "../../constants";
import { DEFAULT_PARSER_CONFIG } from "../parser";
export var EOF_FOLLOW_KEY = {};
export var IN_RULE_RECOVERY_EXCEPTION = "InRuleRecoveryException";
export function InRuleRecoveryException(message) {
this.name = IN_RULE_RECOVERY_EXCEPTION;
this.message = message;
}
InRuleRecoveryException.prototype = Error.prototype;
/**
* This trait is responsible for the error recovery and fault tolerant logic
*/
var Recoverable = /** @class */ (function () {
function Recoverable() {
}
Recoverable.prototype.initRecoverable = function (config) {
this.firstAfterRepMap = {};
this.resyncFollows = {};
this.recoveryEnabled = has(config, "recoveryEnabled")
? config.recoveryEnabled
: DEFAULT_PARSER_CONFIG.recoveryEnabled;
// performance optimization, NOOP will be inlined which
// effectively means that this optional feature does not exist
// when not used.
if (this.recoveryEnabled) {
this.attemptInRepetitionRecovery = attemptInRepetitionRecovery;
}
};
Recoverable.prototype.getTokenToInsert = function (tokType) {
var tokToInsert = createTokenInstance(tokType, "", NaN, NaN, NaN, NaN, NaN, NaN);
tokToInsert.isInsertedInRecovery = true;
return tokToInsert;
};
Recoverable.prototype.canTokenTypeBeInsertedInRecovery = function (tokType) {
return true;
};
Recoverable.prototype.tryInRepetitionRecovery = function (grammarRule, grammarRuleArgs, lookAheadFunc, expectedTokType) {
var _this = this;
// TODO: can the resyncTokenType be cached?
var reSyncTokType = this.findReSyncTokenType();
var savedLexerState = this.exportLexerState();
var resyncedTokens = [];
var passedResyncPoint = false;
var nextTokenWithoutResync = this.LA(1);
var currToken = this.LA(1);
var generateErrorMessage = function () {
var previousToken = _this.LA(0);
// we are preemptively re-syncing before an error has been detected, therefor we must reproduce
// the error that would have been thrown
var msg = _this.errorMessageProvider.buildMismatchTokenMessage({
expected: expectedTokType,
actual: nextTokenWithoutResync,
previous: previousToken,
ruleName: _this.getCurrRuleFullName()
});
var error = new MismatchedTokenException(msg, nextTokenWithoutResync, _this.LA(0));
// the first token here will be the original cause of the error, this is not part of the resyncedTokens property.
error.resyncedTokens = dropRight(resyncedTokens);
_this.SAVE_ERROR(error);
};
while (!passedResyncPoint) {
// re-synced to a point where we can safely exit the repetition/
if (this.tokenMatcher(currToken, expectedTokType)) {
generateErrorMessage();
return; // must return here to avoid reverting the inputIdx
}
else if (lookAheadFunc.call(this)) {
// we skipped enough tokens so we can resync right back into another iteration of the repetition grammar rule
generateErrorMessage();
// recursive invocation in other to support multiple re-syncs in the same top level repetition grammar rule
grammarRule.apply(this, grammarRuleArgs);
return; // must return here to avoid reverting the inputIdx
}
else if (this.tokenMatcher(currToken, reSyncTokType)) {
passedResyncPoint = true;
}
else {
currToken = this.SKIP_TOKEN();
this.addToResyncTokens(currToken, resyncedTokens);
}
}
// we were unable to find a CLOSER point to resync inside the Repetition, reset the state.
// The parsing exception we were trying to prevent will happen in the NEXT parsing step. it may be handled by
// "between rules" resync recovery later in the flow.
this.importLexerState(savedLexerState);
};
Recoverable.prototype.shouldInRepetitionRecoveryBeTried = function (expectTokAfterLastMatch, nextTokIdx, notStuck) {
// Edge case of arriving from a MANY repetition which is stuck
// Attempting recovery in this case could cause an infinite loop
if (notStuck === false) {
return false;
}
// arguments to try and perform resync into the next iteration of the many are missing
if (expectTokAfterLastMatch === undefined || nextTokIdx === undefined) {
return false;
}
// no need to recover, next token is what we expect...
if (this.tokenMatcher(this.LA(1), expectTokAfterLastMatch)) {
return false;
}
// error recovery is disabled during backtracking as it can make the parser ignore a valid grammar path
// and prefer some backtracking path that includes recovered errors.
if (this.isBackTracking()) {
return false;
}
// if we can perform inRule recovery (single token insertion or deletion) we always prefer that recovery algorithm
// because if it works, it makes the least amount of changes to the input stream (greedy algorithm)
//noinspection RedundantIfStatementJS
if (this.canPerformInRuleRecovery(expectTokAfterLastMatch, this.getFollowsForInRuleRecovery(expectTokAfterLastMatch, nextTokIdx))) {
return false;
}
return true;
};
// Error Recovery functionality
Recoverable.prototype.getFollowsForInRuleRecovery = function (tokType, tokIdxInRule) {
var grammarPath = this.getCurrentGrammarPath(tokType, tokIdxInRule);
var follows = this.getNextPossibleTokenTypes(grammarPath);
return follows;
};
Recoverable.prototype.tryInRuleRecovery = function (expectedTokType, follows) {
if (this.canRecoverWithSingleTokenInsertion(expectedTokType, follows)) {
var tokToInsert = this.getTokenToInsert(expectedTokType);
return tokToInsert;
}
if (this.canRecoverWithSingleTokenDeletion(expectedTokType)) {
var nextTok = this.SKIP_TOKEN();
this.consumeToken();
return nextTok;
}
throw new InRuleRecoveryException("sad sad panda");
};
Recoverable.prototype.canPerformInRuleRecovery = function (expectedToken, follows) {
return (this.canRecoverWithSingleTokenInsertion(expectedToken, follows) ||
this.canRecoverWithSingleTokenDeletion(expectedToken));
};
Recoverable.prototype.canRecoverWithSingleTokenInsertion = function (expectedTokType, follows) {
var _this = this;
if (!this.canTokenTypeBeInsertedInRecovery(expectedTokType)) {
return false;
}
// must know the possible following tokens to perform single token insertion
if (isEmpty(follows)) {
return false;
}
var mismatchedTok = this.LA(1);
var isMisMatchedTokInFollows = find(follows, function (possibleFollowsTokType) {
return _this.tokenMatcher(mismatchedTok, possibleFollowsTokType);
}) !== undefined;
return isMisMatchedTokInFollows;
};
Recoverable.prototype.canRecoverWithSingleTokenDeletion = function (expectedTokType) {
var isNextTokenWhatIsExpected = this.tokenMatcher(this.LA(2), expectedTokType);
return isNextTokenWhatIsExpected;
};
Recoverable.prototype.isInCurrentRuleReSyncSet = function (tokenTypeIdx) {
var followKey = this.getCurrFollowKey();
var currentRuleReSyncSet = this.getFollowSetFromFollowKey(followKey);
return contains(currentRuleReSyncSet, tokenTypeIdx);
};
Recoverable.prototype.findReSyncTokenType = function () {
var allPossibleReSyncTokTypes = this.flattenFollowSet();
// this loop will always terminate as EOF is always in the follow stack and also always (virtually) in the input
var nextToken = this.LA(1);
var k = 2;
while (true) {
var nextTokenType = nextToken.tokenType;
if (contains(allPossibleReSyncTokTypes, nextTokenType)) {
return nextTokenType;
}
nextToken = this.LA(k);
k++;
}
};
Recoverable.prototype.getCurrFollowKey = function () {
// the length is at least one as we always add the ruleName to the stack before invoking the rule.
if (this.RULE_STACK.length === 1) {
return EOF_FOLLOW_KEY;
}
var currRuleShortName = this.getLastExplicitRuleShortName();
var currRuleIdx = this.getLastExplicitRuleOccurrenceIndex();
var prevRuleShortName = this.getPreviousExplicitRuleShortName();
return {
ruleName: this.shortRuleNameToFullName(currRuleShortName),
idxInCallingRule: currRuleIdx,
inRule: this.shortRuleNameToFullName(prevRuleShortName)
};
};
Recoverable.prototype.buildFullFollowKeyStack = function () {
var _this = this;
var explicitRuleStack = this.RULE_STACK;
var explicitOccurrenceStack = this.RULE_OCCURRENCE_STACK;
return map(explicitRuleStack, function (ruleName, idx) {
if (idx === 0) {
return EOF_FOLLOW_KEY;
}
return {
ruleName: _this.shortRuleNameToFullName(ruleName),
idxInCallingRule: explicitOccurrenceStack[idx],
inRule: _this.shortRuleNameToFullName(explicitRuleStack[idx - 1])
};
});
};
Recoverable.prototype.flattenFollowSet = function () {
var _this = this;
var followStack = map(this.buildFullFollowKeyStack(), function (currKey) {
return _this.getFollowSetFromFollowKey(currKey);
});
return flatten(followStack);
};
Recoverable.prototype.getFollowSetFromFollowKey = function (followKey) {
if (followKey === EOF_FOLLOW_KEY) {
return [EOF];
}
var followName = followKey.ruleName + followKey.idxInCallingRule + IN + followKey.inRule;
return this.resyncFollows[followName];
};
// It does not make any sense to include a virtual EOF token in the list of resynced tokens
// as EOF does not really exist and thus does not contain any useful information (line/column numbers)
Recoverable.prototype.addToResyncTokens = function (token, resyncTokens) {
if (!this.tokenMatcher(token, EOF)) {
resyncTokens.push(token);
}
return resyncTokens;
};
Recoverable.prototype.reSyncTo = function (tokType) {
var resyncedTokens = [];
var nextTok = this.LA(1);
while (this.tokenMatcher(nextTok, tokType) === false) {
nextTok = this.SKIP_TOKEN();
this.addToResyncTokens(nextTok, resyncedTokens);
}
// the last token is not part of the error.
return dropRight(resyncedTokens);
};
Recoverable.prototype.attemptInRepetitionRecovery = function (prodFunc, args, lookaheadFunc, dslMethodIdx, prodOccurrence, nextToksWalker, notStuck) {
// by default this is a NO-OP
// The actual implementation is with the function(not method) below
};
Recoverable.prototype.getCurrentGrammarPath = function (tokType, tokIdxInRule) {
var pathRuleStack = this.getHumanReadableRuleStack();
var pathOccurrenceStack = cloneArr(this.RULE_OCCURRENCE_STACK);
var grammarPath = {
ruleStack: pathRuleStack,
occurrenceStack: pathOccurrenceStack,
lastTok: tokType,
lastTokOccurrence: tokIdxInRule
};
return grammarPath;
};
Recoverable.prototype.getHumanReadableRuleStack = function () {
var _this = this;
return map(this.RULE_STACK, function (currShortName) {
return _this.shortRuleNameToFullName(currShortName);
});
};
return Recoverable;
}());
export { Recoverable };
export function attemptInRepetitionRecovery(prodFunc, args, lookaheadFunc, dslMethodIdx, prodOccurrence, nextToksWalker, notStuck) {
var key = this.getKeyForAutomaticLookahead(dslMethodIdx, prodOccurrence);
var firstAfterRepInfo = this.firstAfterRepMap[key];
if (firstAfterRepInfo === undefined) {
var currRuleName = this.getCurrRuleFullName();
var ruleGrammar = this.getGAstProductions()[currRuleName];
var walker = new nextToksWalker(ruleGrammar, prodOccurrence);
firstAfterRepInfo = walker.startWalking();
this.firstAfterRepMap[key] = firstAfterRepInfo;
}
var expectTokAfterLastMatch = firstAfterRepInfo.token;
var nextTokIdx = firstAfterRepInfo.occurrence;
var isEndOfRule = firstAfterRepInfo.isEndOfRule;
// special edge case of a TOP most repetition after which the input should END.
// this will force an attempt for inRule recovery in that scenario.
if (this.RULE_STACK.length === 1 &&
isEndOfRule &&
expectTokAfterLastMatch === undefined) {
expectTokAfterLastMatch = EOF;
nextTokIdx = 1;
}
if (this.shouldInRepetitionRecoveryBeTried(expectTokAfterLastMatch, nextTokIdx, notStuck)) {
// TODO: performance optimization: instead of passing the original args here, we modify
// the args param (or create a new one) and make sure the lookahead func is explicitly provided
// to avoid searching the cache for it once more.
this.tryInRepetitionRecovery(prodFunc, args, lookaheadFunc, expectTokAfterLastMatch);
}
}
//# sourceMappingURL=recoverable.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,191 @@
import { addNoneTerminalToCst, addTerminalToCst, setNodeLocationFull, setNodeLocationOnlyOffset } from "../../cst/cst";
import { has, isUndefined, keys, NOOP } from "../../../utils/utils";
import { createBaseSemanticVisitorConstructor, createBaseVisitorConstructorWithDefaults } from "../../cst/cst_visitor";
import { DEFAULT_PARSER_CONFIG } from "../parser";
/**
* This trait is responsible for the CST building logic.
*/
var TreeBuilder = /** @class */ (function () {
function TreeBuilder() {
}
TreeBuilder.prototype.initTreeBuilder = function (config) {
this.CST_STACK = [];
// outputCst is no longer exposed/defined in the pubic API
this.outputCst = config.outputCst;
this.nodeLocationTracking = has(config, "nodeLocationTracking")
? config.nodeLocationTracking
: DEFAULT_PARSER_CONFIG.nodeLocationTracking;
if (!this.outputCst) {
this.cstInvocationStateUpdate = NOOP;
this.cstFinallyStateUpdate = NOOP;
this.cstPostTerminal = NOOP;
this.cstPostNonTerminal = NOOP;
this.cstPostRule = NOOP;
}
else {
if (/full/i.test(this.nodeLocationTracking)) {
if (this.recoveryEnabled) {
this.setNodeLocationFromToken = setNodeLocationFull;
this.setNodeLocationFromNode = setNodeLocationFull;
this.cstPostRule = NOOP;
this.setInitialNodeLocation = this.setInitialNodeLocationFullRecovery;
}
else {
this.setNodeLocationFromToken = NOOP;
this.setNodeLocationFromNode = NOOP;
this.cstPostRule = this.cstPostRuleFull;
this.setInitialNodeLocation = this.setInitialNodeLocationFullRegular;
}
}
else if (/onlyOffset/i.test(this.nodeLocationTracking)) {
if (this.recoveryEnabled) {
this.setNodeLocationFromToken = setNodeLocationOnlyOffset;
this.setNodeLocationFromNode = setNodeLocationOnlyOffset;
this.cstPostRule = NOOP;
this.setInitialNodeLocation = this.setInitialNodeLocationOnlyOffsetRecovery;
}
else {
this.setNodeLocationFromToken = NOOP;
this.setNodeLocationFromNode = NOOP;
this.cstPostRule = this.cstPostRuleOnlyOffset;
this.setInitialNodeLocation = this.setInitialNodeLocationOnlyOffsetRegular;
}
}
else if (/none/i.test(this.nodeLocationTracking)) {
this.setNodeLocationFromToken = NOOP;
this.setNodeLocationFromNode = NOOP;
this.cstPostRule = NOOP;
this.setInitialNodeLocation = NOOP;
}
else {
throw Error("Invalid <nodeLocationTracking> config option: \"" + config.nodeLocationTracking + "\"");
}
}
};
TreeBuilder.prototype.setInitialNodeLocationOnlyOffsetRecovery = function (cstNode) {
cstNode.location = {
startOffset: NaN,
endOffset: NaN
};
};
TreeBuilder.prototype.setInitialNodeLocationOnlyOffsetRegular = function (cstNode) {
cstNode.location = {
// without error recovery the starting Location of a new CstNode is guaranteed
// To be the next Token's startOffset (for valid inputs).
// For invalid inputs there won't be any CSTOutput so this potential
// inaccuracy does not matter
startOffset: this.LA(1).startOffset,
endOffset: NaN
};
};
TreeBuilder.prototype.setInitialNodeLocationFullRecovery = function (cstNode) {
cstNode.location = {
startOffset: NaN,
startLine: NaN,
startColumn: NaN,
endOffset: NaN,
endLine: NaN,
endColumn: NaN
};
};
/**
* @see setInitialNodeLocationOnlyOffsetRegular for explanation why this work
* @param cstNode
*/
TreeBuilder.prototype.setInitialNodeLocationFullRegular = function (cstNode) {
var nextToken = this.LA(1);
cstNode.location = {
startOffset: nextToken.startOffset,
startLine: nextToken.startLine,
startColumn: nextToken.startColumn,
endOffset: NaN,
endLine: NaN,
endColumn: NaN
};
};
TreeBuilder.prototype.cstInvocationStateUpdate = function (fullRuleName, shortName) {
var cstNode = {
name: fullRuleName,
children: {}
};
this.setInitialNodeLocation(cstNode);
this.CST_STACK.push(cstNode);
};
TreeBuilder.prototype.cstFinallyStateUpdate = function () {
this.CST_STACK.pop();
};
TreeBuilder.prototype.cstPostRuleFull = function (ruleCstNode) {
var prevToken = this.LA(0);
var loc = ruleCstNode.location;
// If this condition is true it means we consumed at least one Token
// In this CstNode.
if (loc.startOffset <= prevToken.startOffset === true) {
loc.endOffset = prevToken.endOffset;
loc.endLine = prevToken.endLine;
loc.endColumn = prevToken.endColumn;
}
// "empty" CstNode edge case
else {
loc.startOffset = NaN;
loc.startLine = NaN;
loc.startColumn = NaN;
}
};
TreeBuilder.prototype.cstPostRuleOnlyOffset = function (ruleCstNode) {
var prevToken = this.LA(0);
var loc = ruleCstNode.location;
// If this condition is true it means we consumed at least one Token
// In this CstNode.
if (loc.startOffset <= prevToken.startOffset === true) {
loc.endOffset = prevToken.endOffset;
}
// "empty" CstNode edge case
else {
loc.startOffset = NaN;
}
};
TreeBuilder.prototype.cstPostTerminal = function (key, consumedToken) {
var rootCst = this.CST_STACK[this.CST_STACK.length - 1];
addTerminalToCst(rootCst, consumedToken, key);
// This is only used when **both** error recovery and CST Output are enabled.
this.setNodeLocationFromToken(rootCst.location, consumedToken);
};
TreeBuilder.prototype.cstPostNonTerminal = function (ruleCstResult, ruleName) {
var preCstNode = this.CST_STACK[this.CST_STACK.length - 1];
addNoneTerminalToCst(preCstNode, ruleName, ruleCstResult);
// This is only used when **both** error recovery and CST Output are enabled.
this.setNodeLocationFromNode(preCstNode.location, ruleCstResult.location);
};
TreeBuilder.prototype.getBaseCstVisitorConstructor = function () {
if (isUndefined(this.baseCstVisitorConstructor)) {
var newBaseCstVisitorConstructor = createBaseSemanticVisitorConstructor(this.className, keys(this.gastProductionsCache));
this.baseCstVisitorConstructor = newBaseCstVisitorConstructor;
return newBaseCstVisitorConstructor;
}
return this.baseCstVisitorConstructor;
};
TreeBuilder.prototype.getBaseCstVisitorConstructorWithDefaults = function () {
if (isUndefined(this.baseCstVisitorWithDefaultsConstructor)) {
var newConstructor = createBaseVisitorConstructorWithDefaults(this.className, keys(this.gastProductionsCache), this.getBaseCstVisitorConstructor());
this.baseCstVisitorWithDefaultsConstructor = newConstructor;
return newConstructor;
}
return this.baseCstVisitorWithDefaultsConstructor;
};
TreeBuilder.prototype.getLastExplicitRuleShortName = function () {
var ruleStack = this.RULE_STACK;
return ruleStack[ruleStack.length - 1];
};
TreeBuilder.prototype.getPreviousExplicitRuleShortName = function () {
var ruleStack = this.RULE_STACK;
return ruleStack[ruleStack.length - 2];
};
TreeBuilder.prototype.getLastExplicitRuleOccurrenceIndex = function () {
var occurrenceStack = this.RULE_OCCURRENCE_STACK;
return occurrenceStack[occurrenceStack.length - 1];
};
return TreeBuilder;
}());
export { TreeBuilder };
//# sourceMappingURL=tree_builder.js.map

File diff suppressed because one or more lines are too long