如何将此 Antlr3 AST 转换为 Antlr4?

How do I convert this Antlr3 AST to Antlr4?

我正在尝试将现有的 Antlr3 项目转换为 Antlr4 以获得更多功能。我的语法不能用 Antlr4.9

编译
expr        
    : term ( OR^ term )* ;

factor 
    : ava | NOT^ factor | (LPAREN! expr RPAREN!) ;

主要是因为 Antlr4 不再支持 ^!。从文档看来那些是

AST root operator. When generating abstract syntax trees (ASTs), token references suffixed with the "^" root operator force AST nodes to be created and added as the root of the current tree. This symbol is only effective when the buildAST option is set. More information about ASTs is also available.

AST exclude operator. When generating abstract syntax trees, token references suffixed with the "!" exclude operator are not included in the AST constructed for that rule. Rule references can also be suffixed with the exclude operator, which implies that, while the tree for the referenced rule is constructed, it is not linked into the tree for the referencing rule. This symbol is only effective when the buildAST option is set. More information about ASTs is also available.

如果我把它们去掉它会编译,但我不确定它们是什么意思以及 Antlr4 将如何支持它。

LPARENRPAREN 是令牌

tokens {
    EQUALS = '=';
    LPAREN = '(';
    RPAREN = ')';
}

哪个 Antlr4 在错误消息中提供了转换它的方法,但 ^! 没有。该语法用于解析布尔表达式,例如 (a=b AND b=c)

我认为这是规则

targetingexpr returns [boolean value]
    : expr { $value = $expr.value; } ;

expr returns [boolean value]
    : ^(NOT a=expr) { $value = !a; }        
    | ^(AND a=expr b=expr) { $value = a && b; }
    | ^(OR a=expr b=expr) { $value = a || b; }
    | ^(EQUALS A=ALPHANUM B=ALPHANUM) { $value = targetingContext.contains($A.text,$B.text); }
    ;
    

v3 语法:

...

tokens {
    EQUALS = '=';
    LPAREN = '(';
    RPAREN = ')';
}

...

expr        
    : term ( OR^ term )* ;

factor 
    : ava | NOT^ factor | (LPAREN! expr RPAREN!) ;

在 v4 中看起来像这样:

...

expr        
    : term ( OR term )* ;

factor 
    : ava | NOT factor | (LPAREN expr RPAREN) ;

EQUALS : '=';
LPAREN : '(';
RPAREN : ')';

所以,只需删除内联 ^! 运算符(树重写在 ANTLR4 中不再可用),并将 tokens { ... } 部分中的文字标记移动到自己的词法分析器中规则。

I think this is the rule

targetingexpr returns [boolean value]
    : expr { $value = $expr.value; } ;

expr returns [boolean value]
    : ^(NOT a=expr) { $value = !a; }        
    | ^(AND a=expr b=expr) { $value = a && b; }
    | ^(OR a=expr b=expr) { $value = a || b; }
    | ^(EQUALS A=ALPHANUM B=ALPHANUM) { $value = targetingContext.contains($A.text,$B.text); }
    ;

您在此处发布的是树语法的一部分,没有对应的树语法。在 ANTLR4 中,您将使用访问者来评估您的表达式,而不是在树语法中。