如何隐藏ANTLR4中的parens?

时间:2015-04-05 08:51:52

标签: antlr

例如,input ='(1 + 2)* 3'。

树就像'(expr(expr((expr(expr 1)+(expr 2))))*(expr 3))'

然后,我想隐藏或删除树中的'('和')',不再需要它们了。我试着去做,但没有。

expr : ID LPAREN exprList? RPAREN
     | '-' expr
     | '!' expr
     | expr op=('*'|'/') expr
     | expr op=('+'|'-') expr
     | ID
     | INT
     | LPAREN expr RPAREN //### Parens Here ####
     ;
 LPAREN : '(' ;
 RPAREN : ')' ;

我想要的是**不**以下。

PAREN : ( '(' | ')' ) -> channel(HIDDEN)

2 个答案:

答案 0 :(得分:1)

标准解析器生成器方案将解析与树构建分开。

这允许人们设计自定义动作来构建AST,并将其结构微调到目标语言(包括省略具体语法,如"括号")。

价格是不仅要指定语法,还必须指定构建AST的规则。这使得定义一个"语法+树构建器"大约是定义语法的两倍。当你的语法很小时,这并不重要,但通常微小的语法意味着玩具问题"。对于大量真实生产粗糙的语法,这很重要;在尝试使这些语法正确的时候,通常会有一堆初步的流失,而AST构建的东西在这个阶段就会受到妨碍。聪明的人延迟添加AST构建规则,直到流失阶段结束,但这只是部分工作,并且事实证明你可能想要根据你想要构建的AST重塑语法,所以这个延迟实际上增加

我的公司构建了一个工具,DMS Software Reengineering Toolkit,它包含一个解析器生成器。我们决定,大约20年前第一个这样做的AFAIK,这个额外的AST构建步骤太多了,对于我们期望(并且确实)构建的许多大型语法的好处。因此我们设计了DMS以在解析时自动构建具体的语法树。瞧,写一个语法,得到一个解析器,树是免费的。这个决定结果非常好。

价格是最终树保留所有具体语法,例如括号。虽然它可能看起来不太优雅,但事实证明,在操作树木(检查,遍历,分析,修改......)时,这在实践中并不重要。我们为了更容易的树木构建和语法维护而进行了一些不合时宜的交易。

与他之前的ANTLR1 / 2/3系统不同,ANTLR家伙(!)决定使用ANTRL4来跟随我们的领先优势并切换到构建" ASTs"自动从语法中,作为具体的语法树。 (我不知道你是否真的可以编写自己的AST构建规则来覆盖ANTLR4的内置功能。对这个答案的评论表明,从ANTLR4获取AST的方法是走CST并构建什么你想要的。我并不热衷于这个解决方案;它让我感到高兴的是为构建和管理AST而付出了代价,同时也为构建CST提供了解析开销[时间和空间]。如果你只建造小树也许你不在乎。对于DMS,我们会定期阅读数千个文件进行处理;空间和时间都很重要!)

关于如何使这更优雅(有效甚至更像AST)的一些讨论,请参阅我的SO answer on ASTs vs. CSTs

答案 1 :(得分:0)

要在树中抑制无用的令牌,请使用'!'对应标记后的符号:

//remove ',' comma from the output
list: LISTNAME LISTMEMBER (','! LISTMEMBER)*;  

来自http://meri-stuff.blogspot.com/2011/09/antlr-tutorial-expression-language.html