1

I'm writing a Java program that needs to parse JavaScript to a syntax tree. Trying the Nashorn API in JDK 9, which is said to be able to do this. The documentation on the datatype returned by the parser doesn't look terribly enlightening: https://docs.oracle.com/javase/9/docs/api/jdk/nashorn/api/tree/CompilationUnitTree.html

I've tried writing and running some code that looks like this:

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

but the output looks like this:

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

What am I missing?

To be clear, I'm not asking why the output consists only of symbols with @ signs - obviously that's just the default toString - I'm pointing out that the obvious way to get information out of the returned data doesn't do anything, so presumably the intended way is something nonobvious.

rwallace
  • 31,405
  • 40
  • 123
  • 242
  • 1
    `ExpressionStatementTreeImpl` seems not to implement `toString()`. –  Jan 23 '18 at 10:28
  • @LutzHorn Indeed, so what does it implement instead to enable one to obtain the syntax tree? – rwallace Jan 23 '18 at 10:30
  • Dupe of this I guess: https://stackoverflow.com/questions/29140402 But most of the answers there seem to assume you control the source. – Jorn Vernee Jan 23 '18 at 10:30
  • @JornVernee Different question - that's a question of how the authors of the API could have made it more easily accessible; I'm asking how to use the API as it is. – rwallace Jan 23 '18 at 10:31

1 Answers1

1

tree.getSourceElements() gives you a list of elements of type Tree which has the method getKind​() that gives you the Tree.Kind of the element:

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:
            [...]
    }
}

If you want to run down the AST you can then implement the interface TreeVisitor<R,D> to visit the nodes:

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);
}
Georg Leber
  • 3,470
  • 5
  • 40
  • 63