Merge pull request #3130 from antlr/fix-3216

Fix #3126
This commit is contained in:
ericvergnaud 2021-03-19 10:55:52 +08:00 committed by GitHub
commit 3590d4d5e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 18 additions and 22 deletions

View File

@ -7,11 +7,16 @@ const {Token} = require('./Token');
/* stop is not included! */
class Interval {
constructor(start, stop) {
this.start = start;
this.stop = stop;
}
clone() {
return new Interval(this.start, this.stop);
}
contains(item) {
return item >= this.start && item < this.stop;
}
@ -55,7 +60,7 @@ class IntervalSet {
addInterval(toAdd) {
if (this.intervals === null) {
this.intervals = [];
this.intervals.push(toAdd);
this.intervals.push(toAdd.clone());
} else {
// find insert pos
for (let pos = 0; pos < this.intervals.length; pos++) {
@ -78,7 +83,7 @@ class IntervalSet {
}
}
// greater than any existing
this.intervals.push(toAdd);
this.intervals.push(toAdd.clone());
}
}

View File

@ -224,16 +224,16 @@ class Parser extends Recognizer {
}
}
// Remove all parse listeners.
// Remove all parse listeners.
removeParseListeners() {
this._parseListeners = null;
}
// Notify any parse listeners of an enter rule event.
// Notify any parse listeners of an enter rule event.
triggerEnterRuleEvent() {
if (this._parseListeners !== null) {
const ctx = this._ctx;
this._parseListeners.map(function(listener) {
this._parseListeners.forEach(function(listener) {
listener.enterEveryRule(ctx);
ctx.enterRule(listener);
});
@ -248,7 +248,7 @@ class Parser extends Recognizer {
if (this._parseListeners !== null) {
// reverse order walk of listeners
const ctx = this._ctx;
this._parseListeners.slice(0).reverse().map(function(listener) {
this._parseListeners.slice(0).reverse().forEach(function(listener) {
ctx.exitRule(listener);
listener.exitEveryRule(ctx);
});
@ -392,7 +392,7 @@ class Parser extends Recognizer {
}
node.invokingState = this.state;
if (hasListener) {
this._parseListeners.map(function(listener) {
this._parseListeners.forEach(function(listener) {
if (node instanceof ErrorNode || (node.isErrorNode !== undefined && node.isErrorNode())) {
listener.visitErrorNode(node);
} else if (node instanceof TerminalNode) {
@ -422,17 +422,13 @@ class Parser extends Recognizer {
if (this.buildParseTrees) {
this.addContextToParseTree();
}
if (this._parseListeners !== null) {
this.triggerEnterRuleEvent();
}
this.triggerEnterRuleEvent();
}
exitRule() {
this._ctx.stop = this._input.LT(-1);
// trigger event on _ctx, before it reverts to parent
if (this._parseListeners !== null) {
this.triggerExitRuleEvent();
}
this.triggerExitRuleEvent();
this.state = this._ctx.invokingState;
this._ctx = this._ctx.parentCtx;
}
@ -469,10 +465,7 @@ class Parser extends Recognizer {
this._precedenceStack.push(precedence);
this._ctx = localctx;
this._ctx.start = this._input.LT(1);
if (this._parseListeners !== null) {
this.triggerEnterRuleEvent(); // simulates rule entry for
// left-recursive rules
}
this.triggerEnterRuleEvent(); // simulates rule entry for left-recursive rules
}
// Like {@link //enterRule} but for recursive rules.
@ -487,10 +480,7 @@ class Parser extends Recognizer {
if (this.buildParseTrees) {
this._ctx.addChild(previous);
}
if (this._parseListeners !== null) {
this.triggerEnterRuleEvent(); // simulates rule entry for
// left-recursive rules
}
this.triggerEnterRuleEvent(); // simulates rule entry for left-recursive rules
}
unrollRecursionContexts(parentCtx) {
@ -498,7 +488,8 @@ class Parser extends Recognizer {
this._ctx.stop = this._input.LT(-1);
const retCtx = this._ctx; // save current ctx (return value)
// unroll so _ctx is as it was before call to recursive method
if (this._parseListeners !== null) {
const parseListeners = this.getParseListeners();
if (parseListeners !== null && parseListeners.length > 0) {
while (this._ctx !== parentCtx) {
this.triggerExitRuleEvent();
this._ctx = this._ctx.parentCtx;