2

我正在寻找一种从将填充 AST 的语法文件(类似 BNF/BNF)生成解析器的方法。但是,我还希望以开发人员可读的方式自动生成各种 AST 类。

示例:对于以下语法文件

expressions = expression+;
expression = CONST | math_expression;
math_expression = add_expression | substract_expression;
add_expression = expression PLUS expression;
substract_expression = expression MINUS expression;

CONST: ('0'..'9')+;
PLUS: '+';
MINUS: '-';    

我希望生成以下 Java 类(以我期望它们的字段为示例):

class Expressions {List<Expression> expression};
class Expression {String const; MathExpression mathExpression;} //only one should be filled.
class MathExpression {AddExpression addExpression; SubstractExpression substractExpression;}
class AddExpression {Expression expression1; Expression expression2;}
class SubstractExpression {Expression expression1; Expression expression2;}

而且,在运行时,我希望表达式“1+1-2”生成以下对象图来表示 AST:

Expressions(Expression(MathExpression(AddExpression(1, SubstractExpression(1, 2)))))

(不要介意运算符优先级)。

我一直在探索 DSL 解析器生成器(JavaCC/ANTLR 和朋友),我能找到的最接近的方法是使用 ANTLR 生成具有“enterExpression”和“leaveExpression”样式方法的侦听器类。我发现使用“multi”使用 JavaCC 和 jjtree 生成的代码有点相似——但它非常笨拙且难以使用。

我的语法需求有点简单——我想尽可能地自动化 AST 对象图的创建。

有什么提示吗?

4

1 回答 1

3

如果你想要大量支持 DSL 构造,ANTLR 和 JavaCC 可能不是你要走的路。它们提供解析、构建树的一些支持……然后你就靠自己了。但是,正如您所了解的那样,设计您自己的树、处理细节需要大量工作,而此时您还没有完成 DSL;你仍然不能使用它。

还有更完整的解决方案:JetBrains MPS、Xtext、Spoofax、DMS。它们都提供了定义 DSL、将其转换为内部形式(“构建树”)并为代码生成提供支持的方法。前三个集成了 IDE 支持,适用于“小型”DSL;DMS 不会,但可以处理 C++ 和 DSL 等真实语言。我认为前三个是开源的;DMS 是商业的(我是 DMS 背后的一方)。

Markus Voelter 刚刚发布了一本关于DSL 工程的在线书籍,供您提出捐赠的想法。他详细介绍了 MPS、XText、Spoofax,但没有介绍 DMS。他告诉你你需要知道什么,你需要做什么;根据我对这本书的浏览,它非常广泛。您可能不会在“简单”上下车;DSL 具有很多语义复杂性,支持机制也很困难。

我认识作者,非常尊重他在这个领域的技能,并与他共同教授夏季技术技能,包括喝一些好喝的啤酒。否则我无事可做这本书。

于 2013-01-28T01:46:32.107 回答