Java ANTLR4如何提取python表达式变量

Java ANTLR4如何提取python表达式变量,java,python,variables,antlr4,Java,Python,Variables,Antlr4,使用以下ANTLR语法:我想从给定表达式进行解析,假设: x.split(y, 3) 或 变量x和y。我将如何实现这一点 我尝试了以下方法,但似乎很麻烦,因为我必须添加所有内置python函数: 定义侦听器接口 const listener = new MyPythonListener() antlr.tree.ParseTreeWalker.DEFAULT.walk(listener, abstractTree) 使用正则表达式+模式匹配: const symbolicNames = ['

使用以下ANTLR语法:我想从给定表达式进行解析,假设:

x.split(y, 3)

变量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_]+$/)
    }
}

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

def some_method_name(some_param_name):
x、 分裂(y,3)
变量名似乎是atom规则的子项:

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));

System.out.println(new Builder.Tree(source).toStringASCII());
String source=“定义一些方法名称(一些参数名称):\n x.split(y,3)\n”;
Python3Lexer lexer=新的Python3Lexer(CharStreams.fromString(source));
Python3Parser=newpython3parser(newcommontokenstream(lexer));
ParseTreeWalker.DEFAULT.walk(新的Python3BaseListener(){
@凌驾
public void enterAtom(Python3Parser.AtomContext ctx){
如果(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());
亲自检查您感兴趣的节点在解析树中的位置。上面的代码将打印:

”-文件输入
|-stmt
|'-复合物
|'-funcdef
||-def
||-一些_方法_名称
||-参数
|        |  |- (
|| |-typedargslist
|| |'-tfpdef
|| |'-一些参数
|        |  '- )
|        |- :
|“-套房
|           |- 
|           |- 
||-stmt
||'-简单的
|| |-小型
|| |'-expr|stmt
|| |'-测试列表|星|表达式
|| |'-测试
|| |'-或| U测试
|| |'-和|测试
|| |'-非|测试
|| |'-比较
|| |'-星型
|| |'-expr
|| |'-xor|u expr
|| |'-和| expr
|| |'-移位表达式
|| |‘-arith|u expr
|| |’-术语
|| |'-系数
|| |”-电源
|| | |-原子
|| | |'-x
|| | |-拖车
|           |     |                                                  |  |- .
|| | |'-拆分
|| |'-拖车
|           |     |                                                     |- (
|| | |-arglist
|| | | |-参数
|| | | |'-测试
|| | | |'-或| U测试
|| | | |'-和|测试
|| | | | |-非|测试
|| | | |'-比较
|| | | | |'-星型
|| | | |'-expr
|| | | |'-异或表达式
|| | | |'-和| expr
|| | | |'-移位表达式
|| | | |'-arith|u expr
|| | | |'-术语
|| | | |'-系数
|| | | |'-电源
|| | | |'-原子
|| | | |'-y
|           |     |                                                     |  |- ,
|| | |'-参数
|| | |'-测试
|| | |'-或| U测试
|| | |'-和|测试
|           |     |