我正在尝试修复我的TreeWalker,以便它可以根据是否找到括号来实现不同的字符串模板。
即。在以下公式中:x - (y - z) 使用括号将改变公式的值。没有括号,公式变为x - y - z,这是错误的。我试图使用一个不同的字符串模板减去和减去括号。具体如下:
minus(op1,op2) ::= "$op1$ - $op2$"
minusb(op1,op2) ::= "($op1$ - $op2$)"
我尝试使用的TreeWalker部分如下所示。这只是一个更大的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之前的标记是一个括号(词法分析器标记OPEN'('))时,我需要语法谓词表达式为true。这是否需要从Parser传递给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; }
;
答案 0 :(得分:0)
我可能会尝试类似以下内容而不是使用语义谓词。您只需要确保不使用解析器语法中!
规则中的additiveExpr
运算符,或OPEN
和CLOSE
令牌将无法供您的树木步行者使用。
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; }
这声明了2个具有相同名称aFlag
的不同变量。其中一个将出现在范围类中,另一个将是additiveExpr
方法中的局部变量。您可能打算这样做:
scope { bool aFlag }
@init { $additiveExpr::aFlag = true; }