| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- # Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
- # Use of this file is governed by the BSD 3-clause license that
- # can be found in the LICENSE.txt file in the project root.
- #* A rule invocation record for parsing.
- #
- # Contains all of the information about the current rule not stored in the
- # RuleContext. It handles parse tree children list, Any ATN state
- # tracing, and the default values available for rule indications:
- # start, stop, rule index, current alt number, current
- # ATN state.
- #
- # Subclasses made for each rule and grammar track the parameters,
- # return values, locals, and labels specific to that rule. These
- # are the objects that are returned from rules.
- #
- # Note text is not an actual field of a rule return value; it is computed
- # from start and stop using the input stream's toString() method. I
- # could add a ctor to this so that we can pass in and store the input
- # stream, but I'm not sure we want to do that. It would seem to be undefined
- # to get the .text property anyway if the rule matches tokens from multiple
- # input streams.
- #
- # I do not use getters for fields of objects that are used simply to
- # group values such as this aggregate. The getters/setters are there to
- # satisfy the superclass interface.
- from antlr4.RuleContext import RuleContext
- from antlr4.Token import Token
- from antlr4.tree.Tree import ParseTreeListener, ParseTree, TerminalNodeImpl, ErrorNodeImpl, TerminalNode, \
- INVALID_INTERVAL
- # need forward declaration
- ParserRuleContext = None
- class ParserRuleContext(RuleContext):
- __slots__ = ('children', 'start', 'stop', 'exception')
- def __init__(self, parent:ParserRuleContext = None, invokingStateNumber:int = None ):
- super().__init__(parent, invokingStateNumber)
- #* If we are debugging or building a parse tree for a visitor,
- # we need to track all of the tokens and rule invocations associated
- # with this rule's context. This is empty for parsing w/o tree constr.
- # operation because we don't the need to track the details about
- # how we parse this rule.
- #/
- self.children = None
- self.start = None
- self.stop = None
- # The exception that forced this rule to return. If the rule successfully
- # completed, this is {@code null}.
- 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
- self.invokingState = ctx.invokingState
- self.children = None
- 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
- def exitRule(self, listener:ParseTreeListener):
- pass
- #* Does not set parent link; other add methods do that#/
- def addChild(self, child:ParseTree):
- if self.children is None:
- self.children = []
- self.children.append(child)
- return child
- #* Used by enterOuterAlt to toss out a RuleContext previously added as
- # we entered a rule. If we have # label, we will need to remove
- # generic ruleContext object.
- #/
- def removeLastChild(self):
- if self.children is not None:
- del self.children[len(self.children)-1]
- def addTokenNode(self, token:Token):
- node = TerminalNodeImpl(token)
- self.addChild(node)
- node.parentCtx = self
- return node
- def addErrorNode(self, badToken:Token):
- node = ErrorNodeImpl(badToken)
- self.addChild(node)
- node.parentCtx = self
- return node
- def getChild(self, i:int, ttype:type = None):
- if ttype is None:
- return self.children[i] if len(self.children)>i else None
- else:
- for child in self.getChildren():
- if not isinstance(child, ttype):
- continue
- if i==0:
- return child
- i -= 1
- return None
- def getChildren(self, predicate = None):
- if self.children is not None:
- for child in self.children:
- if predicate is not None and not predicate(child):
- continue
- yield child
- def getToken(self, ttype:int, i:int):
- for child in self.getChildren():
- if not isinstance(child, TerminalNode):
- continue
- if child.symbol.type != ttype:
- continue
- if i==0:
- return child
- i -= 1
- return None
- def getTokens(self, ttype:int ):
- if self.getChildren() is None:
- return []
- tokens = []
- for child in self.getChildren():
- if not isinstance(child, TerminalNode):
- continue
- if child.symbol.type != ttype:
- continue
- tokens.append(child)
- return tokens
- def getTypedRuleContext(self, ctxType:type, i:int):
- return self.getChild(i, ctxType)
- def getTypedRuleContexts(self, ctxType:type):
- children = self.getChildren()
- if children is None:
- return []
- contexts = []
- for child in children:
- if not isinstance(child, ctxType):
- continue
- contexts.append(child)
- return contexts
- def getChildCount(self):
- return len(self.children) if self.children else 0
- def getSourceInterval(self):
- if self.start is None or self.stop is None:
- return INVALID_INTERVAL
- else:
- return (self.start.tokenIndex, self.stop.tokenIndex)
- RuleContext.EMPTY = ParserRuleContext()
- class InterpreterRuleContext(ParserRuleContext):
- def __init__(self, parent:ParserRuleContext, invokingStateNumber:int, ruleIndex:int):
- super().__init__(parent, invokingStateNumber)
- self.ruleIndex = ruleIndex
|