Search code examples
javaparsingdsljavaccjavaparser

Combine Java parser in custom parser for expressions


I'm trying to create a custom domain specific language for creating HTML templates using java expressions statements.

For instance it should parse tags combined with java statements:

<div>
    if (someValue == true) {

        <span>"someValue was true"</span>

    }
</div>

Now I know how to write such a parser. However it would be very much simpler if I could just use the standard Java Parser for the expressions, so that I do not have to reimplement a part of the Java Parser. What I'm trying to achieve could look like:

IfStatementNode parseIfStatement() {

    scanner.expect("if");

    scanner.expect("(");

    JavaExpression expression = scanner.parseJavaExpression(); // <--- how to implement this?

    scanner.expect(")");

    return new IfStatementNode(expression);
}

How can this be done so that scanner.parseJavaExpression parses any Java Expression?


Solution

  • You are right: you can reuse JavaParser and I would suggest you do so because parsing Java expressions is not trivial at all. JavaParser is well mantained, and it is working on building support for Java 9, which you will get for free if you use JavaParser.

    Using JavaParser in this case it is so simple that I am almost ashamed of writing this code:

    Expression expression = JavaParser.parseExpression(code);
    

    And you are done.

    Now, that we throw exceptions if there are errors in the code. If you want to get a nice list of issues to report them to your users you could do that like this:

      ParseResult<Expression> result = new JavaParser().parse(ParseStart.EXPRESSION, new StringProvider(code));
      for (Problem p : result.getProblems()) {
          System.err.println("Problem at " + p.getLocation().get() + 
                  ": " + p.getMessage());
      }
    

    If you want then to process the code to calculate types or resolve references to external classes you may want to look at JavaSymbolSolver, which is built on top of JavaParser.

    Source: I am a JavaParser contributor