在表达式的自定义解析器中组合 Java 解析器
Combine Java parser in custom parser for expressions
我正在尝试创建自定义域特定语言,以使用 java 表达式语句创建 HTML 模板。
例如,它应该解析结合 java 语句的标签:
<div>
if (someValue == true) {
<span>"someValue was true"</span>
}
</div>
现在我知道如何编写这样的解析器了。但是,如果我可以只对表达式使用标准的 Java 解析器,那将会简单得多,这样我就不必重新实现 Java 解析器的一部分。我想要实现的目标可能如下所示:
IfStatementNode parseIfStatement() {
scanner.expect("if");
scanner.expect("(");
JavaExpression expression = scanner.parseJavaExpression(); // <--- how to implement this?
scanner.expect(")");
return new IfStatementNode(expression);
}
如何才能做到 scanner.parseJavaExpression
解析任何 Java 表达式?
一个选项是添加一些生成代码以将表达式转换为 Function 对象的有效 java 代码。然后,您可以使用运行时可用的常规 java 编译器解析生成的函数(包含 return 值的表达式)。
这仍然需要您能够找到表达式的结尾。 StreamTokenizer 可能就足够/方便了。
另一个问题是跟踪变量 when/if 您添加对它们的支持。
另一种方法可能是扩展模板中不是 Java 的部分(例如将 <span>
变成 output.append("<span>")
),将你的模板变成有效的 Java代码,可以整体编译。
你是对的:你可以重用 JavaParser 我建议你这样做,因为解析 Java 表达式一点也不简单。 JavaParser 维护得很好,它正在努力构建对 Java 9 的支持,如果您使用 JavaParser.
,您将免费获得它
在这种情况下使用 JavaParser 非常简单,以至于我写这段代码几乎感到羞耻:
Expression expression = JavaParser.parseExpression(code);
大功告成。
现在,如果代码中有错误,我们将抛出异常。如果您想获得一个很好的问题列表以将它们报告给您的用户,您可以这样做:
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());
}
如果您随后想处理代码以计算类型或解析对外部 类 的引用,您可能需要查看 JavaSymbolSolver,它建立在 Java 之上解析器。
来源:我是 JavaParser 贡献者
我正在尝试创建自定义域特定语言,以使用 java 表达式语句创建 HTML 模板。
例如,它应该解析结合 java 语句的标签:
<div>
if (someValue == true) {
<span>"someValue was true"</span>
}
</div>
现在我知道如何编写这样的解析器了。但是,如果我可以只对表达式使用标准的 Java 解析器,那将会简单得多,这样我就不必重新实现 Java 解析器的一部分。我想要实现的目标可能如下所示:
IfStatementNode parseIfStatement() {
scanner.expect("if");
scanner.expect("(");
JavaExpression expression = scanner.parseJavaExpression(); // <--- how to implement this?
scanner.expect(")");
return new IfStatementNode(expression);
}
如何才能做到 scanner.parseJavaExpression
解析任何 Java 表达式?
一个选项是添加一些生成代码以将表达式转换为 Function 对象的有效 java 代码。然后,您可以使用运行时可用的常规 java 编译器解析生成的函数(包含 return 值的表达式)。
这仍然需要您能够找到表达式的结尾。 StreamTokenizer 可能就足够/方便了。
另一个问题是跟踪变量 when/if 您添加对它们的支持。
另一种方法可能是扩展模板中不是 Java 的部分(例如将 <span>
变成 output.append("<span>")
),将你的模板变成有效的 Java代码,可以整体编译。
你是对的:你可以重用 JavaParser 我建议你这样做,因为解析 Java 表达式一点也不简单。 JavaParser 维护得很好,它正在努力构建对 Java 9 的支持,如果您使用 JavaParser.
,您将免费获得它在这种情况下使用 JavaParser 非常简单,以至于我写这段代码几乎感到羞耻:
Expression expression = JavaParser.parseExpression(code);
大功告成。
现在,如果代码中有错误,我们将抛出异常。如果您想获得一个很好的问题列表以将它们报告给您的用户,您可以这样做:
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());
}
如果您随后想处理代码以计算类型或解析对外部 类 的引用,您可能需要查看 JavaSymbolSolver,它建立在 Java 之上解析器。
来源:我是 JavaParser 贡献者