Antlr 字符串模板和语法谓词

Antlr 字符串模板和语法谓词,antlr,stringtemplate,Antlr,Stringtemplate,我正在尝试修复我的TreeWalker,以便它可以根据是否找到括号实现不同的字符串模板 i、 e.在以下公式中:x-y-z 使用括号将更改公式的值。如果没有括号,公式将变成x-y-z,这是错误的。我试图使用一个不同的字符串模板来表示负号和带括号的负号。详情如下: minus(op1,op2) ::= "$op1$ - $op2$" minusb(op1,op2) ::= "($op1$ - $op2$)" 下面是我尝试使用的TreeWalker

我正在尝试修复我的TreeWalker,以便它可以根据是否找到括号实现不同的字符串模板

i、 e.在以下公式中:x-y-z 使用括号将更改公式的值。如果没有括号,公式将变成x-y-z,这是错误的。我试图使用一个不同的字符串模板来表示负号和带括号的负号。详情如下:

minus(op1,op2)              ::= "$op1$ - $op2$"
minusb(op1,op2)             ::= "($op1$ - $op2$)"
下面是我尝试使用的TreeWalker部分。这只是一个更大的树行者的一部分

additiveExpr
scope { bool aFlag }
@init {bool aFlag = true; }
    :   ^(PLUS
          { $additiveExpr::aFlag = false;
            $formula::mFlag = false;
          }
          op1=expression op2=expression)
        -> {$additiveExpr::aFlag}?
           plusb(op1={$op1.st},op2={$op2.st})
        -> plus(op1={$op1.st},op2={$op2.st})
    |   ^(MINUS
          {
            $additiveExpr::aFlag = false;
            $formula::mFlag = false;
          }
          op1=expression op2=expression)
        -> {$additiveExpr::aFlag}?
           minusb(op1={$op1.st},op2={$op2.st})
        -> minus(op1={$op1.st},op2={$op2.st})
在上面的规则中,aFlag总是返回false,生成没有括号的模板。我很难理解为什么在有括号的情况下它不会返回真值

如果有帮助的话,我可以发布解析器的其他部分

我已经计算出条件部分是由语法谓词决定的。当additiveExpr之前的标记是一个括号lexer标记OPEN时,我需要语法谓词表达式为true。这是否需要从解析器传递到TreeWalker,或者我可以从这里解决吗?这是等效的解析器代码

absExpr returns [string ret_type]
    :   ABS^ OPEN! additiveExpr CLOSE!
        {$ret_type = "numeric"; }
    |   additiveExpr
        {$ret_type = $additiveExpr.ret_type; }
    ;

additiveExpr returns [string ret_type]
    :   m=multiplicativeExpr ((PLUS|MINUS)^ multiplicativeExpr )*
        {$ret_type =  $m.ret_type; }
    ;
编辑:

最新语法分析器部分:

absExpr returns [string ret_type] 
    :   ABS^ OPEN additiveExpr CLOSE
        {$ret_type =  $additiveExpr.ret_type; }
    |   (OPEN additiveExpr CLOSE)=> OPEN additiveExpr CLOSE
        {$ret_type =  $additiveExpr.ret_type; }
    |   additiveExpr
        {$ret_type = $additiveExpr.ret_type; }
    ;

我可能会尝试以下方法,而不是使用语义谓词。你只需要确保不要使用这个工具!解析器语法中additiveExpr规则中的运算符,或者打开和关闭标记将不可供树遍历器使用

additiveExpr
    :   ^(PLUS OPEN op1=expression op2=expression CLOSE)
        -> plusb(op1={$op1.st},op2={$op2.st})
    |   ^(PLUS op1=expression op2=expression)
        -> plus(op1={$op1.st},op2={$op2.st})
    |   ^(MINUS OPEN op1=expression op2=expression CLOSE)
        -> minusb(op1={$op1.st},op2={$op2.st})
    |   ^(MINUS op1=expression op2=expression)
        -> minus(op1={$op1.st},op2={$op2.st})
    ;
先前的答复:

我很难说你到底想让它怎么工作。有一个问题可能是初始化:

scope { bool aFlag }
@init {bool aFlag = true; }
这声明了两个同名的不同变量aFlag。其中一个将出现在scope类中,另一个将是additiveExpr方法中的局部变量。您可能打算这样做:

scope { bool aFlag }
@init { $additiveExpr::aFlag = true; }

特别针对我研究过的ANTLR语法的提示:[]是方括号或方括号,是圆括号,{}是花括号或方括号,是尖括号。它可能在那个区域。在一个简化的例子中,我尝试翻译下面的X+Z-T。我有一个字符串模板用于减号/加号,还有一个用于带括号的减号/加号。因此,当我的翻译出现时,我要么在所有的单词周围加上括号,要么不加括号。“我只想在括号出现在我的原始公式中时才能得到它们。”JamesRandles我重写了我答案的前半部分。希望这能帮助你让它工作起来非常感谢。我离结果更近了。然而,我仍然在为解析器部分而挣扎。我尝试了许多选项将开/闭括号发送到walker,但我尝试的选项似乎无法正常工作。我已经修改了我的问题,以包含解析器的最新部分。显然有些地方出了问题,但我不确定如何改变它。