如何在java中从ANTLR AST生成函数定义?

时间:2018-03-15 19:11:18

标签: java antlr abstract-syntax-tree

我使用过Python3语法并构建了一个AST。 我的源代码字符串只是Python的一个小函数。 我的代码如下:

public class Main {

public static void main(String[] args) {

    String source = "def sum( arg1, arg2 ):\r\n" 
                    + "   total = arg1 + arg2\r\n"
                    + "   print \"Inside the function : \", total\r\n"
                    + "   return total;\n";
    Python3Lexer lexer = new Python3Lexer(CharStreams.fromString(source));
    Python3Parser parser = new Python3Parser(new CommonTokenStream(lexer));

    ParseTreeWalker.DEFAULT.walk(new Python3BaseListener() {


        @Override
        public enterFuncdef(Python3Parser.FuncdefContext ctx) {
            //Here which function would give me the function definition?
        }
    }, parser.single_input());
}
}

在这里,我如何输出功能的名称? (和)? 我很难理解语法。

1 个答案:

答案 0 :(得分:0)

有几件事:

  1. 您应该使用解析器规则file_input作为起点:single_input用于there is more information under there too including position - 就像解析Python源一样
  2. public enterFuncdef在无效的Java代码中:您缺少返回类型(在这种情况下为void
  3. 您在无效的Python 3源代码中解析的Python源代码。 print "..."应为print("...")
  4. 现在,如果你看一下你正在收听的解析器规则:

    funcdef
     : DEF NAME parameters ( '->' test )? ':' suite
     ;
    

    您看到它有一个NAME令牌。你可以像这样抓住它:

    import org.antlr.v4.runtime.*;
    import org.antlr.v4.runtime.tree.ParseTreeWalker;
    
    public class Main {
    
      public static void main(String[] args) {
    
        String source = "def sum( arg1, arg2 ):\r\n"
                + "   total = arg1 + arg2\r\n"
                + "   print(\"Inside the function : \", total)\r\n"
                + "   return total;\n";
    
        Python3Lexer lexer = new Python3Lexer(CharStreams.fromString(source));
        Python3Parser parser = new Python3Parser(new CommonTokenStream(lexer));
    
        ParseTreeWalker.DEFAULT.walk(new Python3BaseListener() {
          @Override
          public void enterFuncdef(Python3Parser.FuncdefContext ctx) {
            System.out.printf("NAME=%s\n", ctx.NAME().getText());
          }
        }, parser.file_input());
      }
    }
    

    运行上面的课程将打印:NAME=sum

    顺便说一句,语法回购中有一个例子可以完全符合您的要求:REPL