@traqula/chevrotain 1.0.5 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -63,7 +63,7 @@ __export(index_exports, {
63
63
  module.exports = __toCommonJS(index_exports);
64
64
 
65
65
  // ../../node_modules/chevrotain/lib/src/version.js
66
- var VERSION = "11.0.3";
66
+ var VERSION = "11.2.0";
67
67
 
68
68
  // ../../node_modules/lodash-es/_freeGlobal.js
69
69
  var freeGlobal = typeof global == "object" && global && global.Object === Object && global;
@@ -3575,6 +3575,16 @@ var RegExpParser = class {
3575
3575
  case "!":
3576
3576
  type = "NegativeLookahead";
3577
3577
  break;
3578
+ case "<": {
3579
+ switch (this.popChar()) {
3580
+ case "=":
3581
+ type = "Lookbehind";
3582
+ break;
3583
+ case "!":
3584
+ type = "NegativeLookbehind";
3585
+ }
3586
+ break;
3587
+ }
3578
3588
  }
3579
3589
  ASSERT_EXISTS(type);
3580
3590
  const disjunction = this.disjunction();
@@ -4066,9 +4076,9 @@ var RegExpParser = class {
4066
4076
  default:
4067
4077
  return false;
4068
4078
  }
4069
- // '(?=' or '(?!'
4079
+ // '(?=' or '(?!' or `(?<=` or `(?<!`
4070
4080
  case "(":
4071
- return this.peekChar(1) === "?" && (this.peekChar(2) === "=" || this.peekChar(2) === "!");
4081
+ return this.peekChar(1) === "?" && (this.peekChar(2) === "=" || this.peekChar(2) === "!" || this.peekChar(2) === "<" && (this.peekChar(3) === "=" || this.peekChar(3) === "!"));
4072
4082
  default:
4073
4083
  return false;
4074
4084
  }
@@ -4188,6 +4198,12 @@ var BaseRegExpVisitor = class {
4188
4198
  case "NegativeLookahead":
4189
4199
  this.visitNegativeLookahead(node);
4190
4200
  break;
4201
+ case "Lookbehind":
4202
+ this.visitLookbehind(node);
4203
+ break;
4204
+ case "NegativeLookbehind":
4205
+ this.visitNegativeLookbehind(node);
4206
+ break;
4191
4207
  case "Character":
4192
4208
  this.visitCharacter(node);
4193
4209
  break;
@@ -4227,6 +4243,10 @@ var BaseRegExpVisitor = class {
4227
4243
  }
4228
4244
  visitNegativeLookahead(node) {
4229
4245
  }
4246
+ visitLookbehind(node) {
4247
+ }
4248
+ visitNegativeLookbehind(node) {
4249
+ }
4230
4250
  // atoms
4231
4251
  visitCharacter(node) {
4232
4252
  }
@@ -4306,6 +4326,8 @@ function firstCharOptimizedIndices(ast, result, ignoreCase) {
4306
4326
  // assertions do not affect potential starting codes
4307
4327
  case "Lookahead":
4308
4328
  case "NegativeLookahead":
4329
+ case "Lookbehind":
4330
+ case "NegativeLookbehind":
4309
4331
  case "StartAnchor":
4310
4332
  case "WordBoundary":
4311
4333
  case "NonWordBoundary":
@@ -4428,6 +4450,12 @@ var CharCodeFinder = class extends BaseRegExpVisitor {
4428
4450
  case "NegativeLookahead":
4429
4451
  this.visitNegativeLookahead(node);
4430
4452
  return;
4453
+ case "Lookbehind":
4454
+ this.visitLookbehind(node);
4455
+ return;
4456
+ case "NegativeLookbehind":
4457
+ this.visitNegativeLookbehind(node);
4458
+ return;
4431
4459
  }
4432
4460
  super.visitChildren(node);
4433
4461
  }
@@ -4465,10 +4493,8 @@ function canMatchCharCode(charCodes, pattern) {
4465
4493
  var PATTERN = "PATTERN";
4466
4494
  var DEFAULT_MODE = "defaultMode";
4467
4495
  var MODES = "modes";
4468
- var SUPPORT_STICKY = typeof new RegExp("(?:)").sticky === "boolean";
4469
4496
  function analyzeTokenTypes(tokenTypes, options) {
4470
4497
  options = defaults_default(options, {
4471
- useSticky: SUPPORT_STICKY,
4472
4498
  debug: false,
4473
4499
  safeMode: false,
4474
4500
  positionTracking: "full",
@@ -4517,7 +4543,7 @@ function analyzeTokenTypes(tokenTypes, options) {
4517
4543
  ], regExpSource[1])) {
4518
4544
  return regExpSource[1];
4519
4545
  } else {
4520
- return options.useSticky ? addStickyFlag(currPattern) : addStartOfInput(currPattern);
4546
+ return addStickyFlag(currPattern);
4521
4547
  }
4522
4548
  } else if (isFunction_default(currPattern)) {
4523
4549
  hasCustom = true;
@@ -4531,7 +4557,7 @@ function analyzeTokenTypes(tokenTypes, options) {
4531
4557
  } else {
4532
4558
  const escapedRegExpString = currPattern.replace(/[\\^$.*+?()[\]{}|]/g, "\\$&");
4533
4559
  const wrappedRegExp = new RegExp(escapedRegExpString);
4534
- return options.useSticky ? addStickyFlag(wrappedRegExp) : addStartOfInput(wrappedRegExp);
4560
+ return addStickyFlag(wrappedRegExp);
4535
4561
  }
4536
4562
  } else {
4537
4563
  throw Error("non exhaustive match");
@@ -4883,24 +4909,27 @@ function findUnreachablePatterns(tokenTypes) {
4883
4909
  }
4884
4910
  return result;
4885
4911
  }, []);
4886
- forEach_default(tokenTypes, (tokType, testIdx) => {
4887
- forEach_default(canBeTested, ({ str, idx, tokenType }) => {
4888
- if (testIdx < idx && testTokenType(str, tokType.PATTERN)) {
4889
- const msg = `Token: ->${tokenType.name}<- can never be matched.
4890
- Because it appears AFTER the Token Type ->${tokType.name}<-in the lexer's definition.
4912
+ forEach_default(tokenTypes, (aTokType, aIdx) => {
4913
+ forEach_default(canBeTested, ({ str: bStr, idx: bIdx, tokenType: bTokType }) => {
4914
+ if (aIdx < bIdx && tryToMatchStrToPattern(bStr, aTokType.PATTERN)) {
4915
+ const msg = `Token: ->${bTokType.name}<- can never be matched.
4916
+ Because it appears AFTER the Token Type ->${aTokType.name}<-in the lexer's definition.
4891
4917
  See https://chevrotain.io/docs/guide/resolving_lexer_errors.html#UNREACHABLE`;
4892
4918
  errors.push({
4893
4919
  message: msg,
4894
4920
  type: LexerDefinitionErrorType.UNREACHABLE_PATTERN,
4895
- tokenTypes: [tokType, tokenType]
4921
+ tokenTypes: [aTokType, bTokType]
4896
4922
  });
4897
4923
  }
4898
4924
  });
4899
4925
  });
4900
4926
  return errors;
4901
4927
  }
4902
- function testTokenType(str, pattern) {
4928
+ function tryToMatchStrToPattern(str, pattern) {
4903
4929
  if (isRegExp_default(pattern)) {
4930
+ if (usesLookAheadOrBehind(pattern)) {
4931
+ return false;
4932
+ }
4904
4933
  const regExpArray = pattern.exec(str);
4905
4934
  return regExpArray !== null && regExpArray.index === 0;
4906
4935
  } else if (isFunction_default(pattern)) {
@@ -4931,9 +4960,8 @@ function noMetaChar(regExp) {
4931
4960
  ];
4932
4961
  return find_default(metaChars, (char) => regExp.source.indexOf(char) !== -1) === void 0;
4933
4962
  }
4934
- function addStartOfInput(pattern) {
4935
- const flags = pattern.ignoreCase ? "i" : "";
4936
- return new RegExp(`^(?:${pattern.source})`, flags);
4963
+ function usesLookAheadOrBehind(regExp) {
4964
+ return /(\(\?=)|(\(\?!)|(\(\?<=)|(\(\?<!)/.test(regExp.source);
4937
4965
  }
4938
4966
  function addStickyFlag(pattern) {
4939
4967
  const flags = pattern.ignoreCase ? "iy" : "y";
@@ -5252,7 +5280,7 @@ var defaultLexerErrorProvider = {
5252
5280
  buildUnableToPopLexerModeMessage(token) {
5253
5281
  return `Unable to pop Lexer Mode after encountering Token ->${token.image}<- The Mode Stack is empty`;
5254
5282
  },
5255
- buildUnexpectedCharactersMessage(fullText, startOffset, length, line, column) {
5283
+ buildUnexpectedCharactersMessage(fullText, startOffset, length, line, column, mode) {
5256
5284
  return `unexpected character: ->${fullText.charAt(startOffset)}<- at offset: ${startOffset}, skipped ${length} characters.`;
5257
5285
  }
5258
5286
  };
@@ -5415,13 +5443,6 @@ var Lexer = class {
5415
5443
  PRINT_WARNING(warningDescriptor.message);
5416
5444
  });
5417
5445
  this.TRACE_INIT("Choosing sub-methods implementations", () => {
5418
- if (SUPPORT_STICKY) {
5419
- this.chopInput = identity_default;
5420
- this.match = this.matchWithTest;
5421
- } else {
5422
- this.updateLastIndex = noop_default;
5423
- this.match = this.matchWithExec;
5424
- }
5425
5446
  if (hasOnlySingleMode) {
5426
5447
  this.handleModes = noop_default;
5427
5448
  }
@@ -5484,7 +5505,7 @@ var Lexer = class {
5484
5505
  // this method also used quite a bit of `!` none null assertions because it is too optimized
5485
5506
  // for `tsc` to always understand it is "safe"
5486
5507
  tokenizeInternal(text, initialMode) {
5487
- let i, j, k, matchAltImage, longerAlt, matchedImage, payload, altPayload, imageLength, group, tokType, newToken, errLength, droppedChar, msg, match;
5508
+ let i, j, k, matchAltImage, longerAlt, matchedImage, payload, altPayload, imageLength, group, tokType, newToken, errLength, msg, match;
5488
5509
  const orgText = text;
5489
5510
  const orgLength = orgText.length;
5490
5511
  let offset = 0;
@@ -5503,19 +5524,7 @@ var Lexer = class {
5503
5524
  const modeStack = [];
5504
5525
  const emptyArray = [];
5505
5526
  Object.freeze(emptyArray);
5506
- let getPossiblePatterns;
5507
- function getPossiblePatternsSlow() {
5508
- return patternIdxToConfig;
5509
- }
5510
- function getPossiblePatternsOptimized(charCode) {
5511
- const optimizedCharIdx = charCodeToOptimizedIndex(charCode);
5512
- const possiblePatterns = currCharCodeToPatternIdxToConfig[optimizedCharIdx];
5513
- if (possiblePatterns === void 0) {
5514
- return emptyArray;
5515
- } else {
5516
- return possiblePatterns;
5517
- }
5518
- }
5527
+ let isOptimizedMode = false;
5519
5528
  const pop_mode = (popToken) => {
5520
5529
  if (modeStack.length === 1 && // if we have both a POP_MODE and a PUSH_MODE this is in-fact a "transition"
5521
5530
  // So no error should occur.
@@ -5536,9 +5545,9 @@ var Lexer = class {
5536
5545
  currModePatternsLength = patternIdxToConfig.length;
5537
5546
  const modeCanBeOptimized = this.canModeBeOptimized[newMode] && this.config.safeMode === false;
5538
5547
  if (currCharCodeToPatternIdxToConfig && modeCanBeOptimized) {
5539
- getPossiblePatterns = getPossiblePatternsOptimized;
5548
+ isOptimizedMode = true;
5540
5549
  } else {
5541
- getPossiblePatterns = getPossiblePatternsSlow;
5550
+ isOptimizedMode = false;
5542
5551
  }
5543
5552
  }
5544
5553
  };
@@ -5550,9 +5559,9 @@ var Lexer = class {
5550
5559
  currModePatternsLength = patternIdxToConfig.length;
5551
5560
  const modeCanBeOptimized = this.canModeBeOptimized[newMode] && this.config.safeMode === false;
5552
5561
  if (currCharCodeToPatternIdxToConfig && modeCanBeOptimized) {
5553
- getPossiblePatterns = getPossiblePatternsOptimized;
5562
+ isOptimizedMode = true;
5554
5563
  } else {
5555
- getPossiblePatterns = getPossiblePatternsSlow;
5564
+ isOptimizedMode = false;
5556
5565
  }
5557
5566
  }
5558
5567
  push_mode.call(this, initialMode);
@@ -5560,8 +5569,16 @@ var Lexer = class {
5560
5569
  const recoveryEnabled = this.config.recoveryEnabled;
5561
5570
  while (offset < orgLength) {
5562
5571
  matchedImage = null;
5572
+ imageLength = -1;
5563
5573
  const nextCharCode = orgText.charCodeAt(offset);
5564
- const chosenPatternIdxToConfig = getPossiblePatterns(nextCharCode);
5574
+ let chosenPatternIdxToConfig;
5575
+ if (isOptimizedMode) {
5576
+ const optimizedCharIdx = charCodeToOptimizedIndex(nextCharCode);
5577
+ const possiblePatterns = currCharCodeToPatternIdxToConfig[optimizedCharIdx];
5578
+ chosenPatternIdxToConfig = possiblePatterns !== void 0 ? possiblePatterns : emptyArray;
5579
+ } else {
5580
+ chosenPatternIdxToConfig = patternIdxToConfig;
5581
+ }
5565
5582
  const chosenPatternsLength = chosenPatternIdxToConfig.length;
5566
5583
  for (i = 0; i < chosenPatternsLength; i++) {
5567
5584
  currConfig = chosenPatternIdxToConfig[i];
@@ -5570,12 +5587,14 @@ var Lexer = class {
5570
5587
  const singleCharCode = currConfig.short;
5571
5588
  if (singleCharCode !== false) {
5572
5589
  if (nextCharCode === singleCharCode) {
5590
+ imageLength = 1;
5573
5591
  matchedImage = currPattern;
5574
5592
  }
5575
5593
  } else if (currConfig.isCustom === true) {
5576
5594
  match = currPattern.exec(orgText, offset, matchedTokens, groups);
5577
5595
  if (match !== null) {
5578
5596
  matchedImage = match[0];
5597
+ imageLength = matchedImage.length;
5579
5598
  if (match.payload !== void 0) {
5580
5599
  payload = match.payload;
5581
5600
  }
@@ -5583,12 +5602,13 @@ var Lexer = class {
5583
5602
  matchedImage = null;
5584
5603
  }
5585
5604
  } else {
5586
- this.updateLastIndex(currPattern, offset);
5587
- matchedImage = this.match(currPattern, text, offset);
5605
+ currPattern.lastIndex = offset;
5606
+ imageLength = this.matchLength(currPattern, text, offset);
5588
5607
  }
5589
- if (matchedImage !== null) {
5608
+ if (imageLength !== -1) {
5590
5609
  longerAlt = currConfig.longerAlt;
5591
5610
  if (longerAlt !== void 0) {
5611
+ matchedImage = text.substring(offset, offset + imageLength);
5592
5612
  const longerAltLength = longerAlt.length;
5593
5613
  for (k = 0; k < longerAltLength; k++) {
5594
5614
  const longerAltConfig = patternIdxToConfig[longerAlt[k]];
@@ -5605,11 +5625,12 @@ var Lexer = class {
5605
5625
  matchAltImage = null;
5606
5626
  }
5607
5627
  } else {
5608
- this.updateLastIndex(longerAltPattern, offset);
5628
+ longerAltPattern.lastIndex = offset;
5609
5629
  matchAltImage = this.match(longerAltPattern, text, offset);
5610
5630
  }
5611
5631
  if (matchAltImage && matchAltImage.length > matchedImage.length) {
5612
5632
  matchedImage = matchAltImage;
5633
+ imageLength = matchAltImage.length;
5613
5634
  payload = altPayload;
5614
5635
  currConfig = longerAltConfig;
5615
5636
  break;
@@ -5619,10 +5640,10 @@ var Lexer = class {
5619
5640
  break;
5620
5641
  }
5621
5642
  }
5622
- if (matchedImage !== null) {
5623
- imageLength = matchedImage.length;
5643
+ if (imageLength !== -1) {
5624
5644
  group = currConfig.group;
5625
5645
  if (group !== void 0) {
5646
+ matchedImage = matchedImage !== null ? matchedImage : text.substring(offset, offset + imageLength);
5626
5647
  tokType = currConfig.tokenTypeIdx;
5627
5648
  newToken = this.createTokenInstance(matchedImage, offset, tokType, currConfig.tokenType, line, column, imageLength);
5628
5649
  this.handlePayload(newToken, payload);
@@ -5632,15 +5653,13 @@ var Lexer = class {
5632
5653
  groups[group].push(newToken);
5633
5654
  }
5634
5655
  }
5635
- text = this.chopInput(text, imageLength);
5636
- offset = offset + imageLength;
5637
- column = this.computeNewColumn(column, imageLength);
5638
5656
  if (trackLines === true && currConfig.canLineTerminator === true) {
5639
5657
  let numOfLTsInMatch = 0;
5640
5658
  let foundTerminator;
5641
5659
  let lastLTEndOffset;
5642
5660
  lineTerminatorPattern.lastIndex = 0;
5643
5661
  do {
5662
+ matchedImage = matchedImage !== null ? matchedImage : text.substring(offset, offset + imageLength);
5644
5663
  foundTerminator = lineTerminatorPattern.test(matchedImage);
5645
5664
  if (foundTerminator === true) {
5646
5665
  lastLTEndOffset = lineTerminatorPattern.lastIndex - 1;
@@ -5651,8 +5670,13 @@ var Lexer = class {
5651
5670
  line = line + numOfLTsInMatch;
5652
5671
  column = imageLength - lastLTEndOffset;
5653
5672
  this.updateTokenEndLineColumnLocation(newToken, group, lastLTEndOffset, numOfLTsInMatch, line, column, imageLength);
5673
+ } else {
5674
+ column = this.computeNewColumn(column, imageLength);
5654
5675
  }
5676
+ } else {
5677
+ column = this.computeNewColumn(column, imageLength);
5655
5678
  }
5679
+ offset = offset + imageLength;
5656
5680
  this.handleModes(currConfig, pop_mode, push_mode, newToken);
5657
5681
  } else {
5658
5682
  const errorStartOffset = offset;
@@ -5660,7 +5684,6 @@ var Lexer = class {
5660
5684
  const errorColumn = column;
5661
5685
  let foundResyncPoint = recoveryEnabled === false;
5662
5686
  while (foundResyncPoint === false && offset < orgLength) {
5663
- text = this.chopInput(text, 1);
5664
5687
  offset++;
5665
5688
  for (j = 0; j < currModePatternsLength; j++) {
5666
5689
  const currConfig2 = patternIdxToConfig[j];
@@ -5673,7 +5696,7 @@ var Lexer = class {
5673
5696
  } else if (currConfig2.isCustom === true) {
5674
5697
  foundResyncPoint = currPattern.exec(orgText, offset, matchedTokens, groups) !== null;
5675
5698
  } else {
5676
- this.updateLastIndex(currPattern, offset);
5699
+ currPattern.lastIndex = offset;
5677
5700
  foundResyncPoint = currPattern.exec(text) !== null;
5678
5701
  }
5679
5702
  if (foundResyncPoint === true) {
@@ -5683,7 +5706,7 @@ var Lexer = class {
5683
5706
  }
5684
5707
  errLength = offset - errorStartOffset;
5685
5708
  column = this.computeNewColumn(column, errLength);
5686
- msg = this.config.errorMessageProvider.buildUnexpectedCharactersMessage(orgText, errorStartOffset, errLength, errorLine, errorColumn);
5709
+ msg = this.config.errorMessageProvider.buildUnexpectedCharactersMessage(orgText, errorStartOffset, errLength, errorLine, errorColumn, last_default(modeStack));
5687
5710
  errors.push({
5688
5711
  offset: errorStartOffset,
5689
5712
  line: errorLine,
@@ -5716,12 +5739,6 @@ var Lexer = class {
5716
5739
  push_mode.call(this, config.push);
5717
5740
  }
5718
5741
  }
5719
- chopInput(text, length) {
5720
- return text.substring(length);
5721
- }
5722
- updateLastIndex(regExp, newLastIndex) {
5723
- regExp.lastIndex = newLastIndex;
5724
- }
5725
5742
  // TODO: decrease this under 600 characters? inspect stripping comments option in TSC compiler
5726
5743
  updateTokenEndLineColumnLocation(newToken, group, lastLTIdx, numOfLTsInMatch, line, column, imageLength) {
5727
5744
  let lastCharIsLT, fixForEndingInLT;
@@ -5784,19 +5801,22 @@ var Lexer = class {
5784
5801
  token.payload = payload;
5785
5802
  }
5786
5803
  }
5787
- matchWithTest(pattern, text, offset) {
5804
+ match(pattern, text, offset) {
5788
5805
  const found = pattern.test(text);
5789
5806
  if (found === true) {
5790
5807
  return text.substring(offset, pattern.lastIndex);
5791
5808
  }
5792
5809
  return null;
5793
5810
  }
5794
- matchWithExec(pattern, text) {
5795
- const regExpArray = pattern.exec(text);
5796
- return regExpArray !== null ? regExpArray[0] : null;
5811
+ matchLength(pattern, text, offset) {
5812
+ const found = pattern.test(text);
5813
+ if (found === true) {
5814
+ return pattern.lastIndex - offset;
5815
+ }
5816
+ return -1;
5797
5817
  }
5798
5818
  };
5799
- Lexer.SKIPPED = "This marks a skipped Token pattern, this means each token identified by it willbe consumed and then thrown into oblivion, this can be used to for example to completely ignore whitespace.";
5819
+ Lexer.SKIPPED = "This marks a skipped Token pattern, this means each token identified by it will be consumed and then thrown into oblivion, this can be used to for example to completely ignore whitespace.";
5800
5820
  Lexer.NA = /NOT_APPLICABLE/;
5801
5821
 
5802
5822
  // ../../node_modules/chevrotain/lib/src/scan/tokens_public.js
@@ -5972,12 +5992,20 @@ For Further details.`;
5972
5992
  return errMsg;
5973
5993
  },
5974
5994
  buildAlternationAmbiguityError(options) {
5975
- const pathMsg = map_default(options.prefixPath, (currtok) => tokenLabel2(currtok)).join(", ");
5976
5995
  const occurrence = options.alternation.idx === 0 ? "" : options.alternation.idx;
5996
+ const isEmptyPath = options.prefixPath.length === 0;
5977
5997
  let currMessage = `Ambiguous Alternatives Detected: <${options.ambiguityIndices.join(" ,")}> in <OR${occurrence}> inside <${options.topLevelRule.name}> Rule,
5978
- <${pathMsg}> may appears as a prefix path in all these alternatives.
5979
5998
  `;
5980
- currMessage = currMessage + `See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#AMBIGUOUS_ALTERNATIVES
5999
+ if (isEmptyPath) {
6000
+ currMessage += `These alternatives are all empty (match no tokens), making them indistinguishable.
6001
+ Only the last alternative may be empty.
6002
+ `;
6003
+ } else {
6004
+ const pathMsg = map_default(options.prefixPath, (currtok) => tokenLabel2(currtok)).join(", ");
6005
+ currMessage += `<${pathMsg}> may appears as a prefix path in all these alternatives.
6006
+ `;
6007
+ }
6008
+ currMessage += `See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#AMBIGUOUS_ALTERNATIVES
5981
6009
  For Further details.`;
5982
6010
  return currMessage;
5983
6011
  },
@@ -6548,7 +6576,7 @@ function buildAlternativesLookAheadFunc(alts, hasPredicates, tokenMatcher2, dyna
6548
6576
  const currPath = currAlt[j];
6549
6577
  const currPathLength = currPath.length;
6550
6578
  for (let i = 0; i < currPathLength; i++) {
6551
- const nextToken = this.LA(i + 1);
6579
+ const nextToken = this.LA_FAST(i + 1);
6552
6580
  if (tokenMatcher2(nextToken, currPath[i]) === false) {
6553
6581
  continue nextPath;
6554
6582
  }
@@ -6576,7 +6604,7 @@ function buildAlternativesLookAheadFunc(alts, hasPredicates, tokenMatcher2, dyna
6576
6604
  return result;
6577
6605
  }, {});
6578
6606
  return function() {
6579
- const nextToken = this.LA(1);
6607
+ const nextToken = this.LA_FAST(1);
6580
6608
  return choiceToAlt[nextToken.tokenTypeIdx];
6581
6609
  };
6582
6610
  } else {
@@ -6588,7 +6616,7 @@ function buildAlternativesLookAheadFunc(alts, hasPredicates, tokenMatcher2, dyna
6588
6616
  const currPath = currAlt[j];
6589
6617
  const currPathLength = currPath.length;
6590
6618
  for (let i = 0; i < currPathLength; i++) {
6591
- const nextToken = this.LA(i + 1);
6619
+ const nextToken = this.LA_FAST(i + 1);
6592
6620
  if (tokenMatcher2(nextToken, currPath[i]) === false) {
6593
6621
  continue nextPath;
6594
6622
  }
@@ -6611,7 +6639,7 @@ function buildSingleAlternativeLookaheadFunction(alt, tokenMatcher2, dynamicToke
6611
6639
  const expectedTokenType = singleTokensTypes[0];
6612
6640
  const expectedTokenUniqueKey = expectedTokenType.tokenTypeIdx;
6613
6641
  return function() {
6614
- return this.LA(1).tokenTypeIdx === expectedTokenUniqueKey;
6642
+ return this.LA_FAST(1).tokenTypeIdx === expectedTokenUniqueKey;
6615
6643
  };
6616
6644
  } else {
6617
6645
  const choiceToAlt = reduce_default(singleTokensTypes, (result, currTokType, idx) => {
@@ -6622,7 +6650,7 @@ function buildSingleAlternativeLookaheadFunction(alt, tokenMatcher2, dynamicToke
6622
6650
  return result;
6623
6651
  }, []);
6624
6652
  return function() {
6625
- const nextToken = this.LA(1);
6653
+ const nextToken = this.LA_FAST(1);
6626
6654
  return choiceToAlt[nextToken.tokenTypeIdx] === true;
6627
6655
  };
6628
6656
  }
@@ -6632,7 +6660,7 @@ function buildSingleAlternativeLookaheadFunction(alt, tokenMatcher2, dynamicToke
6632
6660
  const currPath = alt[j];
6633
6661
  const currPathLength = currPath.length;
6634
6662
  for (let i = 0; i < currPathLength; i++) {
6635
- const nextToken = this.LA(i + 1);
6663
+ const nextToken = this.LA_FAST(i + 1);
6636
6664
  if (tokenMatcher2(nextToken, currPath[i]) === false) {
6637
6665
  continue nextPath;
6638
6666
  }
@@ -7349,8 +7377,8 @@ var Recoverable = class {
7349
7377
  const savedLexerState = this.exportLexerState();
7350
7378
  const resyncedTokens = [];
7351
7379
  let passedResyncPoint = false;
7352
- const nextTokenWithoutResync = this.LA(1);
7353
- let currToken = this.LA(1);
7380
+ const nextTokenWithoutResync = this.LA_FAST(1);
7381
+ let currToken = this.LA_FAST(1);
7354
7382
  const generateErrorMessage = () => {
7355
7383
  const previousToken = this.LA(0);
7356
7384
  const msg = this.errorMessageProvider.buildMismatchTokenMessage({
@@ -7384,7 +7412,7 @@ var Recoverable = class {
7384
7412
  if (notStuck === false) {
7385
7413
  return false;
7386
7414
  }
7387
- if (this.tokenMatcher(this.LA(1), expectTokAfterLastMatch)) {
7415
+ if (this.tokenMatcher(this.LA_FAST(1), expectTokAfterLastMatch)) {
7388
7416
  return false;
7389
7417
  }
7390
7418
  if (this.isBackTracking()) {
@@ -7423,7 +7451,7 @@ var Recoverable = class {
7423
7451
  if (isEmpty_default(follows)) {
7424
7452
  return false;
7425
7453
  }
7426
- const mismatchedTok = this.LA(1);
7454
+ const mismatchedTok = this.LA_FAST(1);
7427
7455
  const isMisMatchedTokInFollows = find_default(follows, (possibleFollowsTokType) => {
7428
7456
  return this.tokenMatcher(mismatchedTok, possibleFollowsTokType);
7429
7457
  }) !== void 0;
@@ -7433,7 +7461,12 @@ var Recoverable = class {
7433
7461
  if (!this.canTokenTypeBeDeletedInRecovery(expectedTokType)) {
7434
7462
  return false;
7435
7463
  }
7436
- const isNextTokenWhatIsExpected = this.tokenMatcher(this.LA(2), expectedTokType);
7464
+ const isNextTokenWhatIsExpected = this.tokenMatcher(
7465
+ // not using LA_FAST because LA(2) might be un-safe with maxLookahead=1
7466
+ // in some edge cases (?)
7467
+ this.LA(2),
7468
+ expectedTokType
7469
+ );
7437
7470
  return isNextTokenWhatIsExpected;
7438
7471
  }
7439
7472
  isInCurrentRuleReSyncSet(tokenTypeIdx) {
@@ -7443,7 +7476,7 @@ var Recoverable = class {
7443
7476
  }
7444
7477
  findReSyncTokenType() {
7445
7478
  const allPossibleReSyncTokTypes = this.flattenFollowSet();
7446
- let nextToken = this.LA(1);
7479
+ let nextToken = this.LA_FAST(1);
7447
7480
  let k = 2;
7448
7481
  while (true) {
7449
7482
  const foundMatch = find_default(allPossibleReSyncTokTypes, (resyncTokType) => {
@@ -7458,10 +7491,10 @@ var Recoverable = class {
7458
7491
  }
7459
7492
  }
7460
7493
  getCurrFollowKey() {
7461
- if (this.RULE_STACK.length === 1) {
7494
+ if (this.RULE_STACK_IDX === 0) {
7462
7495
  return EOF_FOLLOW_KEY;
7463
7496
  }
7464
- const currRuleShortName = this.getLastExplicitRuleShortName();
7497
+ const currRuleShortName = this.currRuleShortName;
7465
7498
  const currRuleIdx = this.getLastExplicitRuleOccurrenceIndex();
7466
7499
  const prevRuleShortName = this.getPreviousExplicitRuleShortName();
7467
7500
  return {
@@ -7473,16 +7506,20 @@ var Recoverable = class {
7473
7506
  buildFullFollowKeyStack() {
7474
7507
  const explicitRuleStack = this.RULE_STACK;
7475
7508
  const explicitOccurrenceStack = this.RULE_OCCURRENCE_STACK;
7476
- return map_default(explicitRuleStack, (ruleName, idx) => {
7509
+ const len = this.RULE_STACK_IDX + 1;
7510
+ const result = new Array(len);
7511
+ for (let idx = 0; idx < len; idx++) {
7477
7512
  if (idx === 0) {
7478
- return EOF_FOLLOW_KEY;
7513
+ result[idx] = EOF_FOLLOW_KEY;
7514
+ } else {
7515
+ result[idx] = {
7516
+ ruleName: this.shortRuleNameToFullName(explicitRuleStack[idx]),
7517
+ idxInCallingRule: explicitOccurrenceStack[idx],
7518
+ inRule: this.shortRuleNameToFullName(explicitRuleStack[idx - 1])
7519
+ };
7479
7520
  }
7480
- return {
7481
- ruleName: this.shortRuleNameToFullName(ruleName),
7482
- idxInCallingRule: explicitOccurrenceStack[idx],
7483
- inRule: this.shortRuleNameToFullName(explicitRuleStack[idx - 1])
7484
- };
7485
- });
7521
+ }
7522
+ return result;
7486
7523
  }
7487
7524
  flattenFollowSet() {
7488
7525
  const followStack = map_default(this.buildFullFollowKeyStack(), (currKey) => {
@@ -7507,7 +7544,7 @@ var Recoverable = class {
7507
7544
  }
7508
7545
  reSyncTo(tokType) {
7509
7546
  const resyncedTokens = [];
7510
- let nextTok = this.LA(1);
7547
+ let nextTok = this.LA_FAST(1);
7511
7548
  while (this.tokenMatcher(nextTok, tokType) === false) {
7512
7549
  nextTok = this.SKIP_TOKEN();
7513
7550
  this.addToResyncTokens(nextTok, resyncedTokens);
@@ -7518,7 +7555,7 @@ var Recoverable = class {
7518
7555
  }
7519
7556
  getCurrentGrammarPath(tokType, tokIdxInRule) {
7520
7557
  const pathRuleStack = this.getHumanReadableRuleStack();
7521
- const pathOccurrenceStack = clone_default(this.RULE_OCCURRENCE_STACK);
7558
+ const pathOccurrenceStack = this.RULE_OCCURRENCE_STACK.slice(0, this.RULE_OCCURRENCE_STACK_IDX + 1);
7522
7559
  const grammarPath = {
7523
7560
  ruleStack: pathRuleStack,
7524
7561
  occurrenceStack: pathOccurrenceStack,
@@ -7528,7 +7565,12 @@ var Recoverable = class {
7528
7565
  return grammarPath;
7529
7566
  }
7530
7567
  getHumanReadableRuleStack() {
7531
- return map_default(this.RULE_STACK, (currShortName) => this.shortRuleNameToFullName(currShortName));
7568
+ const len = this.RULE_STACK_IDX + 1;
7569
+ const result = new Array(len);
7570
+ for (let i = 0; i < len; i++) {
7571
+ result[i] = this.shortRuleNameToFullName(this.RULE_STACK[i]);
7572
+ }
7573
+ return result;
7532
7574
  }
7533
7575
  };
7534
7576
  function attemptInRepetitionRecovery(prodFunc, args, lookaheadFunc, dslMethodIdx, prodOccurrence, nextToksWalker, notStuck) {
@@ -7544,7 +7586,7 @@ function attemptInRepetitionRecovery(prodFunc, args, lookaheadFunc, dslMethodIdx
7544
7586
  let expectTokAfterLastMatch = firstAfterRepInfo.token;
7545
7587
  let nextTokIdx = firstAfterRepInfo.occurrence;
7546
7588
  const isEndOfRule = firstAfterRepInfo.isEndOfRule;
7547
- if (this.RULE_STACK.length === 1 && isEndOfRule && expectTokAfterLastMatch === void 0) {
7589
+ if (this.RULE_STACK_IDX === 0 && isEndOfRule && expectTokAfterLastMatch === void 0) {
7548
7590
  expectTokAfterLastMatch = EOF;
7549
7591
  nextTokIdx = 1;
7550
7592
  }
@@ -7672,8 +7714,7 @@ var LooksAhead = class {
7672
7714
  }
7673
7715
  // this actually returns a number, but it is always used as a string (object prop key)
7674
7716
  getKeyForAutomaticLookahead(dslMethodIdx, occurrence) {
7675
- const currRuleShortName = this.getLastExplicitRuleShortName();
7676
- return getKeyForAutomaticLookahead(currRuleShortName, dslMethodIdx, occurrence);
7717
+ return getKeyForAutomaticLookahead(this.currRuleShortName, dslMethodIdx, occurrence);
7677
7718
  }
7678
7719
  getLaFuncFromCache(key) {
7679
7720
  return this.lookAheadFuncsCache.get(key);
@@ -7920,7 +7961,7 @@ var TreeBuilder = class {
7920
7961
  // To be the next Token's startOffset (for valid inputs).
7921
7962
  // For invalid inputs there won't be any CSTOutput so this potential
7922
7963
  // inaccuracy does not matter
7923
- startOffset: this.LA(1).startOffset,
7964
+ startOffset: this.LA_FAST(1).startOffset,
7924
7965
  endOffset: NaN
7925
7966
  };
7926
7967
  }
@@ -7940,7 +7981,7 @@ var TreeBuilder = class {
7940
7981
  * @param cstNode
7941
7982
  */
7942
7983
  setInitialNodeLocationFullRegular(cstNode) {
7943
- const nextToken = this.LA(1);
7984
+ const nextToken = this.LA_FAST(1);
7944
7985
  cstNode.location = {
7945
7986
  startOffset: nextToken.startOffset,
7946
7987
  startLine: nextToken.startLine,
@@ -8009,17 +8050,11 @@ var TreeBuilder = class {
8009
8050
  }
8010
8051
  return this.baseCstVisitorWithDefaultsConstructor;
8011
8052
  }
8012
- getLastExplicitRuleShortName() {
8013
- const ruleStack = this.RULE_STACK;
8014
- return ruleStack[ruleStack.length - 1];
8015
- }
8016
8053
  getPreviousExplicitRuleShortName() {
8017
- const ruleStack = this.RULE_STACK;
8018
- return ruleStack[ruleStack.length - 2];
8054
+ return this.RULE_STACK[this.RULE_STACK_IDX - 1];
8019
8055
  }
8020
8056
  getLastExplicitRuleOccurrenceIndex() {
8021
- const occurrenceStack = this.RULE_OCCURRENCE_STACK;
8022
- return occurrenceStack[occurrenceStack.length - 1];
8057
+ return this.RULE_OCCURRENCE_STACK[this.RULE_OCCURRENCE_STACK_IDX];
8023
8058
  }
8024
8059
  };
8025
8060
 
@@ -8043,15 +8078,22 @@ var LexerAdapter = class {
8043
8078
  }
8044
8079
  // skips a token and returns the next token
8045
8080
  SKIP_TOKEN() {
8046
- if (this.currIdx <= this.tokVector.length - 2) {
8081
+ if (this.currIdx <= this.tokVectorLength - 2) {
8047
8082
  this.consumeToken();
8048
- return this.LA(1);
8083
+ return this.LA_FAST(1);
8049
8084
  } else {
8050
8085
  return END_OF_FILE;
8051
8086
  }
8052
8087
  }
8053
8088
  // Lexer (accessing Token vector) related methods which can be overridden to implement lazy lexers
8054
8089
  // or lexers dependent on parser context.
8090
+ // Performance Optimized version of LA without bound checks
8091
+ // note that token beyond the end of the token vector EOF Token will still be returned
8092
+ // due to using sentinels at the end of the token vector. (for K=max lookahead)
8093
+ LA_FAST(howMuch) {
8094
+ const soughtIdx = this.currIdx + howMuch;
8095
+ return this.tokVector[soughtIdx];
8096
+ }
8055
8097
  LA(howMuch) {
8056
8098
  const soughtIdx = this.currIdx + howMuch;
8057
8099
  if (soughtIdx < 0 || this.tokVectorLength <= soughtIdx) {
@@ -8073,7 +8115,7 @@ var LexerAdapter = class {
8073
8115
  this.currIdx = -1;
8074
8116
  }
8075
8117
  moveToTerminatedState() {
8076
- this.currIdx = this.tokVector.length - 1;
8118
+ this.currIdx = this.tokVectorLength - 1;
8077
8119
  }
8078
8120
  getLexerPosition() {
8079
8121
  return this.exportLexerState();
@@ -8369,11 +8411,13 @@ var RecognizerApi = class {
8369
8411
  return ruleImplementation;
8370
8412
  }
8371
8413
  BACKTRACK(grammarRule, args) {
8414
+ var _a;
8415
+ const ruleToCall = (_a = grammarRule.coreRule) !== null && _a !== void 0 ? _a : grammarRule;
8372
8416
  return function() {
8373
8417
  this.isBackTrackingStack.push(1);
8374
8418
  const orgState = this.saveRecogState();
8375
8419
  try {
8376
- grammarRule.apply(this, args);
8420
+ ruleToCall.apply(this, args);
8377
8421
  return true;
8378
8422
  } catch (e) {
8379
8423
  if (isRecognitionException(e)) {
@@ -8405,11 +8449,14 @@ var RecognizerEngine = class {
8405
8449
  this.ruleShortNameIdx = 256;
8406
8450
  this.tokenMatcher = tokenStructuredMatcherNoCategories;
8407
8451
  this.subruleIdx = 0;
8452
+ this.currRuleShortName = 0;
8408
8453
  this.definedRulesNames = [];
8409
8454
  this.tokensMap = {};
8410
8455
  this.isBackTrackingStack = [];
8411
8456
  this.RULE_STACK = [];
8457
+ this.RULE_STACK_IDX = -1;
8412
8458
  this.RULE_OCCURRENCE_STACK = [];
8459
+ this.RULE_OCCURRENCE_STACK_IDX = -1;
8413
8460
  this.gastProductionsCache = {};
8414
8461
  if (has_default(config, "serializedGrammar")) {
8415
8462
  throw Error("The Parser's configuration can no longer contain a <serializedGrammar> property.\n See: https://chevrotain.io/docs/changes/BREAKING_CHANGES.html#_6-0-0\n For Further details.");
@@ -8456,9 +8503,9 @@ Make sure that all grammar rule definitions are done before 'performSelfAnalysis
8456
8503
  this.ruleShortNameIdx++;
8457
8504
  this.shortRuleNameToFull[shortName] = ruleName;
8458
8505
  this.fullRuleNameToShort[ruleName] = shortName;
8459
- let invokeRuleWithTry;
8506
+ let coreRuleFunction;
8460
8507
  if (this.outputCst === true) {
8461
- invokeRuleWithTry = function invokeRuleWithTry2(...args) {
8508
+ coreRuleFunction = function invokeRuleWithTry(...args) {
8462
8509
  try {
8463
8510
  this.ruleInvocationStateUpdate(shortName, ruleName, this.subruleIdx);
8464
8511
  impl.apply(this, args);
@@ -8472,7 +8519,7 @@ Make sure that all grammar rule definitions are done before 'performSelfAnalysis
8472
8519
  }
8473
8520
  };
8474
8521
  } else {
8475
- invokeRuleWithTry = function invokeRuleWithTryCst(...args) {
8522
+ coreRuleFunction = function invokeRuleWithTryCst(...args) {
8476
8523
  try {
8477
8524
  this.ruleInvocationStateUpdate(shortName, ruleName, this.subruleIdx);
8478
8525
  return impl.apply(this, args);
@@ -8483,11 +8530,19 @@ Make sure that all grammar rule definitions are done before 'performSelfAnalysis
8483
8530
  }
8484
8531
  };
8485
8532
  }
8486
- const wrappedGrammarRule = Object.assign(invokeRuleWithTry, { ruleName, originalGrammarAction: impl });
8533
+ const rootRuleFunction = function rootRule(...args) {
8534
+ this.onBeforeParse(ruleName);
8535
+ try {
8536
+ return coreRuleFunction.apply(this, args);
8537
+ } finally {
8538
+ this.onAfterParse(ruleName);
8539
+ }
8540
+ };
8541
+ const wrappedGrammarRule = Object.assign(rootRuleFunction, { ruleName, originalGrammarAction: impl, coreRule: coreRuleFunction });
8487
8542
  return wrappedGrammarRule;
8488
8543
  }
8489
8544
  invokeRuleCatch(e, resyncEnabledConfig, recoveryValueFunc) {
8490
- const isFirstInvokedRule = this.RULE_STACK.length === 1;
8545
+ const isFirstInvokedRule = this.RULE_STACK_IDX === 0;
8491
8546
  const reSyncEnabled = resyncEnabledConfig && !this.isBackTracking() && this.recoveryEnabled;
8492
8547
  if (isRecognitionException(e)) {
8493
8548
  const recogError = e;
@@ -8585,9 +8640,9 @@ Make sure that all grammar rule definitions are done before 'performSelfAnalysis
8585
8640
  if (firstIterationLookaheadFunc.call(this) === true) {
8586
8641
  action.call(this);
8587
8642
  const separatorLookAheadFunc = () => {
8588
- return this.tokenMatcher(this.LA(1), separator);
8643
+ return this.tokenMatcher(this.LA_FAST(1), separator);
8589
8644
  };
8590
- while (this.tokenMatcher(this.LA(1), separator) === true) {
8645
+ while (this.tokenMatcher(this.LA_FAST(1), separator) === true) {
8591
8646
  this.CONSUME(separator);
8592
8647
  action.call(this);
8593
8648
  }
@@ -8651,9 +8706,9 @@ Make sure that all grammar rule definitions are done before 'performSelfAnalysis
8651
8706
  if (firstIterationLaFunc.call(this) === true) {
8652
8707
  action.call(this);
8653
8708
  const separatorLookAheadFunc = () => {
8654
- return this.tokenMatcher(this.LA(1), separator);
8709
+ return this.tokenMatcher(this.LA_FAST(1), separator);
8655
8710
  };
8656
- while (this.tokenMatcher(this.LA(1), separator) === true) {
8711
+ while (this.tokenMatcher(this.LA_FAST(1), separator) === true) {
8657
8712
  this.CONSUME(separator);
8658
8713
  action.call(this);
8659
8714
  }
@@ -8697,24 +8752,19 @@ Make sure that all grammar rule definitions are done before 'performSelfAnalysis
8697
8752
  this.raiseNoAltException(occurrence, altsOrOpts.ERR_MSG);
8698
8753
  }
8699
8754
  ruleFinallyStateUpdate() {
8700
- this.RULE_STACK.pop();
8701
- this.RULE_OCCURRENCE_STACK.pop();
8702
- this.cstFinallyStateUpdate();
8703
- if (this.RULE_STACK.length === 0 && this.isAtEndOfInput() === false) {
8704
- const firstRedundantTok = this.LA(1);
8705
- const errMsg = this.errorMessageProvider.buildNotAllInputParsedMessage({
8706
- firstRedundant: firstRedundantTok,
8707
- ruleName: this.getCurrRuleFullName()
8708
- });
8709
- this.SAVE_ERROR(new NotAllInputParsedException(errMsg, firstRedundantTok));
8755
+ this.RULE_STACK_IDX--;
8756
+ this.RULE_OCCURRENCE_STACK_IDX--;
8757
+ if (this.RULE_STACK_IDX >= 0) {
8758
+ this.currRuleShortName = this.RULE_STACK[this.RULE_STACK_IDX];
8710
8759
  }
8760
+ this.cstFinallyStateUpdate();
8711
8761
  }
8712
8762
  subruleInternal(ruleToCall, idx, options) {
8713
8763
  let ruleResult;
8714
8764
  try {
8715
8765
  const args = options !== void 0 ? options.ARGS : void 0;
8716
8766
  this.subruleIdx = idx;
8717
- ruleResult = ruleToCall.apply(this, args);
8767
+ ruleResult = ruleToCall.coreRule.apply(this, args);
8718
8768
  this.cstPostNonTerminal(ruleResult, options !== void 0 && options.LABEL !== void 0 ? options.LABEL : ruleToCall.ruleName);
8719
8769
  return ruleResult;
8720
8770
  } catch (e) {
@@ -8731,7 +8781,7 @@ Make sure that all grammar rule definitions are done before 'performSelfAnalysis
8731
8781
  consumeInternal(tokType, idx, options) {
8732
8782
  let consumedToken;
8733
8783
  try {
8734
- const nextToken = this.LA(1);
8784
+ const nextToken = this.LA_FAST(1);
8735
8785
  if (this.tokenMatcher(nextToken, tokType) === true) {
8736
8786
  this.consumeToken();
8737
8787
  consumedToken = nextToken;
@@ -8778,7 +8828,7 @@ Make sure that all grammar rule definitions are done before 'performSelfAnalysis
8778
8828
  }
8779
8829
  saveRecogState() {
8780
8830
  const savedErrors = this.errors;
8781
- const savedRuleStack = clone_default(this.RULE_STACK);
8831
+ const savedRuleStack = this.RULE_STACK.slice(0, this.RULE_STACK_IDX + 1);
8782
8832
  return {
8783
8833
  errors: savedErrors,
8784
8834
  lexerState: this.exportLexerState(),
@@ -8789,18 +8839,26 @@ Make sure that all grammar rule definitions are done before 'performSelfAnalysis
8789
8839
  reloadRecogState(newState) {
8790
8840
  this.errors = newState.errors;
8791
8841
  this.importLexerState(newState.lexerState);
8792
- this.RULE_STACK = newState.RULE_STACK;
8842
+ const saved = newState.RULE_STACK;
8843
+ for (let i = 0; i < saved.length; i++) {
8844
+ this.RULE_STACK[i] = saved[i];
8845
+ }
8846
+ this.RULE_STACK_IDX = saved.length - 1;
8847
+ if (this.RULE_STACK_IDX >= 0) {
8848
+ this.currRuleShortName = this.RULE_STACK[this.RULE_STACK_IDX];
8849
+ }
8793
8850
  }
8794
8851
  ruleInvocationStateUpdate(shortName, fullName, idxInCallingRule) {
8795
- this.RULE_OCCURRENCE_STACK.push(idxInCallingRule);
8796
- this.RULE_STACK.push(shortName);
8852
+ this.RULE_OCCURRENCE_STACK[++this.RULE_OCCURRENCE_STACK_IDX] = idxInCallingRule;
8853
+ this.RULE_STACK[++this.RULE_STACK_IDX] = shortName;
8854
+ this.currRuleShortName = shortName;
8797
8855
  this.cstInvocationStateUpdate(fullName);
8798
8856
  }
8799
8857
  isBackTracking() {
8800
8858
  return this.isBackTrackingStack.length !== 0;
8801
8859
  }
8802
8860
  getCurrRuleFullName() {
8803
- const shortName = this.getLastExplicitRuleShortName();
8861
+ const shortName = this.currRuleShortName;
8804
8862
  return this.shortRuleNameToFull[shortName];
8805
8863
  }
8806
8864
  shortRuleNameToFullName(shortName) {
@@ -8812,11 +8870,53 @@ Make sure that all grammar rule definitions are done before 'performSelfAnalysis
8812
8870
  reset() {
8813
8871
  this.resetLexerState();
8814
8872
  this.subruleIdx = 0;
8873
+ this.currRuleShortName = 0;
8815
8874
  this.isBackTrackingStack = [];
8816
8875
  this.errors = [];
8817
- this.RULE_STACK = [];
8876
+ this.RULE_STACK_IDX = -1;
8877
+ this.RULE_OCCURRENCE_STACK_IDX = -1;
8818
8878
  this.CST_STACK = [];
8819
- this.RULE_OCCURRENCE_STACK = [];
8879
+ }
8880
+ /**
8881
+ * Hook called before the root-level parsing rule is invoked.
8882
+ * This is only called when a rule is invoked directly by the consumer
8883
+ * (e.g., `parser.json()`), not when invoked as a sub-rule via SUBRULE.
8884
+ *
8885
+ * Override this method to perform actions before parsing begins.
8886
+ * The default implementation is a no-op.
8887
+ *
8888
+ * @param ruleName - The name of the root rule being invoked.
8889
+ */
8890
+ onBeforeParse(ruleName) {
8891
+ for (let i = 0; i < this.maxLookahead + 1; i++) {
8892
+ this.tokVector.push(END_OF_FILE);
8893
+ }
8894
+ }
8895
+ /**
8896
+ * Hook called after the root-level parsing rule has completed (or thrown).
8897
+ * This is only called when a rule is invoked directly by the consumer
8898
+ * (e.g., `parser.json()`), not when invoked as a sub-rule via SUBRULE.
8899
+ *
8900
+ * This hook is called in a `finally` block, so it executes regardless of
8901
+ * whether parsing succeeded or threw an error.
8902
+ *
8903
+ * Override this method to perform actions after parsing completes.
8904
+ * The default implementation is a no-op.
8905
+ *
8906
+ * @param ruleName - The name of the root rule that was invoked.
8907
+ */
8908
+ onAfterParse(ruleName) {
8909
+ if (this.isAtEndOfInput() === false) {
8910
+ const firstRedundantTok = this.LA(1);
8911
+ const errMsg = this.errorMessageProvider.buildNotAllInputParsedMessage({
8912
+ firstRedundant: firstRedundantTok,
8913
+ ruleName: this.getCurrRuleFullName()
8914
+ });
8915
+ this.SAVE_ERROR(new NotAllInputParsedException(errMsg, firstRedundantTok));
8916
+ }
8917
+ while (this.tokVector.at(-1) === END_OF_FILE) {
8918
+ this.tokVector.pop();
8919
+ }
8820
8920
  }
8821
8921
  };
8822
8922
 
@@ -8830,7 +8930,7 @@ var ErrorHandler = class {
8830
8930
  if (isRecognitionException(error)) {
8831
8931
  error.context = {
8832
8932
  ruleStack: this.getHumanReadableRuleStack(),
8833
- ruleOccurrenceStack: clone_default(this.RULE_OCCURRENCE_STACK)
8933
+ ruleOccurrenceStack: this.RULE_OCCURRENCE_STACK.slice(0, this.RULE_OCCURRENCE_STACK_IDX + 1)
8834
8934
  };
8835
8935
  this._errors.push(error);
8836
8936
  return error;
@@ -9605,10 +9705,11 @@ lodash-es/lodash.js:
9605
9705
  (**
9606
9706
  * @license
9607
9707
  * Lodash (Custom Build) <https://lodash.com/>
9608
- * Build: `lodash modularize exports="es" -o ./`
9708
+ * Build: `lodash modularize exports="es" --repo lodash/lodash#4.18.1 -o ./`
9609
9709
  * Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
9610
9710
  * Released under MIT license <https://lodash.com/license>
9611
9711
  * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
9612
9712
  * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
9613
9713
  *)
9614
9714
  */
9715
+ //# sourceMappingURL=index.js.map