错误的规则ANTLR

时间:2014-03-27 15:02:55

标签: antlr grammar

抱歉我的英语。学习规则antlr,我转动曲线计算器,请告诉我哪里不能正确写。

  • >如果我写: 2+(2 * 2)我的计算器显示:4。
  • >如果我写: 2 + pi 我的计算器显示:第1行:2在输入'pi'行没有可行的选择  1:4输入''4.0
  • 没有可行的选择
  • >如果我写: cos 2 我的计算器显示:第1行:0输入'cos'没有可行的选择  0.9092974268256817

同样的错误......我问你的帮助

这是我得到的:

grammar rulle;

options {
  language = Java;
}

rule returns [double value]
    : exp=additionExp { $value = $exp.value; }
    ; 

additionExp returns [double value]
    :    m1=involutExp      {$value = $m1.value;}
         ( '+' m2=involutExp  {$value += $m1.value;}
         | '-' m2=involutExp  {$value -= $m2.value;}
         )* 
    ; 

involutExp returns [double value]
    : i1=radicalExp {$value = $i1.value;} 
        ( '^' i1=radicalExp {$value = Math.pow($value, $i1.value);}
        )*
    ;

radicalExp returns [double value]
    : r1=matchSinCosExp {$value = $r1.value;}
        ( '!' r1=matchSinCosExp{$value = Math.pow($value, 1.0/$r1.value);}
        )*
    ;

matchSinCosExp returns [double value]
    : m1=piExp {$value = $m1.value;}
        ('sin' m1=piExp {$value = Math.sin($m1.value);}
        |'cos' m1=piExp {$value = Math.sin($m1.value);}
        )*
    ;

piExp returns [double value]
    : p1=multiplyExp {$value = $p1.value;}
        ('pi' p1=multiplyExp {$value = ($p1.value-$p1.value)+Math.PI;} 
        )*
    ;

multiplyExp returns [double value]
    :    a1=atomExp     {$value = $a1.value;}
         ( '*' a2=atomExp {$value *= $a2.value;}
         | '/' a2=atomExp {$value /= $a2.value;}
         )* 
    ;


atomExp returns [double value]
    :    n=Number           {$value = Double.parseDouble($n.text);}
    |    '(' exp=additionExp ')' {$value = $exp.value;}
    ;

Number
    :    ('0'..'9')+ ('.' ('0'..'9')+)?
    ;

WS  
    :   (' ' | '\t' | '\r'| '\n') {$channel=HIDDEN;}
    ;

1 个答案:

答案 0 :(得分:1)

此规则中出现多个问题:

piExp returns [double value]
    : p1=multiplyExp {$value = $p1.value;}
        ('pi' p1=multiplyExp {$value = ($p1.value-$p1.value)+Math.PI;} 
        )*
    ;

此规则的结构方式,要获取值π,您需要使用类似3pi4的表达式,即pi被写为二元运算符而不是主要表达。值34实际上被忽略了,因为它们都分配给标签p1(而不是像其他标签p1p2一样规则),因此表达式($p1.value-$p1.value)+Math.PI简化为(0)+Math.PI只是Math.PI

您应该通过以下方式更正此问题:

  1. 删除规则piExp
  2. piExp中对matchSinCosExp的引用替换为对multiplyExp的引用。
  3. 创建新规则primaryExp

    primaryExp returns [double value]
      : Number    {$value = Double.parseDouble($Number.text);}
      | 'pi'      {$value = Math.PI;}
      ;
    
  4. 更改atomExp规则以引用primaryExp而非Number

    atomExp returns [double value]
      : primaryExp              {$value = $primaryExp.value;}
      | '(' exp=additionExp ')' {$value = $exp.value;}
      ;