Add ability to set parse tree internal node super class with option contextSuperClass. Provide impl in Java target that has altNum backing field. Add test across targets to set/get alt num. Fixes #1152.

This commit is contained in:
parrt 2016-03-30 11:00:47 -07:00
parent 7d16438a19
commit 9e98714a1d
41 changed files with 587 additions and 63 deletions

View File

@ -327,6 +327,19 @@ ParseTreeWalker walker = new ParseTreeWalker();
walker.Walk(new LeafListener(), <s>); walker.Walk(new LeafListener(), <s>);
>> >>
TreeNodeWithAltNumField(X) ::= <<
@parser::members {
public class MyRuleNode : ParserRuleContext {
public int altNum;
public MyRuleNode(ParserRuleContext parent, int invokingStateNumber): base(parent, invokingStateNumber)
{
}
public override int getAltNumber() { return altNum; }
public override void setAltNumber(int altNum) { this.altNum = altNum; }
}
}
>>
TokenGetterListener(X) ::= << TokenGetterListener(X) ::= <<
public class LeafListener : TBaseListener { public class LeafListener : TBaseListener {
public override void ExitA(TParser.AContext ctx) { public override void ExitA(TParser.AContext ctx) {

View File

@ -335,6 +335,19 @@ ParseTreeWalker walker = new ParseTreeWalker();
walker.walk(new LeafListener(), <s>); walker.walk(new LeafListener(), <s>);
>> >>
TreeNodeWithAltNumField(X) ::= <<
@parser::members {
public static class MyRuleNode extends ParserRuleContext {
public int altNum;
public MyRuleNode(ParserRuleContext parent, int invokingStateNumber) {
super(parent, invokingStateNumber);
}
@Override public int getAltNumber() { return altNum; }
@Override public void setAltNumber(int altNum) { this.altNum = altNum; }
}
}
>>
TokenGetterListener(X) ::= << TokenGetterListener(X) ::= <<
public static class LeafListener extends TBaseListener { public static class LeafListener extends TBaseListener {
public void exitA(TParser.AContext ctx) { public void exitA(TParser.AContext ctx) {

View File

@ -322,6 +322,20 @@ var walker = new antlr4.tree.ParseTreeWalker();
walker.walk(new this.LeafListener(), <s>); walker.walk(new this.LeafListener(), <s>);
>> >>
TreeNodeWithAltNumField(X) ::= <<
@parser::header {
MyRuleNode = function(parent, invokingState) {
antlr4.ParserRuleContext.call(this, parent, invokingState);
this.altNum = 0;
return this;
};
MyRuleNode.prototype = Object.create(antlr4.ParserRuleContext.prototype);
MyRuleNode.prototype.constructor = MyRuleNode;
}
>>
TokenGetterListener(X) ::= << TokenGetterListener(X) ::= <<
this.LeafListener = function() { this.LeafListener = function() {
this.exitA = function(ctx) { this.exitA = function(ctx) {

View File

@ -322,6 +322,20 @@ var walker = new antlr4.tree.ParseTreeWalker();
walker.walk(new this.LeafListener(), <s>); walker.walk(new this.LeafListener(), <s>);
>> >>
TreeNodeWithAltNumField(X) ::= <<
@parser::header {
MyRuleNode = function(parent, invokingState) {
antlr4.ParserRuleContext.call(this, parent, invokingState);
this.altNum = 0;
return this;
};
MyRuleNode.prototype = Object.create(antlr4.ParserRuleContext.prototype);
MyRuleNode.prototype.constructor = MyRuleNode;
}
>>
TokenGetterListener(X) ::= << TokenGetterListener(X) ::= <<
this.LeafListener = function() { this.LeafListener = function() {
this.exitA = function(ctx) { this.exitA = function(ctx) {

View File

@ -324,6 +324,20 @@ var walker = new antlr4.tree.ParseTreeWalker();
walker.walk(new this.LeafListener(), <s>); walker.walk(new this.LeafListener(), <s>);
>> >>
TreeNodeWithAltNumField(X) ::= <<
@parser::header {
MyRuleNode = function(parent, invokingState) {
antlr4.ParserRuleContext.call(this, parent, invokingState);
this.altNum = 0;
return this;
};
MyRuleNode.prototype = Object.create(antlr4.ParserRuleContext.prototype);
MyRuleNode.prototype.constructor = MyRuleNode;
}
>>
TokenGetterListener(X) ::= << TokenGetterListener(X) ::= <<
this.LeafListener = function() { this.LeafListener = function() {
this.exitA = function(ctx) { this.exitA = function(ctx) {

View File

@ -322,6 +322,24 @@ var walker = new antlr4.tree.ParseTreeWalker();
walker.walk(new this.LeafListener(), <s>); walker.walk(new this.LeafListener(), <s>);
>> >>
TreeNodeWithAltNumField(X) ::= <<
@parser::header {
MyRuleNode = function(parent, invokingState) {
antlr4.ParserRuleContext.call(this, parent, invokingState);
this.altNum = 0;
return this;
};
MyRuleNode.prototype = Object.create(antlr4.ParserRuleContext.prototype);
MyRuleNode.prototype.constructor = MyRuleNode;
MyRuleNode.prototype.getAltNumber = function() { return this.altNum; }
MyRuleNode.prototype.setAltNumber = function(altNumber) { this.altNum = altNumber; }
}
>>
TokenGetterListener(X) ::= << TokenGetterListener(X) ::= <<
this.LeafListener = function() { this.LeafListener = function() {
this.exitA = function(ctx) { this.exitA = function(ctx) {

View File

@ -322,6 +322,21 @@ var walker = new antlr4.tree.ParseTreeWalker();
walker.walk(new this.LeafListener(), <s>); walker.walk(new this.LeafListener(), <s>);
>> >>
TreeNodeWithAltNumField(X) ::= <<
@parser::header {
MyRuleNode = function(parent, invokingState) {
antlr4.ParserRuleContext.call(this, parent, invokingState);
this.altNum = 0;
return this;
};
MyRuleNode.prototype = Object.create(antlr4.ParserRuleContext.prototype);
MyRuleNode.prototype.constructor = MyRuleNode;
}
>>
TokenGetterListener(X) ::= << TokenGetterListener(X) ::= <<
this.LeafListener = function() { this.LeafListener = function() {
this.exitA = function(ctx) { this.exitA = function(ctx) {

View File

@ -312,6 +312,19 @@ walker = ParseTreeWalker()
walker.walk(TParser.LeafListener(), <s>) walker.walk(TParser.LeafListener(), <s>)
>> >>
TreeNodeWithAltNumField(X) ::= <<
@parser::members {
class MyRuleNode(ParserRuleContext):
def __init__(self, parent = None, invokingStateNumber = None ):
super(<X>Parser.MyRuleNode, self).__init__(parent, invokingStateNumber)
self.altNum = 0;
def getAltNumber(self):
return self.altNum
def setAltNumber(self, altNum):
self.altNum = altNum
}
>>
TokenGetterListener(X) ::= << TokenGetterListener(X) ::= <<
if __name__ is not None and "." in __name__: if __name__ is not None and "." in __name__:
from .<X>Listener import <X>Listener from .<X>Listener import <X>Listener

View File

@ -314,6 +314,19 @@ walker = ParseTreeWalker()
walker.walk(TParser.LeafListener(), <s>) walker.walk(TParser.LeafListener(), <s>)
>> >>
TreeNodeWithAltNumField(X) ::= <<
@parser::members {
class MyRuleNode(ParserRuleContext):
def __init__(self, parent:ParserRuleContext = None, invokingStateNumber:int = None ):
super(<X>Parser.MyRuleNode, self).__init__(parent, invokingStateNumber)
self.altNum = 0;
def getAltNumber(self):
return self.altNum
def setAltNumber(self, altNum):
self.altNum = altNum
}
>>
TokenGetterListener(X) ::= << TokenGetterListener(X) ::= <<
class LeafListener(MockListener): class LeafListener(MockListener):
def exitA(self, ctx): def exitA(self, ctx):

View File

@ -0,0 +1,40 @@
TestType() ::= "Parser"
Grammar ::= [
"T": {<grammar("T")>}
]
Input() ::= "xyz"
Rule() ::= "s"
Output() ::= <<
(a:3 x (b:2 y) z)<\n>
>>
Errors() ::= ""
grammar(grammarName) ::= <<
grammar <grammarName>;
options { contextSuperClass=MyRuleNode; }
<TreeNodeWithAltNumField(X=grammarName)>
s
@init {
<BuildParseTrees()>
}
@after {
<ToStringTree("$r.ctx"):writeln()>
}
: r=a ;
a : 'f'
| 'g'
| 'x' b 'z'
;
b : 'e' {} | 'y'
;
>>

View File

@ -6,5 +6,6 @@ TestTemplates ::= [
"RuleRef": [], "RuleRef": [],
"ExtraToken": [], "ExtraToken": [],
"NoViableAlt": [], "NoViableAlt": [],
"Sync": [] "Sync": [],
"AltNum": []
] ]

View File

@ -2,7 +2,6 @@
package org.antlr.v4.test.runtime.csharp; package org.antlr.v4.test.runtime.csharp;
import org.junit.Test; import org.junit.Test;
import org.junit.Ignore;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class TestParseTrees extends BaseTest { public class TestParseTrees extends BaseTest {
@ -52,6 +51,49 @@ public class TestParseTrees extends BaseTest {
assertEquals("(a y)\n", found); assertEquals("(a y)\n", found);
assertNull(this.stderrDuringParse); assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testAltNum() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(547);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("\n");
grammarBuilder.append("options { contextSuperClass=MyRuleNode; }\n");
grammarBuilder.append("\n");
grammarBuilder.append("@parser::members {\n");
grammarBuilder.append("public class MyRuleNode : ParserRuleContext {\n");
grammarBuilder.append(" public int altNum;\n");
grammarBuilder.append(" public MyRuleNode(ParserRuleContext parent, int invokingStateNumber): base(parent, invokingStateNumber)\n");
grammarBuilder.append(" {\n");
grammarBuilder.append(" }\n");
grammarBuilder.append(" public override int getAltNumber() { return altNum; }\n");
grammarBuilder.append(" public override void setAltNumber(int altNum) { this.altNum = altNum; }\n");
grammarBuilder.append("}\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("\n");
grammarBuilder.append("s\n");
grammarBuilder.append("@init {\n");
grammarBuilder.append("this.BuildParseTree = true;\n");
grammarBuilder.append("}\n");
grammarBuilder.append("@after {\n");
grammarBuilder.append("Console.WriteLine($r.ctx.ToStringTree(this));\n");
grammarBuilder.append("}\n");
grammarBuilder.append(" : r=a ;\n");
grammarBuilder.append("\n");
grammarBuilder.append("a : 'f'\n");
grammarBuilder.append(" | 'g'\n");
grammarBuilder.append(" | 'x' b 'z'\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("b : 'e' {} | 'y'\n");
grammarBuilder.append(" ;");
String grammar = grammarBuilder.toString();
String input ="xyz";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals("(a:3 x (b:2 y) z)\n", found);
assertNull(this.stderrDuringParse);
} }
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */ /* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test @Test

View File

@ -1,10 +1,10 @@
/* This file is generated by TestGenerator, any edits will be overwritten by the next generation. */ /* This file is generated by TestGenerator, any edits will be overwritten by the next generation. */
package org.antlr.v4.test.runtime.java; package org.antlr.v4.test.runtime.java;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.*; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
public class TestParseTrees extends BaseTest { public class TestParseTrees extends BaseTest {
@ -62,6 +62,53 @@ public class TestParseTrees extends BaseTest {
} }
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testAltNum() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(562);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("\n");
grammarBuilder.append("options { contextSuperClass=MyRuleNode; }\n");
grammarBuilder.append("\n");
grammarBuilder.append("@parser::members {\n");
grammarBuilder.append("public static class MyRuleNode extends ParserRuleContext {\n");
grammarBuilder.append(" public int altNum;\n");
grammarBuilder.append(" public MyRuleNode(ParserRuleContext parent, int invokingStateNumber) {\n");
grammarBuilder.append(" super(parent, invokingStateNumber);\n");
grammarBuilder.append(" }\n");
grammarBuilder.append(" @Override public int getAltNumber() { return altNum; }\n");
grammarBuilder.append(" @Override public void setAltNumber(int altNum) { this.altNum = altNum; }\n");
grammarBuilder.append("}\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("\n");
grammarBuilder.append("s\n");
grammarBuilder.append("@init {\n");
grammarBuilder.append("setBuildParseTree(true);\n");
grammarBuilder.append("}\n");
grammarBuilder.append("@after {\n");
grammarBuilder.append("System.out.println($r.ctx.toStringTree(this));\n");
grammarBuilder.append("}\n");
grammarBuilder.append(" : r=a ;\n");
grammarBuilder.append("\n");
grammarBuilder.append("a : 'f'\n");
grammarBuilder.append(" | 'g'\n");
grammarBuilder.append(" | 'x' b 'z'\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("b : 'e' {} | 'y'\n");
grammarBuilder.append(" ;");
String grammar = grammarBuilder.toString();
String input ="xyz";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals("(a:3 x (b:2 y) z)\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */ /* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test @Test
public void testExtraToken() throws Exception { public void testExtraToken() throws Exception {

View File

@ -1,10 +1,10 @@
/* This file is generated by TestGenerator, any edits will be overwritten by the next generation. */ /* This file is generated by TestGenerator, any edits will be overwritten by the next generation. */
package org.antlr.v4.test.runtime.javascript.node; package org.antlr.v4.test.runtime.javascript.node;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.*; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class TestParseTrees extends BaseTest { public class TestParseTrees extends BaseTest {
@ -58,6 +58,55 @@ public class TestParseTrees extends BaseTest {
assertEquals("(a y)\n", found); assertEquals("(a y)\n", found);
assertNull(this.stderrDuringParse); assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testAltNum() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(663);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("\n");
grammarBuilder.append("options { contextSuperClass=MyRuleNode; }\n");
grammarBuilder.append("\n");
grammarBuilder.append("@parser::header {\n");
grammarBuilder.append("MyRuleNode = function(parent, invokingState) {\n");
grammarBuilder.append(" antlr4.ParserRuleContext.call(this, parent, invokingState);\n");
grammarBuilder.append("\n");
grammarBuilder.append(" this.altNum = 0;\n");
grammarBuilder.append(" return this;\n");
grammarBuilder.append("};\n");
grammarBuilder.append("\n");
grammarBuilder.append("MyRuleNode.prototype = Object.create(antlr4.ParserRuleContext.prototype);\n");
grammarBuilder.append("MyRuleNode.prototype.constructor = MyRuleNode;\n");
grammarBuilder.append("MyRuleNode.prototype.getAltNumber = function() { return this.altNum; }\n");
grammarBuilder.append("MyRuleNode.prototype.setAltNumber = function(altNumber) { this.altNum = altNumber; }\n");
grammarBuilder.append("\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("\n");
grammarBuilder.append("s\n");
grammarBuilder.append("@init {\n");
grammarBuilder.append("this.buildParseTrees = true;\n");
grammarBuilder.append("}\n");
grammarBuilder.append("@after {\n");
grammarBuilder.append("console.log($r.ctx.toStringTree(null, this));\n");
grammarBuilder.append("}\n");
grammarBuilder.append(" : r=a ;\n");
grammarBuilder.append("\n");
grammarBuilder.append("a : 'f'\n");
grammarBuilder.append(" | 'g'\n");
grammarBuilder.append(" | 'x' b 'z'\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("b : 'e' {} | 'y'\n");
grammarBuilder.append(" ;");
String grammar = grammarBuilder.toString();
String input ="xyz";
String found = execParser("T.g4", grammar, "TParser", "TLexer",
"TListener", "TVisitor",
"s", input, false);
assertEquals("(a:3 x (b:2 y) z)\n", found);
assertNull(this.stderrDuringParse);
} }
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */ /* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test @Test

View File

@ -1,9 +1,10 @@
/* This file is generated by TestGenerator, any edits will be overwritten by the next generation. */ /* This file is generated by TestGenerator, any edits will be overwritten by the next generation. */
package org.antlr.v4.test.runtime.python2; package org.antlr.v4.test.runtime.python2;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class TestParseTrees extends BasePython2Test { public class TestParseTrees extends BasePython2Test {
@ -64,6 +65,54 @@ public class TestParseTrees extends BasePython2Test {
} }
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testAltNum() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(562);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("\n");
grammarBuilder.append("options { contextSuperClass=MyRuleNode; }\n");
grammarBuilder.append("\n");
grammarBuilder.append("@parser::members {\n");
grammarBuilder.append("class MyRuleNode(ParserRuleContext):\n");
grammarBuilder.append(" def __init__(self, parent = None, invokingStateNumber = None ):\n");
grammarBuilder.append(" super(TParser.MyRuleNode, self).__init__(parent, invokingStateNumber)\n");
grammarBuilder.append(" self.altNum = 0;\n");
grammarBuilder.append(" def getAltNumber(self):\n");
grammarBuilder.append(" return self.altNum\n");
grammarBuilder.append(" def setAltNumber(self, altNum):\n");
grammarBuilder.append(" self.altNum = altNum\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("\n");
grammarBuilder.append("s\n");
grammarBuilder.append("@init {\n");
grammarBuilder.append("self._buildParseTrees = True\n");
grammarBuilder.append("}\n");
grammarBuilder.append("@after {\n");
grammarBuilder.append("print($r.ctx.toStringTree(recog=self))\n");
grammarBuilder.append("}\n");
grammarBuilder.append(" : r=a ;\n");
grammarBuilder.append("\n");
grammarBuilder.append("a : 'f'\n");
grammarBuilder.append(" | 'g'\n");
grammarBuilder.append(" | 'x' b 'z'\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("b : 'e' {} | 'y'\n");
grammarBuilder.append(" ;");
String grammar = grammarBuilder.toString();
String input ="xyz";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "TListener", "TVisitor", "s", input, false);
assertEquals("(a:3 x (b:2 y) z)\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */ /* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test @Test
public void testExtraToken() throws Exception { public void testExtraToken() throws Exception {

View File

@ -41,7 +41,7 @@ public abstract class BasePython3Test extends BasePythonTest {
@Override @Override
protected String getPythonExecutable() { protected String getPythonExecutable() {
return "python3.5"; return "python3";
} }
@Override @Override

View File

@ -1,9 +1,10 @@
/* This file is generated by TestGenerator, any edits will be overwritten by the next generation. */ /* This file is generated by TestGenerator, any edits will be overwritten by the next generation. */
package org.antlr.v4.test.runtime.python3; package org.antlr.v4.test.runtime.python3;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class TestParseTrees extends BasePython3Test { public class TestParseTrees extends BasePython3Test {
@ -64,6 +65,54 @@ public class TestParseTrees extends BasePython3Test {
} }
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testAltNum() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(584);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("\n");
grammarBuilder.append("options { contextSuperClass=MyRuleNode; }\n");
grammarBuilder.append("\n");
grammarBuilder.append("@parser::members {\n");
grammarBuilder.append("class MyRuleNode(ParserRuleContext):\n");
grammarBuilder.append(" def __init__(self, parent:ParserRuleContext = None, invokingStateNumber:int = None ):\n");
grammarBuilder.append(" super(TParser.MyRuleNode, self).__init__(parent, invokingStateNumber)\n");
grammarBuilder.append(" self.altNum = 0;\n");
grammarBuilder.append(" def getAltNumber(self):\n");
grammarBuilder.append(" return self.altNum\n");
grammarBuilder.append(" def setAltNumber(self, altNum):\n");
grammarBuilder.append(" self.altNum = altNum\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("\n");
grammarBuilder.append("s\n");
grammarBuilder.append("@init {\n");
grammarBuilder.append("self._buildParseTrees = True\n");
grammarBuilder.append("}\n");
grammarBuilder.append("@after {\n");
grammarBuilder.append("print($r.ctx.toStringTree(recog=self))\n");
grammarBuilder.append("}\n");
grammarBuilder.append(" : r=a ;\n");
grammarBuilder.append("\n");
grammarBuilder.append("a : 'f'\n");
grammarBuilder.append(" | 'g'\n");
grammarBuilder.append(" | 'x' b 'z'\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("b : 'e' {} | 'y'\n");
grammarBuilder.append(" ;");
String grammar = grammarBuilder.toString();
String input ="xyz";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "TListener", "TVisitor", "s", input, false);
assertEquals("(a:3 x (b:2 y) z)\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */ /* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test @Test
public void testExtraToken() throws Exception { public void testExtraToken() throws Exception {

View File

@ -842,6 +842,7 @@ namespace Antlr4.Runtime
public virtual void EnterOuterAlt(ParserRuleContext localctx, int altNum) public virtual void EnterOuterAlt(ParserRuleContext localctx, int altNum)
{ {
localctx.setAltNumber(altNum);
// if we have new localctx, make sure we replace existing ctx // if we have new localctx, make sure we replace existing ctx
// that is previous child of parse tree // that is previous child of parse tree
if (_buildParseTrees && _ctx != localctx) if (_buildParseTrees && _ctx != localctx)

View File

@ -30,6 +30,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using Antlr4.Runtime; using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc; using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Sharpen; using Antlr4.Runtime.Sharpen;
using Antlr4.Runtime.Tree; using Antlr4.Runtime.Tree;
@ -216,6 +217,23 @@ namespace Antlr4.Runtime
} }
} }
/* For rule associated with this parse tree internal node, return
* the outer alternative number used to match the input. Default
* implementation does not compute nor store this alt num. Create
* a subclass of ParserRuleContext with backing field and set
* option contextSuperClass.
* to set it.
*/
public virtual int getAltNumber() { return Atn.ATN.InvalidAltNumber; }
/* Set the outer alternative number for this context node. Default
* implementation does nothing to avoid backing field overhead for
* trees that don't need it. Create
* a subclass of ParserRuleContext with backing field and set
* option contextSuperClass.
*/
public virtual void setAltNumber(int altNumber) { }
public virtual IParseTree GetChild(int i) public virtual IParseTree GetChild(int i)
{ {
return null; return null;

View File

@ -30,6 +30,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using Antlr4.Runtime; using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc; using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Sharpen; using Antlr4.Runtime.Sharpen;
using Antlr4.Runtime.Tree; using Antlr4.Runtime.Tree;
@ -111,10 +112,14 @@ namespace Antlr4.Runtime.Tree
{ {
if (ruleNames != null) if (ruleNames != null)
{ {
if (t is IRuleNode) if (t is RuleContext)
{ {
int ruleIndex = ((IRuleNode)t).RuleContext.RuleIndex; int ruleIndex = ((RuleContext)t).RuleIndex;
string ruleName = ruleNames[ruleIndex]; string ruleName = ruleNames[ruleIndex];
int altNumber = ((RuleContext)t).getAltNumber();
if ( altNumber!=Atn.ATN.InvalidAltNumber ) {
return ruleName+":"+altNumber;
}
return ruleName; return ruleName;
} }
else else

View File

@ -0,0 +1,20 @@
package org.antlr.v4.runtime;
/** A handy class for use with
*
* options {contextSuperClass=org.antlr.v4.runtime.RuleContextWithAltNum;}
*
* that provides a backing field / impl for the outer alternative number
* matched for an internal parse tree node.
*
* I'm only putting into Java runtime as I'm certain I'm the only one that
* will really every use this.
*/
public class RuleContextWithAltNum extends ParserRuleContext {
public int altNum;
public RuleContextWithAltNum(ParserRuleContext parent, int invokingStateNumber) {
super(parent, invokingStateNumber);
}
@Override public int getAltNumber() { return altNum; }
@Override public void setAltNumber(int altNum) { this.altNum = altNum; }
}

View File

@ -33,7 +33,9 @@ package org.antlr.v4.runtime.tree;
import org.antlr.v4.runtime.CommonToken; import org.antlr.v4.runtime.CommonToken;
import org.antlr.v4.runtime.Parser; import org.antlr.v4.runtime.Parser;
import org.antlr.v4.runtime.ParserRuleContext; import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.RuleContext;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.atn.ATN;
import org.antlr.v4.runtime.misc.Interval; import org.antlr.v4.runtime.misc.Interval;
import org.antlr.v4.runtime.misc.Predicate; import org.antlr.v4.runtime.misc.Predicate;
import org.antlr.v4.runtime.misc.Utils; import org.antlr.v4.runtime.misc.Utils;
@ -91,9 +93,13 @@ public class Trees {
public static String getNodeText(Tree t, List<String> ruleNames) { public static String getNodeText(Tree t, List<String> ruleNames) {
if ( ruleNames!=null ) { if ( ruleNames!=null ) {
if ( t instanceof RuleNode ) { if ( t instanceof RuleContext ) {
int ruleIndex = ((RuleNode)t).getRuleContext().getRuleIndex(); int ruleIndex = ((RuleContext)t).getRuleContext().getRuleIndex();
String ruleName = ruleNames.get(ruleIndex); String ruleName = ruleNames.get(ruleIndex);
int altNumber = ((RuleContext) t).getAltNumber();
if ( altNumber!=ATN.INVALID_ALT_NUMBER ) {
return ruleName+":"+altNumber;
}
return ruleName; return ruleName;
} }
else if ( t instanceof ErrorNode) { else if ( t instanceof ErrorNode) {

View File

@ -451,6 +451,7 @@ Parser.prototype.exitRule = function() {
}; };
Parser.prototype.enterOuterAlt = function(localctx, altNum) { Parser.prototype.enterOuterAlt = function(localctx, altNum) {
localctx.setAltNumber(altNum);
// if we have new localctx, make sure we replace existing ctx // if we have new localctx, make sure we replace existing ctx
// that is previous child of parse tree // that is previous child of parse tree
if (this.buildParseTrees && this._ctx !== localctx) { if (this.buildParseTrees && this._ctx !== localctx) {

View File

@ -51,6 +51,7 @@
var RuleNode = require('./tree/Tree').RuleNode; var RuleNode = require('./tree/Tree').RuleNode;
var INVALID_INTERVAL = require('./tree/Tree').INVALID_INTERVAL; var INVALID_INTERVAL = require('./tree/Tree').INVALID_INTERVAL;
var INVALID_ALT_NUMBER = require('./atn/ATN').INVALID_ALT_NUMBER;
function RuleContext(parent, invokingState) { function RuleContext(parent, invokingState) {
RuleNode.call(this); RuleNode.call(this);
@ -113,6 +114,21 @@ RuleContext.prototype.getText = function() {
} }
}; };
// For rule associated with this parse tree internal node, return
// the outer alternative number used to match the input. Default
// implementation does not compute nor store this alt num. Create
// a subclass of ParserRuleContext with backing field and set
// option contextSuperClass.
// to set it.
RuleContext.prototype.getAltNumber = function() { return INVALID_ALT_NUMBER; }
// Set the outer alternative number for this context node. Default
// implementation does nothing to avoid backing field overhead for
// trees that don't need it. Create
// a subclass of ParserRuleContext with backing field and set
// option contextSuperClass.
RuleContext.prototype.setAltNumber = function(altNumber) { }
RuleContext.prototype.getChild = function(i) { RuleContext.prototype.getChild = function(i) {
return null; return null;
}; };

View File

@ -34,6 +34,8 @@ var RuleNode = require('./Tree').RuleNode;
var ErrorNode = require('./Tree').ErrorNode; var ErrorNode = require('./Tree').ErrorNode;
var TerminalNode = require('./Tree').TerminalNode; var TerminalNode = require('./Tree').TerminalNode;
var ParserRuleContext = require('./../ParserRuleContext').ParserRuleContext; var ParserRuleContext = require('./../ParserRuleContext').ParserRuleContext;
var RuleContext = require('./../RuleContext').RuleContext;
var INVALID_ALT_NUMBER = require('./../atn/ATN').INVALID_ALT_NUMBER;
/** A set of utility routines useful for all kinds of ANTLR trees. */ /** A set of utility routines useful for all kinds of ANTLR trees. */
@ -75,8 +77,12 @@ Trees.getNodeText = function(t, ruleNames, recog) {
ruleNames = recog.ruleNames; ruleNames = recog.ruleNames;
} }
if(ruleNames!==null) { if(ruleNames!==null) {
if (t instanceof RuleNode) { if (t instanceof RuleContext) {
return ruleNames[t.getRuleContext().ruleIndex]; var altNumber = t.getAltNumber();
if ( altNumber!=INVALID_ALT_NUMBER ) {
return ruleNames[t.ruleIndex]+":"+altNumber;
}
return ruleNames[t.ruleIndex];
} else if ( t instanceof ErrorNode) { } else if ( t instanceof ErrorNode) {
return t.toString(); return t.toString();
} else if(t instanceof TerminalNode) { } else if(t instanceof TerminalNode) {

View File

@ -2,12 +2,12 @@ from distutils.core import setup
setup( setup(
name='antlr4-python2-runtime', name='antlr4-python2-runtime',
version='4.5.2.1', version='4.5.3',
packages=['antlr4', 'antlr4.atn', 'antlr4.dfa', 'antlr4.tree', 'antlr4.error', 'antlr4.xpath'], packages=['antlr4', 'antlr4.atn', 'antlr4.dfa', 'antlr4.tree', 'antlr4.error', 'antlr4.xpath'],
package_dir={'': 'src'}, package_dir={'': 'src'},
url='http://www.antlr.org', url='http://www.antlr.org',
license='BSD', license='BSD',
author='Eric Vergnaud, Terence Parr, Sam Harwell', author='Eric Vergnaud, Terence Parr, Sam Harwell',
author_email='eric.vergnaud@wanadoo.fr', author_email='eric.vergnaud@wanadoo.fr',
description='ANTLR 4.5.2.1 runtime for Python 2.7.6' description='ANTLR 4.5.3 runtime for Python 2.7.6'
) )

View File

@ -382,6 +382,7 @@ class Parser (Recognizer):
self._ctx = self._ctx.parentCtx self._ctx = self._ctx.parentCtx
def enterOuterAlt(self, localctx, altNum): def enterOuterAlt(self, localctx, altNum):
localctx.setAltNumber(altNum)
# if we have new localctx, make sure we replace existing ctx # if we have new localctx, make sure we replace existing ctx
# that is previous child of parse tree # that is previous child of parse tree
if self.buildParseTrees and self._ctx != localctx: if self.buildParseTrees and self._ctx != localctx:

View File

@ -52,6 +52,7 @@
from io import StringIO from io import StringIO
from antlr4.tree.Tree import RuleNode, INVALID_INTERVAL from antlr4.tree.Tree import RuleNode, INVALID_INTERVAL
from antlr4.tree.Trees import Trees from antlr4.tree.Trees import Trees
from antlr4.atn.ATN import ATN
class RuleContext(RuleNode): class RuleContext(RuleNode):
@ -109,6 +110,23 @@ class RuleContext(RuleNode):
def getRuleIndex(self): def getRuleIndex(self):
return -1 return -1
# For rule associated with this parse tree internal node, return
# the outer alternative number used to match the input. Default
# implementation does not compute nor store this alt num. Create
# a subclass of ParserRuleContext with backing field and set
# option contextSuperClass.
# to set it.
def getAltNumber(self):
return ATN.INVALID_ALT_NUMBER
# Set the outer alternative number for this context node. Default
# implementation does nothing to avoid backing field overhead for
# trees that don't need it. Create
# a subclass of ParserRuleContext with backing field and set
# option contextSuperClass.
def setAltNumber(self, altNumber):
pass
def getChild(self, i): def getChild(self, i):
return None return None

View File

@ -32,6 +32,8 @@
# A set of utility routines useful for all kinds of ANTLR trees.# # A set of utility routines useful for all kinds of ANTLR trees.#
from io import StringIO from io import StringIO
import antlr4
from antlr4.atn.ATN import ATN
from antlr4.Token import Token from antlr4.Token import Token
from antlr4.Utils import escapeWhitespace from antlr4.Utils import escapeWhitespace
from antlr4.tree.Tree import RuleNode, ErrorNode, TerminalNode from antlr4.tree.Tree import RuleNode, ErrorNode, TerminalNode
@ -65,7 +67,9 @@ class Trees(object):
ruleNames = recog.ruleNames ruleNames = recog.ruleNames
if ruleNames is not None: if ruleNames is not None:
if isinstance(t, RuleNode): if isinstance(t, RuleNode):
return ruleNames[t.getRuleContext().getRuleIndex()] if t.getAltNumber()!=ATN.INVALID_ALT_NUMBER:
return ruleNames[t.getRuleIndex()]+":"+str(t.getAltNumber())
return ruleNames[t.getRuleIndex()]
elif isinstance( t, ErrorNode): elif isinstance( t, ErrorNode):
return unicode(t) return unicode(t)
elif isinstance(t, TerminalNode): elif isinstance(t, TerminalNode):

View File

@ -2,12 +2,12 @@ from distutils.core import setup
setup( setup(
name='antlr4-python3-runtime', name='antlr4-python3-runtime',
version='4.5.2.1', version='4.5.3',
packages=['antlr4', 'antlr4.atn', 'antlr4.dfa', 'antlr4.tree', 'antlr4.error', 'antlr4.xpath'], packages=['antlr4', 'antlr4.atn', 'antlr4.dfa', 'antlr4.tree', 'antlr4.error', 'antlr4.xpath'],
package_dir={'': 'src'}, package_dir={'': 'src'},
url='http://www.antlr.org', url='http://www.antlr.org',
license='BSD', license='BSD',
author='Eric Vergnaud, Terence Parr, Sam Harwell', author='Eric Vergnaud, Terence Parr, Sam Harwell',
author_email='eric.vergnaud@wanadoo.fr', author_email='eric.vergnaud@wanadoo.fr',
description='ANTLR 4.5.2.1 runtime for Python 3.4.0' description='ANTLR 4.5.3 runtime for Python 3.4.0'
) )

View File

@ -389,6 +389,7 @@ class Parser (Recognizer):
self._ctx = self._ctx.parentCtx self._ctx = self._ctx.parentCtx
def enterOuterAlt(self, localctx:ParserRuleContext, altNum:int): def enterOuterAlt(self, localctx:ParserRuleContext, altNum:int):
localctx.setAltNumber(altNum)
# if we have new localctx, make sure we replace existing ctx # if we have new localctx, make sure we replace existing ctx
# that is previous child of parse tree # that is previous child of parse tree
if self.buildParseTrees and self._ctx != localctx: if self.buildParseTrees and self._ctx != localctx:

View File

@ -113,6 +113,23 @@ class RuleContext(RuleNode):
def getRuleIndex(self): def getRuleIndex(self):
return -1 return -1
# For rule associated with this parse tree internal node, return
# the outer alternative number used to match the input. Default
# implementation does not compute nor store this alt num. Create
# a subclass of ParserRuleContext with backing field and set
# option contextSuperClass.
# to set it.
def getAltNumber(self):
return 0 # should use ATN.INVALID_ALT_NUMBER but won't compile
# Set the outer alternative number for this context node. Default
# implementation does nothing to avoid backing field overhead for
# trees that don't need it. Create
# a subclass of ParserRuleContext with backing field and set
# option contextSuperClass.
def setAltNumber(self, altNumber:int):
pass
def getChild(self, i:int): def getChild(self, i:int):
return None return None

View File

@ -68,7 +68,9 @@ class Trees(object):
ruleNames = recog.ruleNames ruleNames = recog.ruleNames
if ruleNames is not None: if ruleNames is not None:
if isinstance(t, RuleNode): if isinstance(t, RuleNode):
return ruleNames[t.getRuleContext().getRuleIndex()] if t.getAltNumber()!=0: # should use ATN.INVALID_ALT_NUMBER but won't compile
return ruleNames[t.getRuleIndex()]+":"+str(t.getAltNumber())
return ruleNames[t.getRuleIndex()]
elif isinstance( t, ErrorNode): elif isinstance( t, ErrorNode):
return str(t) return str(t)
elif isinstance(t, TerminalNode): elif isinstance(t, TerminalNode):

View File

@ -1,10 +1,9 @@
package org.antlr.v4.test.tool; package org.antlr.v4.test.tool;
import org.antlr.v4.gui.TreeTextProvider;
import org.antlr.v4.runtime.tree.ErrorNode; import org.antlr.v4.runtime.tree.ErrorNode;
import org.antlr.v4.runtime.tree.Tree; import org.antlr.v4.runtime.tree.Tree;
import org.antlr.v4.runtime.tree.Trees; import org.antlr.v4.runtime.tree.Trees;
import org.antlr.v4.gui.TreeTextProvider;
import org.antlr.v4.tool.GrammarInterpreterRuleContext;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -17,10 +16,6 @@ public class InterpreterTreeTextProvider implements TreeTextProvider {
public String getText(Tree node) { public String getText(Tree node) {
if ( node==null ) return "null"; if ( node==null ) return "null";
String nodeText = Trees.getNodeText(node, ruleNames); String nodeText = Trees.getNodeText(node, ruleNames);
if ( node instanceof GrammarInterpreterRuleContext) {
GrammarInterpreterRuleContext ctx = (GrammarInterpreterRuleContext) node;
return nodeText+":"+ctx.getOuterAltNum();
}
if ( node instanceof ErrorNode) { if ( node instanceof ErrorNode) {
return "<error "+nodeText+">"; return "<error "+nodeText+">";
} }

View File

@ -30,7 +30,7 @@
// args must be <object-model-object>, <fields-resulting-in-STs> // args must be <object-model-object>, <fields-resulting-in-STs>
ParserFile(file, parser, namedActions) ::= << ParserFile(file, parser, namedActions, contextSuperClass) ::= <<
<fileHeader(file.grammarFileName, file.ANTLRVersion)> <fileHeader(file.grammarFileName, file.ANTLRVersion)>
<if(file.genPackage)> <if(file.genPackage)>
namespace <file.genPackage> { namespace <file.genPackage> {
@ -839,7 +839,7 @@ CaptureNextTokenType(d) ::= "<d.varName> = TokenStream.La(1);"
StructDecl(struct,ctorAttrs,attrs,getters,dispatchMethods,interfaces,extensionMembers, StructDecl(struct,ctorAttrs,attrs,getters,dispatchMethods,interfaces,extensionMembers,
superClass={ParserRuleContext}) ::= << superClass={ParserRuleContext}) ::= <<
public partial class <struct.name> : <superClass><if(interfaces)>, <interfaces; separator=", "><endif> { public partial class <struct.name> : <if(contextSuperClass)><contextSuperClass><else>ParserRuleContext<endif><if(interfaces)>, <interfaces; separator=", "><endif> {
<attrs:{a | public <a>;}; separator="\n"> <attrs:{a | public <a>;}; separator="\n">
<getters:{g | <g>}; separator="\n"> <getters:{g | <g>}; separator="\n">
<if(ctorAttrs)>public <struct.name>(ParserRuleContext parent, int invokingState) : base(parent, invokingState) { }<endif> <if(ctorAttrs)>public <struct.name>(ParserRuleContext parent, int invokingState) : base(parent, invokingState) { }<endif>

View File

@ -42,7 +42,7 @@ javaTypeInitMap ::= [
// args must be <object-model-object>, <fields-resulting-in-STs> // args must be <object-model-object>, <fields-resulting-in-STs>
ParserFile(file, parser, namedActions) ::= << ParserFile(file, parser, namedActions, contextSuperClass) ::= <<
<fileHeader(file.grammarFileName, file.ANTLRVersion)> <fileHeader(file.grammarFileName, file.ANTLRVersion)>
<if(file.genPackage)> <if(file.genPackage)>
package <file.genPackage>; package <file.genPackage>;
@ -765,8 +765,9 @@ ListLabelName(label) ::= "<label>"
CaptureNextToken(d) ::= "<d.varName> = _input.LT(1);" CaptureNextToken(d) ::= "<d.varName> = _input.LT(1);"
CaptureNextTokenType(d) ::= "<d.varName> = _input.LA(1);" CaptureNextTokenType(d) ::= "<d.varName> = _input.LA(1);"
StructDecl(struct,ctorAttrs,attrs,getters,dispatchMethods,interfaces,extensionMembers) ::= << StructDecl(struct,ctorAttrs,attrs,getters,dispatchMethods,interfaces,extensionMembers)
public static class <struct.name> extends ParserRuleContext <if(interfaces)> implements <interfaces; separator=", "><endif> { ::= <<
public static class <struct.name> extends <if(contextSuperClass)><contextSuperClass><else>ParserRuleContext<endif><if(interfaces)> implements <interfaces; separator=", "><endif> {
<attrs:{a | public <a>;}; separator="\n"> <attrs:{a | public <a>;}; separator="\n">
<getters:{g | <g>}; separator="\n"> <getters:{g | <g>}; separator="\n">
<if(ctorAttrs)>public <struct.name>(ParserRuleContext parent, int invokingState) { super(parent, invokingState); }<endif> <if(ctorAttrs)>public <struct.name>(ParserRuleContext parent, int invokingState) { super(parent, invokingState); }<endif>

View File

@ -46,7 +46,7 @@ pythonTypeInitMap ::= [
// args must be <object-model-object>, <fields-resulting-in-STs> // args must be <object-model-object>, <fields-resulting-in-STs>
ParserFile(file, parser, namedActions) ::= << ParserFile(file, parser, namedActions, contextSuperClass) ::= <<
<fileHeader(file.grammarFileName, file.ANTLRVersion)> <fileHeader(file.grammarFileName, file.ANTLRVersion)>
var antlr4 = require('antlr4/index'); var antlr4 = require('antlr4/index');
<if(file.genListener)> <if(file.genListener)>
@ -671,8 +671,7 @@ ListLabelName(label) ::= "<label>"
CaptureNextToken(d) ::= "<d.varName> = self._input.LT(1)" CaptureNextToken(d) ::= "<d.varName> = self._input.LT(1)"
CaptureNextTokenType(d) ::= "<d.varName> = this._input.LA(1);" CaptureNextTokenType(d) ::= "<d.varName> = this._input.LA(1);"
StructDecl(struct,ctorAttrs,attrs,getters,dispatchMethods,interfaces,extensionMembers, StructDecl(struct,ctorAttrs,attrs,getters,dispatchMethods,interfaces,extensionMembers) ::= <<
superClass={antlr4.ParserRuleContext}) ::= <<
function <struct.name>(parser, parent, invokingState<struct.ctorAttrs:{a | , <a.name>}>) { function <struct.name>(parser, parent, invokingState<struct.ctorAttrs:{a | , <a.name>}>) {
if(parent===undefined) { if(parent===undefined) {
parent = null; parent = null;
@ -680,7 +679,7 @@ function <struct.name>(parser, parent, invokingState<struct.ctorAttrs:{a | , <a.
if(invokingState===undefined || invokingState===null) { if(invokingState===undefined || invokingState===null) {
invokingState = -1; invokingState = -1;
} }
<superClass>.call(this, parent, invokingState); <if(contextSuperClass)><contextSuperClass><else>antlr4.ParserRuleContext<endif>.call(this, parent, invokingState);
this.parser = parser; this.parser = parser;
this.ruleIndex = <parser.name>.RULE_<struct.derivedFromName>; this.ruleIndex = <parser.name>.RULE_<struct.derivedFromName>;
<attrs:{a | <a>}; separator="\n"> <attrs:{a | <a>}; separator="\n">
@ -688,14 +687,14 @@ function <struct.name>(parser, parent, invokingState<struct.ctorAttrs:{a | , <a.
return this; return this;
} }
<struct.name>.prototype = Object.create(<superClass>.prototype); <struct.name>.prototype = Object.create(<if(contextSuperClass)><contextSuperClass><else>antlr4.ParserRuleContext<endif>.prototype);
<struct.name>.prototype.constructor = <struct.name>; <struct.name>.prototype.constructor = <struct.name>;
<getters:{g | <struct.name>.prototype.<g>}; separator="\n\n"> <getters:{g | <struct.name>.prototype.<g>}; separator="\n\n">
<if(struct.provideCopyFrom)> <! don't need copy unless we have subclasses !> <if(struct.provideCopyFrom)> <! don't need copy unless we have subclasses !>
<struct.name>.prototype.copyFrom = function(ctx) { <struct.name>.prototype.copyFrom = function(ctx) {
<superClass>.prototype.copyFrom.call(this, ctx); <if(contextSuperClass)><contextSuperClass><else>antlr4.ParserRuleContext<endif>.prototype.copyFrom.call(this, ctx);
<struct.attrs:{a | this.<a.name> = ctx.<a.name>;}; separator="\n"> <struct.attrs:{a | this.<a.name> = ctx.<a.name>;}; separator="\n">
}; };
<endif> <endif>

View File

@ -46,7 +46,7 @@ pythonTypeInitMap ::= [
// args must be <object-model-object>, <fields-resulting-in-STs> // args must be <object-model-object>, <fields-resulting-in-STs>
ParserFile(file, parser, namedActions) ::= << ParserFile(file, parser, namedActions, contextSuperClass) ::= <<
<fileHeader(file.grammarFileName, file.ANTLRVersion)> <fileHeader(file.grammarFileName, file.ANTLRVersion)>
# encoding: utf-8 # encoding: utf-8
from __future__ import print_function from __future__ import print_function
@ -630,9 +630,8 @@ ListLabelName(label) ::= "<label>"
CaptureNextToken(d) ::= "<d.varName> = self._input.LT(1)" CaptureNextToken(d) ::= "<d.varName> = self._input.LT(1)"
CaptureNextTokenType(d) ::= "<d.varName> = self._input.LA(1)" CaptureNextTokenType(d) ::= "<d.varName> = self._input.LA(1)"
StructDecl(struct,ctorAttrs,attrs,getters,dispatchMethods,interfaces,extensionMembers, StructDecl(struct,ctorAttrs,attrs,getters,dispatchMethods,interfaces,extensionMembers) ::= <<
superClass={ParserRuleContext}) ::= << class <struct.name>(<if(contextSuperClass)><contextSuperClass><else>ParserRuleContext<endif>):
class <struct.name>(<superClass>):
def __init__(self, parser, parent=None, invokingState=-1<struct.ctorAttrs:{a | , <a.name>=None}>): def __init__(self, parser, parent=None, invokingState=-1<struct.ctorAttrs:{a | , <a.name>=None}>):
super(<parser.name>.<struct.name>, self).__init__(parent, invokingState) super(<parser.name>.<struct.name>, self).__init__(parent, invokingState)

View File

@ -46,7 +46,7 @@ pythonTypeInitMap ::= [
// args must be <object-model-object>, <fields-resulting-in-STs> // args must be <object-model-object>, <fields-resulting-in-STs>
ParserFile(file, parser, namedActions) ::= << ParserFile(file, parser, namedActions, contextSuperClass) ::= <<
<fileHeader(file.grammarFileName, file.ANTLRVersion)> <fileHeader(file.grammarFileName, file.ANTLRVersion)>
# encoding: utf-8 # encoding: utf-8
from antlr4 import * from antlr4 import *
@ -638,9 +638,8 @@ ListLabelName(label) ::= "<label>"
CaptureNextToken(d) ::= "<d.varName> = self._input.LT(1)" CaptureNextToken(d) ::= "<d.varName> = self._input.LT(1)"
CaptureNextTokenType(d) ::= "<d.varName> = self._input.LA(1)" CaptureNextTokenType(d) ::= "<d.varName> = self._input.LA(1)"
StructDecl(struct,ctorAttrs,attrs,getters,dispatchMethods,interfaces,extensionMembers, StructDecl(struct,ctorAttrs,attrs,getters,dispatchMethods,interfaces,extensionMembers) ::= <<
superClass={ParserRuleContext}) ::= << class <struct.name>(<if(contextSuperClass)><contextSuperClass><else>ParserRuleContext<endif>):
class <struct.name>(<superClass>):
def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1<struct.ctorAttrs:{a | , <a.name><if(a.type)>:<a.type><endif>=None}>): def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1<struct.ctorAttrs:{a | , <a.name><if(a.type)>:<a.type><endif>=None}>):
super().__init__(parent, invokingState) super().__init__(parent, invokingState)

View File

@ -63,8 +63,8 @@ public class ParserFile extends OutputFile {
genVisitor = g.tool.gen_visitor; genVisitor = g.tool.gen_visitor;
grammarName = g.name; grammarName = g.name;
if (g.getOptionString("superClass") != null) { if (g.getOptionString("contextSuperClass") != null) {
contextSuperClass = new ActionText(null, g.getOptionString("superClass")); contextSuperClass = new ActionText(null, g.getOptionString("contextSuperClass"));
} }
} }
} }

View File

@ -54,4 +54,15 @@ public class GrammarInterpreterRuleContext extends InterpreterRuleContext {
public void setOuterAltNum(int outerAltNum) { public void setOuterAltNum(int outerAltNum) {
this.outerAltNum = outerAltNum; this.outerAltNum = outerAltNum;
} }
@Override
public int getAltNumber() {
// override here and called old functionality; makes it backward compatible vs changing names
return getOuterAltNum();
}
@Override
public void setAltNumber(int altNumber) {
setOuterAltNum(altNumber);
}
} }