def getRuleTagToken(self, tree:ParseTree):
     if isinstance( tree, RuleNode ):
         if tree.getChildCount()==1 and isinstance(tree.getChild(0), TerminalNode ):
             c = tree.getChild(0)
             if isinstance( c.symbol, RuleTagToken ):
                 return c.symbol
     return None
Example #2
0
 def getRuleTagToken(self, tree:ParseTree):
     if isinstance( tree, RuleNode ):
         if tree.getChildCount()==1 and isinstance(tree.getChild(0), TerminalNode ):
             c = tree.getChild(0)
             if isinstance( c.symbol, RuleTagToken ):
                 return c.symbol
     return None
Example #3
0
 def getPayload(self, tree: ParseTree):
     if tree.getChildCount() == 0:
         # A leaf node: return the tree's payload, which is a Token.
         return tree.getPayload()
     else:
         # The name for parser rule `foo` will be `FooContext`. Strip `Context` and
         # lower case the first character.
         ruleNume = tree.__class__.__name__.replace('Context', '')
         return ruleNume
Example #4
0
 def getPayload(self, tree:ParseTree):
     if tree.getChildCount() == 0:
         # A leaf node: return the tree's payload, which is a Token.
         return tree.getPayload()
     else:
         # The name for parser rule `foo` will be `FooContext`. Strip `Context` and
         # lower case the first character.
         ruleNume = tree.__class__.__name__.replace('Context', '')
         return ruleNume
Example #5
0
 def _findAllNodes(cls, t:ParseTree, index:int, findTokens:bool, nodes:list):
     from antlr4.ParserRuleContext import ParserRuleContext
     # check this node (the root) first
     if findTokens and isinstance(t, TerminalNode):
         if t.symbol.type==index:
             nodes.append(t)
     elif not findTokens and isinstance(t, ParserRuleContext):
         if t.ruleIndex == index:
             nodes.append(t)
     # check children
     for i in range(0, t.getChildCount()):
         cls._findAllNodes(t.getChild(i), index, findTokens, nodes)
Example #6
0
 def _findAllNodes(cls, t:ParseTree, index:int, findTokens:bool, nodes:list):
     from antlr4.ParserRuleContext import ParserRuleContext
     # check this node (the root) first
     if findTokens and isinstance(t, TerminalNode):
         if t.symbol.type==index:
             nodes.append(t)
     elif not findTokens and isinstance(t, ParserRuleContext):
         if t.ruleIndex == index:
             nodes.append(t)
     # check children
     for i in range(0, t.getChildCount()):
         cls._findAllNodes(t.getChild(i), index, findTokens, nodes)
Example #7
0
 def walk(self, tree:ParseTree, ast):
     if tree.getChildCount() > 1:
         for child in tree.getChildren():
             # Don't add useless token to tree
             if isinstance(child.getPayload(), antlr4.Token) and child.symbol.type in useless_tokens:
                 continue
             temp = CstFlattened(ast, child)
             if not isinstance(temp.payload, antlr4.Token):
                 # Only traverse down if the payload is not a Token.
                 self.walk(child, temp)
     else:
         super().walk(tree, ast)
Example #8
0
 def walk(self, tree: ParseTree, ast):
     if tree.getChildCount() > 1:
         for child in tree.getChildren():
             # Don't add useless token to tree
             if isinstance(
                     child.getPayload(),
                     antlr4.Token) and child.symbol.type in useless_tokens:
                 continue
             temp = CstFlattened(ast, child)
             if not isinstance(temp.payload, antlr4.Token):
                 # Only traverse down if the payload is not a Token.
                 self.walk(child, temp)
     else:
         super().walk(tree, ast)
Example #9
0
 def walk(self, tree: ParseTree, ast):
     if tree.getChildCount() == 0:
         # We've reached a leaf. We must create a new instance of an AST because
         # the constructor will make sure this new instance is added to its parent's
         # child nodes.
         CstFlattened(ast, tree)
     elif tree.getChildCount() == 1:
         # We've reached an inner node with a single child: we don't include this in
         # our AST.
         self.walk(tree.getChild(0), ast)
     elif tree.getChildCount() > 1:
         for child in tree.getChildren():
             temp = CstFlattened(ast, child)
             if not isinstance(temp.payload, antlr4.Token):
                 # Only traverse down if the payload is not a Token.
                 self.walk(child, temp)
Example #10
0
 def walk(self, tree:ParseTree, ast):
     if tree.getChildCount() == 0:
         # We've reached a leaf. We must create a new instance of an AST because
         # the constructor will make sure this new instance is added to its parent's
         # child nodes.
         CstFlattened(ast, tree)
     elif tree.getChildCount() == 1:
         # We've reached an inner node with a single child: we don't include this in
         # our AST.
         self.walk(tree.getChild(0), ast)
     elif tree.getChildCount() > 1:
         for child in tree.getChildren():
             temp = CstFlattened(ast, child)
             if not isinstance(temp.payload, antlr4.Token):
                 # Only traverse down if the payload is not a Token.
                 self.walk(child, temp)
Example #11
0
    def matchImpl(self, tree: ParseTree, patternTree: ParseTree, labels: dict):
        if tree is None:
            raise Exception("tree cannot be null")
        if patternTree is None:
            raise Exception("patternTree cannot be null")

        # x and <ID>, x and y, or x and x; or could be mismatched types
        if isinstance(tree, TerminalNode) and isinstance(
                patternTree, TerminalNode):
            mismatchedNode = None
            # both are tokens and they have same type
            if tree.symbol.type == patternTree.symbol.type:
                if isinstance(patternTree.symbol, TokenTagToken):  # x and <ID>
                    tokenTagToken = patternTree.symbol
                    # track label->list-of-nodes for both token name and label (if any)
                    self.map(labels, tokenTagToken.tokenName, tree)
                    if tokenTagToken.label is not None:
                        self.map(labels, tokenTagToken.label, tree)
                elif tree.getText() == patternTree.getText():
                    # x and x
                    pass
                else:
                    # x and y
                    if mismatchedNode is None:
                        mismatchedNode = tree
            else:
                if mismatchedNode is None:
                    mismatchedNode = tree

            return mismatchedNode

        if isinstance(tree, ParserRuleContext) and isinstance(
                patternTree, ParserRuleContext):
            mismatchedNode = None
            # (expr ...) and <expr>
            ruleTagToken = self.getRuleTagToken(patternTree)
            if ruleTagToken is not None:
                m = None
                if tree.ruleContext.ruleIndex == patternTree.ruleContext.ruleIndex:
                    # track label->list-of-nodes for both rule name and label (if any)
                    self.map(labels, ruleTagToken.ruleName, tree)
                    if ruleTagToken.label is not None:
                        self.map(labels, ruleTagToken.label, tree)
                else:
                    if mismatchedNode is None:
                        mismatchedNode = tree

                return mismatchedNode

            # (expr ...) and (expr ...)
            if tree.getChildCount() != patternTree.getChildCount():
                if mismatchedNode is None:
                    mismatchedNode = tree
                return mismatchedNode

            n = tree.getChildCount()
            for i in range(0, n):
                childMatch = self.matchImpl(tree.getChild(i),
                                            patternTree.getChild(i), labels)
                if childMatch is not None:
                    return childMatch

            return mismatchedNode

        # if nodes aren't both tokens or both rule nodes, can't match
        return tree
    def matchImpl(self, tree:ParseTree, patternTree:ParseTree, labels:dict):
        if tree is None:
            raise Exception("tree cannot be null")
        if patternTree is None:
            raise Exception("patternTree cannot be null")

        # x and <ID>, x and y, or x and x; or could be mismatched types
        if isinstance(tree, TerminalNode) and isinstance(patternTree, TerminalNode ):
            mismatchedNode = None
            # both are tokens and they have same type
            if tree.symbol.type == patternTree.symbol.type:
                if isinstance( patternTree.symbol, TokenTagToken ): # x and <ID>
                    tokenTagToken = patternTree.symbol
                    # track label->list-of-nodes for both token name and label (if any)
                    self.map(labels, tokenTagToken.tokenName, tree)
                    if tokenTagToken.label is not None:
                        self.map(labels, tokenTagToken.label, tree)
                elif tree.getText()==patternTree.getText():
                    # x and x
                    pass
                else:
                    # x and y
                    if mismatchedNode is None:
                        mismatchedNode = tree
            else:
                if mismatchedNode is None:
                    mismatchedNode = tree

            return mismatchedNode

        if isinstance(tree, ParserRuleContext) and isinstance(patternTree, ParserRuleContext):
            mismatchedNode = None
            # (expr ...) and <expr>
            ruleTagToken = self.getRuleTagToken(patternTree)
            if ruleTagToken is not None:
                m = None
                if tree.ruleContext.ruleIndex == patternTree.ruleContext.ruleIndex:
                    # track label->list-of-nodes for both rule name and label (if any)
                    self.map(labels, ruleTagToken.ruleName, tree)
                    if ruleTagToken.label is not None:
                        self.map(labels, ruleTagToken.label, tree)
                else:
                    if mismatchedNode is None:
                        mismatchedNode = tree

                return mismatchedNode

            # (expr ...) and (expr ...)
            if tree.getChildCount()!=patternTree.getChildCount():
                if mismatchedNode is None:
                    mismatchedNode = tree
                return mismatchedNode

            n = tree.getChildCount()
            for i in range(0, n):
                childMatch = self.matchImpl(tree.getChild(i), patternTree.getChild(i), labels)
                if childMatch is not None:
                    return childMatch

            return mismatchedNode

        # if nodes aren't both tokens or both rule nodes, can't match
        return tree
Example #13
0
 def descendants(cls, t:ParseTree):
     nodes = [t]
     for i in range(0, t.getChildCount()):
         nodes.extend(cls.descendants(t.getChild(i)))
     return nodes
Example #14
0
 def descendants(cls, t: ParseTree):
     nodes = [t]
     for i in range(0, t.getChildCount()):
         nodes.extend(cls.descendants(t.getChild(i)))
     return nodes
Example #15
0
def adopt(parent: ParserRuleContext, child: ParseTree):
    """Convenience function to create a bidirectional parent-child relationship."""
    addChild(parent, child)
    child.parentCtx = parent