【问题标题】:ANTLR4 How would I extract python expression variablesANTLR4 如何提取 python 表达式变量
【发布时间】:2021-01-20 14:24:29
【问题描述】:

使用以下 ANTLR 语法:https://github.com/bkiers/python3-parser/blob/master/src/main/antlr4/nl/bigo/pythonparser/Python3.g4 我想从给定的表达式中解析,比如说:

x.split(y, 3)

x + y

变量 x 和 y。我将如何实现这一目标?

我尝试了以下方法,但它似乎很麻烦,因为我必须添加所有内置 python 函数:

定义一个监听器接口

const listener = new MyPythonListener()
antlr.tree.ParseTreeWalker.DEFAULT.walk(listener, abstractTree)

使用正则表达式+模式匹配:

const symbolicNames = ['TRUE', 'FALSE', 'NUMEBRS', 'STRING', 'LIST', 'TUPLE', 'DICTIONARY', 'INT', 'LONG', 'FLOAT', 'COMPLEX',
'BOOL', 'STR', 'INT', 'RANGE', 'NONE', 'LEN']

class MyPythonListener extends Python3Listener {
    variables = []

    enterExpr(ctx) {
        const text = this.getElementText(ctx)
        if (text && this.verifyIsVariable(text)) {
            this.variables.push(text)
        }
    }

    verifyIsVariable(leafText) {
        return !leafText.includes('"') && !leafText.includes('\'') && isNaN(leafText) &&
            !symbolicNames.includes(leafText.toUpperCase()) && leafText.match(/^[0-9a-zA-Z_]+$/)
    }
}

【问题讨论】:

  • 您不能使用该语法来提取变量。您可以根据链接到的语法/规范创建 ANTLR 语法,然后使用该 ANTLR 语法来提取变量。 ANTLR 语法很可能不是规范的一对一翻译,所以没有看到 ANTLR 语法就无法回答您的问题。那么,你能发布你的 ANTLR 语法吗?
  • 顺便说一句,使用 Python 自己的 parser/ast 包从 Python 代码中检索这些东西可能更容易:docs.python.org/3/library/ast.html
  • 感谢您的回复,这是我正在使用的 ANTLR 语法:github.com/bkiers/python3-parser - 感谢您将其作为开源分享
  • 不客气。在该存储库的自述文件中,我链接到一个类,该类给出了如何从解析树中提取内容的示例。您能否编辑自己的问题并添加您自己尝试过的内容?
  • @BartKiers 我编辑了问题并添加了一种我尝试使用侦听器+模式匹配的方法。我还尝试了另一种变体,通过生成简化的树并获取叶子,但它看起来并不乐观,欢迎任何关于如何解决此类问题的建议,因为我没有足够的经验来开始一些有希望的事情,我可以'在任何地方都找不到适当的指导。谢谢!

标签: java python variables antlr4


【解决方案1】:

我没有仔细看它,但是在检查了 Python 代码的解析树之后:

def some_method_name(some_param_name):
    x.split(y, 3)

变量名似乎是原子规则的子项:

atom
 : '(' ( yield_expr | testlist_comp )? ')' 
 | '[' testlist_comp? ']'  
 | '{' dictorsetmaker? '}' 
 | NAME 
 | number 
 | str+ 
 | '...' 
 | NONE
 | TRUE
 | FALSE
 ;

其中NAME 是一个变量名。

所以你可以这样做:

String source = "def some_method_name(some_param_name):\n    x.split(y, 3)\n";
Python3Lexer lexer = new Python3Lexer(CharStreams.fromString(source));
Python3Parser parser = new Python3Parser(new CommonTokenStream(lexer));

ParseTreeWalker.DEFAULT.walk(new Python3BaseListener() {
    @Override
    public void enterAtom(Python3Parser.AtomContext ctx) {
        if (ctx.NAME() != null) {
            System.out.println(ctx.NAME().getText());
        }
    }
}, parser.file_input());

将打印:

x
y

而不是方法和参数名称。

再说一遍:没有经过彻底测试,我把它留给你。您可以像这样漂亮地打印解析树:

String source = "def some_method_name(some_param_name):\n    x.split(y, 3)\n";
Python3Lexer lexer = new Python3Lexer(CharStreams.fromString(source));
Python3Parser parser = new Python3Parser(new CommonTokenStream(lexer));

System.out.println(new Builder.Tree(source).toStringASCII());

自行检查您感兴趣的节点在解析树中的位置。上面的代码将打印:

'- file_input
   |- stmt
   |  '- compound_stmt
   |     '- funcdef
   |        |- def
   |        |- some_method_name
   |        |- parameters
   |        |  |- (
   |        |  |- typedargslist
   |        |  |  '- tfpdef
   |        |  |     '- some_param
   |        |  '- )
   |        |- :
   |        '- suite
   |           |- <NEWLINE>
   |           |- <INDENT>
   |           |- stmt
   |           |  '- simple_stmt
   |           |     |- small_stmt
   |           |     |  '- expr_stmt
   |           |     |     '- testlist_star_expr
   |           |     |        '- test
   |           |     |           '- or_test
   |           |     |              '- and_test
   |           |     |                 '- not_test
   |           |     |                    '- comparison
   |           |     |                       '- star_expr
   |           |     |                          '- expr
   |           |     |                             '- xor_expr
   |           |     |                                '- and_expr
   |           |     |                                   '- shift_expr
   |           |     |                                      '- arith_expr
   |           |     |                                         '- term
   |           |     |                                            '- factor
   |           |     |                                               '- power
   |           |     |                                                  |- atom
   |           |     |                                                  |  '- x
   |           |     |                                                  |- trailer
   |           |     |                                                  |  |- .
   |           |     |                                                  |  '- split
   |           |     |                                                  '- trailer
   |           |     |                                                     |- (
   |           |     |                                                     |- arglist
   |           |     |                                                     |  |- argument
   |           |     |                                                     |  |  '- test
   |           |     |                                                     |  |     '- or_test
   |           |     |                                                     |  |        '- and_test
   |           |     |                                                     |  |           '- not_test
   |           |     |                                                     |  |              '- comparison
   |           |     |                                                     |  |                 '- star_expr
   |           |     |                                                     |  |                    '- expr
   |           |     |                                                     |  |                       '- xor_expr
   |           |     |                                                     |  |                          '- and_expr
   |           |     |                                                     |  |                             '- shift_expr
   |           |     |                                                     |  |                                '- arith_expr
   |           |     |                                                     |  |                                   '- term
   |           |     |                                                     |  |                                      '- factor
   |           |     |                                                     |  |                                         '- power
   |           |     |                                                     |  |                                            '- atom
   |           |     |                                                     |  |                                               '- y
   |           |     |                                                     |  |- ,
   |           |     |                                                     |  '- argument
   |           |     |                                                     |     '- test
   |           |     |                                                     |        '- or_test
   |           |     |                                                     |           '- and_test
   |           |     |                                                     |              '- not_test
   |           |     |                                                     |                 '- comparison
   |           |     |                                                     |                    '- star_expr
   |           |     |                                                     |                       '- expr
   |           |     |                                                     |                          '- xor_expr
   |           |     |                                                     |                             '- and_expr
   |           |     |                                                     |                                '- shift_expr
   |           |     |                                                     |                                   '- arith_expr
   |           |     |                                                     |                                      '- term
   |           |     |                                                     |                                         '- factor
   |           |     |                                                     |                                            '- power
   |           |     |                                                     |                                               '- atom
   |           |     |                                                     |                                                  '- number
   |           |     |                                                     |                                                     '- integer
   |           |     |                                                     |                                                        '- 3
   |           |     |                                                     '- )
   |           |     '- <NEWLINE>
   |           '- <DEDENT>
   '- <EOF>

请注意,Builder.Tree 类不是 ANTLR 库的一部分,它位于您在问题中链接到的/my repo 中:https://github.com/bkiers/python3-parser/blob/master/src/main/java/nl/bigo/pythonparser/Builder.java

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-25
    • 2021-07-05
    • 2014-01-27
    • 1970-01-01
    • 2015-05-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多