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! */ /* stop is not included! */
class Interval { class Interval {
constructor(start, stop) { constructor(start, stop) {
this.start = start; this.start = start;
this.stop = stop; this.stop = stop;
} }
clone() {
return new Interval(this.start, this.stop);
}
contains(item) { contains(item) {
return item >= this.start && item < this.stop; return item >= this.start && item < this.stop;
} }
@ -55,7 +60,7 @@ class IntervalSet {
addInterval(toAdd) { addInterval(toAdd) {
if (this.intervals === null) { if (this.intervals === null) {
this.intervals = []; this.intervals = [];
this.intervals.push(toAdd); this.intervals.push(toAdd.clone());
} else { } else {
// find insert pos // find insert pos
for (let pos = 0; pos < this.intervals.length; pos++) { for (let pos = 0; pos < this.intervals.length; pos++) {
@ -78,7 +83,7 @@ class IntervalSet {
} }
} }
// greater than any existing // 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() { removeParseListeners() {
this._parseListeners = null; this._parseListeners = null;
} }
// Notify any parse listeners of an enter rule event. // Notify any parse listeners of an enter rule event.
triggerEnterRuleEvent() { triggerEnterRuleEvent() {
if (this._parseListeners !== null) { if (this._parseListeners !== null) {
const ctx = this._ctx; const ctx = this._ctx;
this._parseListeners.map(function(listener) { this._parseListeners.forEach(function(listener) {
listener.enterEveryRule(ctx); listener.enterEveryRule(ctx);
ctx.enterRule(listener); ctx.enterRule(listener);
}); });
@ -248,7 +248,7 @@ class Parser extends Recognizer {
if (this._parseListeners !== null) { if (this._parseListeners !== null) {
// reverse order walk of listeners // reverse order walk of listeners
const ctx = this._ctx; const ctx = this._ctx;
this._parseListeners.slice(0).reverse().map(function(listener) { this._parseListeners.slice(0).reverse().forEach(function(listener) {
ctx.exitRule(listener); ctx.exitRule(listener);
listener.exitEveryRule(ctx); listener.exitEveryRule(ctx);
}); });
@ -392,7 +392,7 @@ class Parser extends Recognizer {
} }
node.invokingState = this.state; node.invokingState = this.state;
if (hasListener) { if (hasListener) {
this._parseListeners.map(function(listener) { this._parseListeners.forEach(function(listener) {
if (node instanceof ErrorNode || (node.isErrorNode !== undefined && node.isErrorNode())) { if (node instanceof ErrorNode || (node.isErrorNode !== undefined && node.isErrorNode())) {
listener.visitErrorNode(node); listener.visitErrorNode(node);
} else if (node instanceof TerminalNode) { } else if (node instanceof TerminalNode) {
@ -422,17 +422,13 @@ class Parser extends Recognizer {
if (this.buildParseTrees) { if (this.buildParseTrees) {
this.addContextToParseTree(); this.addContextToParseTree();
} }
if (this._parseListeners !== null) { this.triggerEnterRuleEvent();
this.triggerEnterRuleEvent();
}
} }
exitRule() { exitRule() {
this._ctx.stop = this._input.LT(-1); this._ctx.stop = this._input.LT(-1);
// trigger event on _ctx, before it reverts to parent // trigger event on _ctx, before it reverts to parent
if (this._parseListeners !== null) { this.triggerExitRuleEvent();
this.triggerExitRuleEvent();
}
this.state = this._ctx.invokingState; this.state = this._ctx.invokingState;
this._ctx = this._ctx.parentCtx; this._ctx = this._ctx.parentCtx;
} }
@ -469,10 +465,7 @@ class Parser extends Recognizer {
this._precedenceStack.push(precedence); this._precedenceStack.push(precedence);
this._ctx = localctx; this._ctx = localctx;
this._ctx.start = this._input.LT(1); 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. // Like {@link //enterRule} but for recursive rules.
@ -487,10 +480,7 @@ class Parser extends Recognizer {
if (this.buildParseTrees) { if (this.buildParseTrees) {
this._ctx.addChild(previous); 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) { unrollRecursionContexts(parentCtx) {
@ -498,7 +488,8 @@ class Parser extends Recognizer {
this._ctx.stop = this._input.LT(-1); this._ctx.stop = this._input.LT(-1);
const retCtx = this._ctx; // save current ctx (return value) const retCtx = this._ctx; // save current ctx (return value)
// unroll so _ctx is as it was before call to recursive method // 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) { while (this._ctx !== parentCtx) {
this.triggerExitRuleEvent(); this.triggerExitRuleEvent();
this._ctx = this._ctx.parentCtx; this._ctx = this._ctx.parentCtx;