diff --git a/runtime-testsuite/test/org/antlr/v4/test/runtime/descriptors/ParseTreesDescriptors.java b/runtime-testsuite/test/org/antlr/v4/test/runtime/descriptors/ParseTreesDescriptors.java index ea3374f63..6db9769e8 100644 --- a/runtime-testsuite/test/org/antlr/v4/test/runtime/descriptors/ParseTreesDescriptors.java +++ b/runtime-testsuite/test/org/antlr/v4/test/runtime/descriptors/ParseTreesDescriptors.java @@ -112,7 +112,7 @@ public class ParseTreesDescriptors { @Override public boolean ignore(String targetName) { - return !targetName.equals("Java"); + return !targetName.matches("Java|Python2|Python3"); } } diff --git a/runtime/Python2/src/antlr4/ParserRuleContext.py b/runtime/Python2/src/antlr4/ParserRuleContext.py index f0eb4995f..8f68b2ef1 100644 --- a/runtime/Python2/src/antlr4/ParserRuleContext.py +++ b/runtime/Python2/src/antlr4/ParserRuleContext.py @@ -46,6 +46,15 @@ class ParserRuleContext(RuleContext): self.exception = None #* COPY a ctx (I'm deliberately not using copy constructor)#/ + # + # This is used in the generated parser code to flip a generic XContext + # node for rule X to a YContext for alt label Y. In that sense, it is + # not really a generic copy function. + # + # If we do an error sync() at start of a rule, we might add error nodes + # to the generic XContext so this function must copy those nodes to + # the YContext as well else they are lost! + #/ def copyFrom(self, ctx): # from RuleContext self.parentCtx = ctx.parentCtx @@ -54,6 +63,15 @@ class ParserRuleContext(RuleContext): self.start = ctx.start self.stop = ctx.stop + # copy any error nodes to alt label node + if ctx.children is not None: + self.children = [] + # reset parent pointer for any error nodes + for child in ctx.children: + if isinstance(child, ErrorNodeImpl): + self.children.append(child) + child.parentCtx = self + # Double dispatch methods for listeners def enterRule(self, listener): pass diff --git a/runtime/Python3/src/antlr4/ParserRuleContext.py b/runtime/Python3/src/antlr4/ParserRuleContext.py index e72c6e04f..7ac4a750e 100644 --- a/runtime/Python3/src/antlr4/ParserRuleContext.py +++ b/runtime/Python3/src/antlr4/ParserRuleContext.py @@ -51,6 +51,15 @@ class ParserRuleContext(RuleContext): self.exception = None #* COPY a ctx (I'm deliberately not using copy constructor)#/ + # + # This is used in the generated parser code to flip a generic XContext + # node for rule X to a YContext for alt label Y. In that sense, it is + # not really a generic copy function. + # + # If we do an error sync() at start of a rule, we might add error nodes + # to the generic XContext so this function must copy those nodes to + # the YContext as well else they are lost! + #/ def copyFrom(self, ctx:ParserRuleContext): # from RuleContext self.parentCtx = ctx.parentCtx @@ -59,6 +68,15 @@ class ParserRuleContext(RuleContext): self.start = ctx.start self.stop = ctx.stop + # copy any error nodes to alt label node + if ctx.children is not None: + self.children = [] + # reset parent pointer for any error nodes + for child in ctx.children: + if isinstance(child, ErrorNodeImpl): + self.children.append(child) + child.parentCtx = self + # Double dispatch methods for listeners def enterRule(self, listener:ParseTreeListener): pass