使用Nashorn将JavaScript解析为语法树

时间:2018-01-23 10:25:47

标签: javascript java nashorn

我正在编写一个需要将JavaScript解析为语法树的Java程序。在JDK 9中尝试Nashorn API,据说可以做到这一点。解析器返回的数据类型文档看起来并不十分具有启发性: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 - 我指出了获取信息的明显方法退出的数据没有做任何事情,所以推测预期的方式是非显而易见的。

1 个答案:

答案 0 :(得分:1)

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