Antlr 从DSL语法文件生成java类

Antlr 从DSL语法文件生成java类,antlr,dsl,parser-generator,bnf,compiler-compiler,Antlr,Dsl,Parser Generator,Bnf,Compiler Compiler,我正在寻找一种从将填充AST的语法文件(BNF/bnflike)生成解析器的方法。但是,我还希望以一种开发人员可读的方式自动生成各种AST类 例如: 对于以下语法文件 expressions = expression+; expression = CONST | math_expression; math_expression = add_expression | substract_expression; add_expression = expression PLUS expression;

我正在寻找一种从将填充AST的语法文件(BNF/bnflike)生成解析器的方法。但是,我还希望以一种开发人员可读的方式自动生成各种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类(并举例说明我希望它们的字段是什么):

(不必介意运算符优先级)

我一直在探索DSL解析器生成器(JavaCC/ANTLR和friends),我能找到的最接近的东西是使用ANTLR生成具有“enterExpression”和“leaveExpression”风格方法的侦听器类。我发现使用JavaCC和使用“multi”的jjtree生成的代码有点类似,但它非常笨拙,使用起来非常困难

我的语法需求有些简单,我希望尽可能地自动化AST对象图的创建


有什么提示吗?

如果您想获得对DSL构建的大量支持,那么ANTLR和JavaCC可能不适合。它们提供解析,一些构建树的支持。。。在那之后你就得靠自己了。但是,正如您所了解的,设计自己的树、解决细节需要大量的工作,而此时您几乎还没有完成DSL;你还是不能用它

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

Markus Voelter刚刚发布了一本关于的在线书籍,可供您选择捐款。他对MPS、XText、Spoofax进行了详细介绍,但对DMS则没有。他告诉你你需要知道什么,你需要做什么;根据我对这本书的浏览,内容相当广泛。你可能不会因为“简单”而得逞;DSL有很多语义复杂性,而且支持机制也很困难


我认识这位作家,非常尊重他在这一领域的技能,并曾与他共同讲授夏季技术技能,包括喝一些可口的啤酒。否则我就没什么事可做了。

作为啤酒伙伴通常比作为同事更好:)。无论如何-我认为MPS不会做我想做的-据我所知,您构建DSL语法和转换规则,并在MPS中开发,以创建一个完整的程序。我需要一个可移植的解析器,我可以向它输入一个字符串,它将输出AST用于语义分析。然后我计划对它进行多次检查,以了解我需要做什么来满足请求。我不熟悉其他的(我确实浏览了Xtext,但它似乎没有提供我所需要的);如果你坚持在树上停车,那可能是你最好的选择。但是,看我的文章,关于解析后的生活
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;}
Expressions(Expression(MathExpression(AddExpression(1, SubstractExpression(1, 2)))))