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.

4
  • 1
    ExpressionStatementTreeImpl seems not to implement toString(). Commented Jan 23, 2018 at 10:28
  • @LutzHorn Indeed, so what does it implement instead to enable one to obtain the syntax tree? Commented Jan 23, 2018 at 10:30
  • Dupe of this I guess: stackoverflow.com/questions/29140402 But most of the answers there seem to assume you control the source. Commented Jan 23, 2018 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. Commented Jan 23, 2018 at 10:31

1 Answer 1

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);
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.