是否有一个使用antlr4从java源代码创建AST并提取方法,变量和注释的简单示例?

有人可以提供一个详细的例子,说明我如何使用antlr4做到这一点?安装antlr4及其依赖项的说明将受到高度赞赏.

解决方法:

这里是.

首先,你要买ANTLR4书;-)

其次,你将下载antlr4 jar和java语法(http://pragprog.com/book/tpantlr2/the-definitive-antlr-4-reference)

然后,您可以稍微更改语法,将这些添加到标题中

    (...)
grammar Java;

options 
{
    language = Java;
}

// starting point for parsing a java file
compilationUnit
    (...)

我会在语法中改变一点,只是为了说明一些东西.

/*
methodDeclaration
    :   (type|'void') Identifier formalParameters ('[' ']')*
        ('throws' qualifiedNameList)?
        (   methodBody
        |   ';'
        )
    ;
*/
methodDeclaration
    :   (type|'void') myMethodName formalParameters ('[' ']')*
        ('throws' qualifiedNameList)?
        (   methodBody
        |   ';'
        )
    ;

myMethodName
    :   Identifier
    ;

你看,原始语法不允许你从任何其他标识符中识别方法标识符,所以我评论了原始块并添加了一个新块,只是为了向您展示如何获得您想要的.

您必须对要检索的其他元素执行相同操作,例如当前刚刚跳过的注释.那是给你的:-)

现在,创建一个这样的类来生成所有存根

package mypackage;

public class Gen {

    public static void main(String[] args) {
        String[] arg0 = { "-visitor", "/home/leoks/EclipseIndigo/workspace2/SO/src/mypackage/Java.g4", "-package", "mypackage" };
        org.antlr.v4.Tool.main(arg0);
    }

}

运行Gen,你会在mypackage中为你创建一些java代码.

现在创建一个访问者.实际上,访问者将在此示例中解析自己

package mypackage;

import java.io.FileInputStream;
import java.io.IOException;

import mypackage.JavaParser.MyMethodNameContext;

import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeWalker;

/**
 * @author Leonardo Kenji Feb 4, 2014
 */
public class MyVisitor extends JavaBaseVisitor<Void> {

    /**
     * Main Method
     * 
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        ANTLRInputStream input = new ANTLRInputStream(new FileInputStream("/home/leoks/EclipseIndigo/workspace2/SO/src/mypackage/MyVisitor.java")); // we'll
                                                                                                                                                    // parse
                                                                                                                                                    // this
                                                                                                                                                    // file
        JavaLexer lexer = new JavaLexer(input);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        JavaParser parser = new JavaParser(tokens);
        ParseTree tree = parser.compilationUnit(); // see the grammar ->
                                                    // starting point for
                                                    // parsing a java file



        MyVisitor visitor = new MyVisitor(); // extends JavaBaseVisitor<Void>
                                                // and overrides the methods
                                                // you're interested
        visitor.visit(tree);
    }

    /**
     * some attribute comment
     */
    private String  someAttribute;

    @Override
    public Void visitMyMethodName(MyMethodNameContext ctx) {
        System.out.println("Method name:" + ctx.getText());
        return super.visitMyMethodName(ctx);
    }

}

就是这样.

你会得到类似的东西

Method name:main
Method name:visitMyMethodName

PS.还有一件事.当我在eclipse中编写这段代码时,我有一个奇怪的例外.这是由Java 7引起的,只需将这些参数添加到编译器即可修复(感谢此链接http://java.dzone.com/articles/javalangverifyerror-expecting)

上一篇:c# – 语法识别彼此旁边的无限'{‘expr’}’


下一篇:Windows-org.antlr.v4.runtime.misc.TestRig挂起