Implements #1674 "augment TerminalNode with setParent()" for Swift target.
This commit is contained in:
parent
392c637565
commit
38c3aaae8f
|
@ -595,35 +595,21 @@ open class Parser: Recognizer<ParserATNSimulator> {
|
|||
}
|
||||
|
||||
/** 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 func createTerminalNode(parent: ParserRuleContext, t: Token) -> TerminalNode {
|
||||
let node = TerminalNodeImpl(t);
|
||||
node.parent = parent;
|
||||
return node;
|
||||
return 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 func createErrorNode(parent: ParserRuleContext, t: Token) -> ErrorNode {
|
||||
let node = ErrorNode(t);
|
||||
node.parent = parent;
|
||||
return node;
|
||||
return ErrorNode(t);
|
||||
}
|
||||
|
||||
internal func addContextToParseTree() {
|
||||
|
|
|
@ -72,6 +72,14 @@ open class ParserRuleContext: RuleContext {
|
|||
|
||||
/** COPY a ctx (I'm deliberately not using copy constructor) to avoid
|
||||
* confusion with creating node with parent. Does not copy children.
|
||||
*
|
||||
* 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!
|
||||
*/
|
||||
open func copyFrom(_ ctx: ParserRuleContext) {
|
||||
self.parent = ctx.parent
|
||||
|
@ -81,13 +89,12 @@ open class ParserRuleContext: RuleContext {
|
|||
self.stop = ctx.stop
|
||||
|
||||
// copy any error nodes to alt label node
|
||||
if ctx.children != nil{
|
||||
if ctx.children != nil {
|
||||
self.children = Array<ParseTree>()
|
||||
// reset parent pointer for any error nodes
|
||||
for child: ParseTree in ctx.children! {
|
||||
if child is ErrorNode{
|
||||
self.children?.append(child)
|
||||
( (child as! ErrorNode)).parent = self
|
||||
if child is ErrorNode {
|
||||
addChild(child as! ErrorNode)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -130,14 +137,20 @@ open class ParserRuleContext: RuleContext {
|
|||
return addAnyChild(ruleInvocation)
|
||||
}
|
||||
|
||||
/** Add a token leaf node child and force its parent to be this node. */
|
||||
@discardableResult
|
||||
open func addChild(_ t: TerminalNode) -> TerminalNode {
|
||||
t.setParent(self)
|
||||
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
|
||||
*/
|
||||
@discardableResult
|
||||
open func addErrorNode(_ errorNode: ErrorNode) -> ErrorNode {
|
||||
errorNode.setParent(self)
|
||||
return addAnyChild(errorNode)
|
||||
}
|
||||
|
||||
|
@ -150,7 +163,7 @@ open class ParserRuleContext: RuleContext {
|
|||
open func addChild(_ matchedToken: Token) -> TerminalNode {
|
||||
let t: TerminalNodeImpl = TerminalNodeImpl(matchedToken)
|
||||
addAnyChild(t)
|
||||
t.parent = self
|
||||
t.setParent(self)
|
||||
return t
|
||||
}
|
||||
|
||||
|
@ -164,7 +177,7 @@ open class ParserRuleContext: RuleContext {
|
|||
open func addErrorNode(_ badToken: Token) -> ErrorNode {
|
||||
let t: ErrorNode = ErrorNode(badToken)
|
||||
addAnyChild(t)
|
||||
t.parent = self
|
||||
t.setParent(self)
|
||||
return t
|
||||
}
|
||||
|
||||
|
|
|
@ -9,4 +9,18 @@ public class TerminalNode: ParseTree {
|
|||
fatalError()
|
||||
|
||||
}
|
||||
|
||||
/** 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
|
||||
*/
|
||||
public func setParent(_ parent: RuleContext) {
|
||||
RuntimeException(" must overriden !")
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,11 @@ public class TerminalNodeImpl: TerminalNode {
|
|||
return parent
|
||||
}
|
||||
|
||||
override
|
||||
public func setParent(_ parent: RuleContext) {
|
||||
self.parent = parent
|
||||
}
|
||||
|
||||
override
|
||||
public func getPayload() -> AnyObject {
|
||||
return symbol
|
||||
|
|
Loading…
Reference in New Issue