使用Nashorn将JavaScript解析成语法树

Using Nashorn to parse JavaScript into a syntax tree

我正在编写一个 Java 程序,需要将 Java 脚本解析为语法树。试试JDK9中的NashornAPI,据说可以做到这一点。解析器返回的数据类型的文档看起来不是很有启发性:https://docs.oracle.com/javase/9/docs/api/jdk/nashorn/api/tree/CompilationUnitTree.html

我尝试编写 运行 一些代码,如下所示:

        Parser              parser = Parser.create();
        CompilationUnitTree tree   = parser.parse(file, new InputStreamReader(stream), null);
        System.out.println(tree.getSourceElements());
        for (Object o : tree.getSourceElements()) {
            System.out.println(o);
        }

但输出如下所示:

[jdk.nashorn.api.tree.ExpressionStatementTreeImpl@32eebfca]
jdk.nashorn.api.tree.ExpressionStatementTreeImpl@32eebfca

我错过了什么?

明确地说,我不是在问为什么输出只包含带有 @ 符号的符号 - 显然这只是默认值 toString - 我指出的是显而易见的方法从返回的数据中获取信息不会做任何事情,所以大概预期的方式是不明显的。

tree.getSourceElements() 给你一个 Tree 类型的元素列表,它有方法 getKind​() 给你 Tree.Kind 元素:

Parser parser = Parser.create();
CompilationUnitTree tree = parser.parse(file, new InputStreamReader(stream), null);

for (Tree tree : tree.getSourceElements()) {
    System.out.println(tree.getKind());

    switch(tree.getKind()) {
        case FUNCTION:
            [...]
    }
}

如果你想 运行 关闭 AST,你可以实现接口 TreeVisitor<R,D> 来访问节点:

Parser parser = Parser.create();
CompilationUnitTree tree = parser.parse(file, new InputStreamReader(stream), null);

if (tree != null) {
    tree.accept(new BasicTreeVisitor<Void, Void>() {
        public Void visitFunctionCall(FunctionCallTree functionCallTree, Void v) {
             System.out.println("Found a functionCall: " + functionCallTree.getFunctionSelect().getKind​());
             return null;
         }
     }, null);
}