Python 3.x ANTLR4:如何使用python3获取源代码中的位置

Python 3.x ANTLR4:如何使用python3获取源代码中的位置,python-3.x,antlr,antlr4,Python 3.x,Antlr,Antlr4,我想使用ANTLR4使用Python3程序分析COBOL文件。 为此,我需要知道标记(比如MOVE语句)在文件中出现的位置(至少是行,如果可能还包括字符位置)。我特别需要这个,因为我想解析COPY语句(类似于C中的#include),并确保在解析文件时知道我在哪一部分 我已经在这里搜索并找到了类似的问题,但它们似乎不再适用于python实现。例如,这个: 如果我尝试此解决方案,我会在调用getStartIndex()或getSymbol()(AttributeError:“StartRuleCo

我想使用ANTLR4使用Python3程序分析COBOL文件。 为此,我需要知道标记(比如MOVE语句)在文件中出现的位置(至少是行,如果可能还包括字符位置)。我特别需要这个,因为我想解析COPY语句(类似于C中的#include),并确保在解析文件时知道我在哪一部分

我已经在这里搜索并找到了类似的问题,但它们似乎不再适用于python实现。例如,这个:


如果我尝试此解决方案,我会在调用getStartIndex()或getSymbol()(AttributeError:“StartRuleContext”对象没有属性“getStartIndex”)时立即出错。

似乎只有TerminalNodeSimple类型的对象包含所需信息。我提出了以下代码,尽管我不太高兴必须使用instanceof()来检查节点类型是否正确。 如果有人有更干净的方式获取信息,请让我知道

class Cobol85PreprocessorPrintListener(Cobol85PreprocessorListener):
    def enterEveryRule(self, ctx):
        print("<< enterEveryRule type ", type(ctx))
        terminal= ctx
        depth= 0
        while terminal is not None and not isinstance(terminal, tree.Tree.TerminalNode):
            terminal= terminal.getChild(0)
            depth+= 1
        if terminal is not None:
            symbol= terminal.getSymbol()
            print('\tThe info was found in depth %d here:' % depth)
            self.printSymbolDetails(symbol, '\t\t')

    def printSymbolDetails(self, symbol, indent='\t'):
        print(indent + 'symbol=', symbol)
        print(indent + 'text=  ', symbol.text)
        print(indent + 'start= ', symbol.start)
        print(indent + 'stop=  ', symbol.stop)
        print(indent + 'line=  ', symbol.line)
        print(indent + 'column=', symbol.column)
类Cobol85PreprocessorListener(Cobol85PreprocessorListener):
def enterEveryRule(自身,ctx):

print(一种简单且更正确的方法是使用
visiterminal
方法。ANTLR listener提供了在访问终端节点时调用的此方法。然后,您可以从令牌中获取所需的信息

    def visitTerminal(self, node: TerminalNode):
       terminal = node.getSymbol()
        self.print_symbol_detail(terminal)

    def print_symbol_detail(self, terminal, indent='\t'):
       print(indent + 'symbol=', terminal)
       print(indent + 'text=  ', terminal.text)
       print(indent + 'type=  ', terminal.type)
       print(indent + 'start= ', terminal.start)
       print(indent + 'stop=  ', terminal.stop)
       print(indent + 'line=  ', terminal.line)
       print(indent + 'column=', terminal.column)
       print('-'*75)

原理仍然是一样的。请查看python ANTLR4运行时的接口/源代码,以了解确切的命名方式。正如Mike提到的,运行时API基本相同,但从来没有100%。请查看Python3运行时: