【发布时间】:2010-10-11 21:04:00
【问题描述】:
我有一个相对简单的 DSL,我想比一堆手动编码的 java.util.regex.Pattern 语句 + 解析逻辑更健壮地处理它。
引用最多的工具似乎是 ANTLR。我不熟悉它,并愿意尝试一下。但是,当我查看示例时(例如 ANTLR expression evaluator example,或 Martin Fowler 的 HelloAntlr,或 this other Q on stackoverflow),我有点怀疑。原因是语法文件看起来像是一个大杂烩,散布着本质上是命令式的实现语言(例如 Java)的片段。
我真正喜欢的是分离出解析器的命令/评估部分。有没有办法使用 ANTLR(或其他工具)来定义语法并生成一组 Java 源文件,以便它编译成类,我可以使用这些类将输入解析为不作用于该结构的结构?
例如,如果我想只使用 + 和 * 和 () 运算符的表达式求值,并且我有输入
3 * (4 + 7 * 6) * (3 + 7 * (4 + 2))
那么我想做的是编写一个语法将其转换为像这样的层次结构
Product
Term(3)
Sum
Term(4)
Product
Term(7)
Term(6)
Sum
Term(3)
Product
Term(7)
Sum
Term(4)
Term(2)
我可以在哪里使用类似的类
interface Expression<T> {
public T evaluate();
}
class Term implements Expression<Double> {
final private double value;
@Override public Double evaluate() { return value; }
}
class Product implements Expression<Double> {
final private List<Expression<Double>> terms;
@Override public Double evaluate() {
double result = 1;
for (Expression<Double> ex : terms)
result *= ex.evaluate();
return result;
}
}
class Sum implements Expression<Double> {
final private List<Expression<Double>> terms;
@Override public Double evaluate() {
double result = 0;
for (Expression<Double> ex : terms)
result += ex.evaluate();
return result;
}
}
并使用 ANTLR 构建结构。有没有办法做到这一点?我真的更愿意采用这种方法,因为它让我(和其他软件工程师)可以编辑和可视化完整的 Java 类,而不必将这些类分割成 ANTLR 语法文件中的奇怪片段。
有没有办法做到这一点?
澄清:我想在两种方式上花费尽可能多的精力:定义语法本身,以及在独立于 ANTLR 的 Java 中(例如我的 Product/Sum/Term 类)。我想尽量减少我必须花在学习 ANTLR 语法、怪癖和 API 上的时间/经验。我不知道如何从 ANTLR 语法创建和操作 AST。因为这只是大型 Java 项目的一小部分,所以不仅是我,还有我团队中的任何人都必须审查或维护我的代码。
(我并不是说无礼:我愿意投入时间和精力来使用工具,但前提是该工具成为有用的工具并且不会继续成为绊脚石。)
【问题讨论】: