%>
+
+Production(p) ::= <%%>
+
+Result(r) ::= <%%>
+
+ParserPropertyMember() ::= <<
+@members {
+public function Property() : bool
+{
+ return true;
+}
+}
+>>
+
+ParserPropertyCall(p, call) ::= "->"
+
+PositionAdjustingLexerDef() ::= <<
+class PositionAdjustingLexerATNSimulator extends LexerATNSimulator {
+ public function resetAcceptPosition(CharStream \$input, int \$index, int \$line, int \$charPositionInLine) : void {
+ \$input->seek(\$index);
+ \$this->line = \$line;
+ \$this->charPositionInLine = \$charPositionInLine;
+ \$this->consume(\$input);
+ }
+}
+>>
+
+PositionAdjustingLexer() ::= <<
+public function nextToken() : Antlr\\Antlr4\\Runtime\\Token
+{
+ if (!\$this->interp instanceof PositionAdjustingLexerATNSimulator) {
+ \$this->interp = new PositionAdjustingLexerATNSimulator(\$this, self::\$atn, self::\$decisionToDFA, self::\$sharedContextCache);
+ }
+
+ return parent::nextToken();
+}
+
+public function emit() : Antlr\\Antlr4\\Runtime\\Token
+{
+ switch (\$this->type) {
+ case self::TOKENS:
+ \$this->handleAcceptPositionForKeyword('tokens');
+ break;
+
+ case self::LABEL:
+ \$this->handleAcceptPositionForIdentifier();
+ break;
+ }
+
+ return parent::emit();
+}
+
+private function handleAcceptPositionForIdentifier() : bool
+{
+ \$tokenText = \$this->getText();
+ \$identifierLength = 0;
+ while (\$identifierLength \< \strlen(\$tokenText) && self::isIdentifierChar(\$tokenText[\$identifierLength])) {
+ \$identifierLength++;
+ }
+
+ if (\$this->getInputStream()->getIndex() > \$this->tokenStartCharIndex + \$identifierLength) {
+ \$offset = \$identifierLength - 1;
+ \$this->getInterpreter()->resetAcceptPosition(\$this->getInputStream(), \$this->tokenStartCharIndex + \$offset, \$this->tokenStartLine, \$this->tokenStartCharPositionInLine + \$offset);
+
+ return true;
+ }
+
+ return false;
+}
+
+private function handleAcceptPositionForKeyword(string \$keyword) : bool
+{
+ if (\$this->getInputStream()->getIndex() > \$this->tokenStartCharIndex + \strlen(\$keyword)) {
+ \$offset = \strlen(\$keyword) - 1;
+ \$this->getInterpreter()->resetAcceptPosition(\$this->getInputStream(), \$this->tokenStartCharIndex + \$offset, \$this->tokenStartLine, \$this->tokenStartCharPositionInLine + \$offset);
+
+ return true;
+ }
+
+ return false;
+}
+
+private static function isIdentifierChar(string \$c) : bool
+{
+ return \ctype_alnum(\$c) || \$c === '_';
+}
+>>
+
+BasicListener(X) ::= <<
+@parser::definitions {
+class LeafListener extends TBaseListener
+{
+ public function visitTerminal(Antlr\\Antlr4\\Runtime\\Tree\\TerminalNode \$node) : void
+ {
+ echo \$node->getSymbol()->getText() . \PHP_EOL;
+ }
+}
+}
+>>
+
+WalkListener(s) ::= <<
+\$walker = new Antlr\\Antlr4\\Runtime\\Tree\\ParseTreeWalker();
+\$walker->walk(new LeafListener(), );
+>>
+
+TreeNodeWithAltNumField(X) ::= <<
+@parser::contexts {
+class MyRuleNode extends ParserRuleContext
+{
+ public \$altNum;
+
+ public function getAltNumber() : int
+ {
+ return \$this->altNum;
+ }
+
+ public function setAltNumber(int \$altNum) : void
+ {
+ \$this->altNum = \$altNum;
+ }
+}
+}
+>>
+
+TokenGetterListener(X) ::= <<
+@parser::definitions {
+class LeafListener extends TBaseListener {
+ public function exitA(Context\\AContext \$ctx) : void {
+ if (\$ctx->getChildCount() === 2) {
+ echo \sprintf('%s %s [%s]',\$ctx->INT(0)->getSymbol()->getText(), \$ctx->INT(1)->getSymbol()->getText(), \implode(', ', \$ctx->INT())) . \PHP_EOL;
+ } else {
+ echo \$ctx->ID()->getSymbol() . \PHP_EOL;
+ }
+ }
+}
+}
+>>
+
+RuleGetterListener(X) ::= <<
+@parser::definitions {
+class LeafListener extends TBaseListener {
+ public function exitA(Context\\AContext \$ctx) : void
+ {
+ if (\$ctx->getChildCount() === 2) {
+ echo \sprintf('%s %s %s', \$ctx->b(0)->start->getText(), \$ctx->b(1)->start->getText(),\$ctx->b()[0]->start->getText()) . \PHP_EOL;
+ } else {
+ echo \$ctx->b(0)->start->getText() . \PHP_EOL;
+ }
+ }
+}
+}
+>>
+
+
+LRListener(X) ::= <<
+@parser::definitions {
+class LeafListener extends TBaseListener {
+ public function exitE(Context\\EContext \$ctx) : void
+ {
+ if (\$ctx->getChildCount() === 3) {
+ echo \sprintf('%s %s %s', \$ctx->e(0)->start->getText(), \$ctx->e(1)->start->getText(), \$ctx->e()[0]->start->getText()) . \PHP_EOL;
+ } else {
+ echo \$ctx->INT()->getSymbol()->getText() . \PHP_EOL;
+ }
+ }
+}
+}
+>>
+
+LRWithLabelsListener(X) ::= <<
+@parser::definitions {
+class LeafListener extends TBaseListener
+{
+ public function exitCall(Context\\CallContext \$ctx) : void {
+ echo \sprintf('%s %s',\$ctx->e()->start->getText(),\$ctx->eList()) . \PHP_EOL;
+ }
+
+ public function exitInt(Context\\IntContext \$ctx) : void {
+ echo \$ctx->INT()->getSymbol()->getText() . \PHP_EOL;
+ }
+}
+}
+>>
+
+DeclareContextListGettersFunction() ::= <<
+public function foo() : void {
+ \$s = null;
+ \$a = \$s->a();
+ \$b = \$s->b();
+}
+>>
+
+Declare_foo() ::= <<
+public function foo() : void {
+ echo 'foo' . \PHP_EOL;
+}
+>>
+
+Invoke_foo() ::= "\$this->foo();"
+
+Declare_pred() ::= <>
+
+Invoke_pred(v) ::= "\$this->pred()"
+
+ParserTokenType(t) ::= "Parser::"
+ContextRuleFunction(ctx, rule) ::= "->"
+StringType() ::= ""
+ContextMember(ctx, subctx, member) ::= "->->"
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/templates/Python2.test.stg b/runtime-testsuite/resources/org/antlr/v4/test/runtime/templates/Python2.test.stg
index cc0d9d9c2..3102f4120 100644
--- a/runtime-testsuite/resources/org/antlr/v4/test/runtime/templates/Python2.test.stg
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/templates/Python2.test.stg
@@ -14,6 +14,8 @@ Cast(t,v) ::= ""
Append(a,b) ::= " + str()"
+AppendStr(a,b) ::= " + "
+
Concat(a,b) ::= ""
DeclareLocal(s,v) ::= " = "
@@ -26,6 +28,12 @@ InitIntMember(n,v) ::= <% = %>
InitBooleanMember(n,v) ::= <% = %>
+InitIntVar(n,v) ::= <%%>
+
+IntArg(n) ::= ""
+
+VarRef(n) ::= ""
+
GetMember(n) ::= <%self.%>
SetMember(n,v) ::= <%self. = %>
@@ -94,6 +102,8 @@ def Property(self):
ParserPropertyCall(p, call) ::= "."
+PositionAdjustingLexerDef() ::= ""
+
PositionAdjustingLexer() ::= <<
def resetAcceptPosition(self, index, line, column):
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/templates/Python3.test.stg b/runtime-testsuite/resources/org/antlr/v4/test/runtime/templates/Python3.test.stg
index c91563017..858b76113 100644
--- a/runtime-testsuite/resources/org/antlr/v4/test/runtime/templates/Python3.test.stg
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/templates/Python3.test.stg
@@ -14,6 +14,8 @@ Cast(t,v) ::= ""
Append(a,b) ::= " + str(