如何将此 Antlr3 AST 转换为 Antlr4?

问题描述

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

expr        
    : term ( OR^ term )* ;

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

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

AST 根运算符。在生成抽象语法树 (AST) 时,标记 以“^”根运算符为后缀的引用强制 AST 节点 创建并添加为当前树的根。这个符号只是 设置 buildAST 选项时有效。有关 AST 的更多信息 也可用。

AST 排除运算符。生成抽象语法树时,token 引用后缀为“!” exclude 运算符不包含在 为该规则构建的 AST。规则引用也可以 后缀为 exclude 运算符,这意味着,而树 由于引用的规则被构造,它没有链接到树中 为引用规则。此符号仅在以下情况下有效 设置了 buildAST 选项。还提供了有关 AST 的更多信息。

如果我去掉它们,它会编译,但我不确定这些是什么意思以及 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 { ... } 部分中的文字标记移动到自己的词法分析器规则中。

我认为这是规则

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 中,您将使用访问者来评估您的表达式,而不是在树语法中。