From 81681abfb3900e4b59c54b50793be9d44ac01490 Mon Sep 17 00:00:00 2001 From: parrt Date: Sat, 18 Feb 2017 11:21:17 -0800 Subject: [PATCH] augment TerminalNode with setParent(). Technically, this is not backward compatible as it changes the interface but no one was able to create custom TerminalNodes anyway so I'm adding as it improves internal code quality. addChild now sets the parent rather than create. MUCH better. --- .../Java/src/org/antlr/v4/runtime/Parser.java | 23 ++++--------------- .../antlr/v4/runtime/ParserRuleContext.java | 20 ++++++++++------ .../antlr/v4/runtime/tree/TerminalNode.java | 12 ++++++++++ .../v4/runtime/tree/TerminalNodeImpl.java | 6 +++++ 4 files changed, 35 insertions(+), 26 deletions(-) diff --git a/runtime/Java/src/org/antlr/v4/runtime/Parser.java b/runtime/Java/src/org/antlr/v4/runtime/Parser.java index 2253eaac8..ad0dbe945 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/Parser.java +++ b/runtime/Java/src/org/antlr/v4/runtime/Parser.java @@ -20,7 +20,6 @@ import org.antlr.v4.runtime.misc.IntegerStack; import org.antlr.v4.runtime.misc.IntervalSet; import org.antlr.v4.runtime.tree.ErrorNode; import org.antlr.v4.runtime.tree.ErrorNodeImpl; -import org.antlr.v4.runtime.tree.ParseTree; import org.antlr.v4.runtime.tree.ParseTreeListener; import org.antlr.v4.runtime.tree.ParseTreeWalker; import org.antlr.v4.runtime.tree.TerminalNode; @@ -594,35 +593,21 @@ public abstract class Parser extends Recognizer { } /** How to create a token leaf node associated with a parent. - * Typically, the terminal node to create is not a function of the parent - * but this method must still set the parent pointer of the terminal node - * returned. I would prefer having {@link ParserRuleContext#addAnyChild(ParseTree)} - * set the parent pointer, but the parent pointer is implementation dependent - * and currently there is no setParent() in {@link TerminalNode} (and can't - * add method in Java 1.7 without breaking backward compatibility). + * Typically, the terminal node to create is not a function of the parent. * * @since 4.6.1 */ public TerminalNode createTerminalNode(ParserRuleContext parent, Token t) { - TerminalNodeImpl node = new TerminalNodeImpl(t); - node.parent = parent; - return node; + return new TerminalNodeImpl(t); } /** How to create an error node, given a token, associated with a parent. - * Typically, the error node to create is not a function of the parent - * but this method must still set the parent pointer of the terminal node - * returned. I would prefer having {@link ParserRuleContext#addAnyChild(ParseTree)} - * set the parent pointer, but the parent pointer is implementation dependent - * and currently there is no setParent() in {@link ErrorNode} (and can't - * add method in Java 1.7 without breaking backward compatibility). + * Typically, the error node to create is not a function of the parent. * * @since 4.6.1 */ public ErrorNode createErrorNode(ParserRuleContext parent, Token t) { - ErrorNodeImpl node = new ErrorNodeImpl(t); - node.parent = parent; - return node; + return new ErrorNodeImpl(t); } protected void addContextToParseTree() { diff --git a/runtime/Java/src/org/antlr/v4/runtime/ParserRuleContext.java b/runtime/Java/src/org/antlr/v4/runtime/ParserRuleContext.java index d39666ad5..c43cca642 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/ParserRuleContext.java +++ b/runtime/Java/src/org/antlr/v4/runtime/ParserRuleContext.java @@ -79,7 +79,8 @@ public class ParserRuleContext extends RuleContext { public ParserRuleContext() { } /** COPY a ctx (I'm deliberately not using copy constructor) to avoid - * confusion with creating node with parent. Does not copy children. + * confusion with creating node with parent. Does not copy children + * (except error leaves). * * 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 @@ -101,9 +102,8 @@ public class ParserRuleContext extends RuleContext { this.children = new ArrayList<>(); // reset parent pointer for any error nodes for (ParseTree child : ctx.children) { - if ( child instanceof ErrorNodeImpl ) { - this.children.add(child); - ((ErrorNodeImpl) child).parent = this; + if ( child instanceof ErrorNode ) { + addChild((ErrorNode)child); } } } @@ -139,12 +139,18 @@ public class ParserRuleContext extends RuleContext { return addAnyChild(ruleInvocation); } + /** Add a token leaf node child and force its parent to be this node. */ public TerminalNode addChild(TerminalNode t) { + t.setParent(this); return addAnyChild(t); } - /** Add an error node child. @since 4.6.1 */ + /** Add an error node child and force its parent to be this node. + * + * @since 4.6.1 + */ public ErrorNode addErrorNode(ErrorNode errorNode) { + errorNode.setParent(this); return addAnyChild(errorNode); } @@ -157,7 +163,7 @@ public class ParserRuleContext extends RuleContext { public TerminalNode addChild(Token matchedToken) { TerminalNodeImpl t = new TerminalNodeImpl(matchedToken); addAnyChild(t); - t.parent = this; + t.setParent(this); return t; } @@ -170,7 +176,7 @@ public class ParserRuleContext extends RuleContext { public ErrorNode addErrorNode(Token badToken) { ErrorNodeImpl t = new ErrorNodeImpl(badToken); addAnyChild(t); - t.parent = this; + t.setParent(this); return t; } diff --git a/runtime/Java/src/org/antlr/v4/runtime/tree/TerminalNode.java b/runtime/Java/src/org/antlr/v4/runtime/tree/TerminalNode.java index d8a3e65a1..1e40d2afc 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/tree/TerminalNode.java +++ b/runtime/Java/src/org/antlr/v4/runtime/tree/TerminalNode.java @@ -6,8 +6,20 @@ package org.antlr.v4.runtime.tree; +import org.antlr.v4.runtime.RuleContext; import org.antlr.v4.runtime.Token; public interface TerminalNode extends ParseTree { Token getSymbol(); + + /** Set the parent for this leaf node. + * + * Technically, this is not backward compatible as it changes + * the interface but no one was able to create custom + * TerminalNodes anyway so I'm adding as it improves internal + * code quality. + * + * @since 4.6.1 + */ + void setParent(RuleContext parent); } diff --git a/runtime/Java/src/org/antlr/v4/runtime/tree/TerminalNodeImpl.java b/runtime/Java/src/org/antlr/v4/runtime/tree/TerminalNodeImpl.java index 1882d16a8..94ad19dc9 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/tree/TerminalNodeImpl.java +++ b/runtime/Java/src/org/antlr/v4/runtime/tree/TerminalNodeImpl.java @@ -7,6 +7,7 @@ package org.antlr.v4.runtime.tree; import org.antlr.v4.runtime.Parser; +import org.antlr.v4.runtime.RuleContext; import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.misc.Interval; @@ -25,6 +26,11 @@ public class TerminalNodeImpl implements TerminalNode { @Override public ParseTree getParent() { return parent; } + @Override + public void setParent(RuleContext parent) { + this.parent = parent; + } + @Override public Token getPayload() { return symbol; }