Antlr 错误规则

Antlr 错误规则,antlr,grammar,Antlr,Grammar,对不起我的英语。学习规则antlr,我转动了曲线计算器,请告诉我哪里写不好 >如果我写:2+(2*2)我的计算器显示:4 >如果我写:2+pi我的计算器显示:行1:2在输入“pi”行没有可行的替代方案 输入“4.0”时1:4没有可行的替代方案 >如果我写:cos2我的计算器显示:行1:0在输入“cos”处没有可行的替代方案 0.9092974268256817 还有同样类型的错误…我请求你的帮助 以下是我得到的: grammar rulle; options { language =

对不起我的英语。学习规则antlr,我转动了曲线计算器,请告诉我哪里写不好

  • >如果我写:2+(2*2)我的计算器显示:4
  • >如果我写:2+pi我的计算器显示:行1:2在输入“pi”行没有可行的替代方案 输入“4.0”时1:4没有可行的替代方案
  • >如果我写:cos2我的计算器显示:行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;}
    ;

此规则中出现多个问题:

piExp returns [double value]
    : p1=multiplyExp {$value = $p1.value;}
        ('pi' p1=multiplyExp {$value = ($p1.value-$p1.value)+Math.PI;} 
        )*
    ;
按照此规则的结构方式,要获得值π,需要使用类似
3pi4
的表达式,即
pi
被写成二进制运算符,而不是主表达式。值
3
4
实际上被忽略,因为这两个值都被分配给标签
p1
(与其他规则中单独的标签
p1
p2
不同),因此表达式
($p1.value-$p1.value)+Math.PI
简化为
(0)+Math.PI
就是
Math.PI

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

  • 删除规则
    piExp
  • matchsincoexp
    中对
    piExp
    的引用替换为对
    multiplyExp
    的引用
  • 创建新规则
    primaryExp

    primaryExp returns [double value]
      : Number    {$value = Double.parseDouble($Number.text);}
      | 'pi'      {$value = Math.PI;}
      ;
    
  • atomExp
    规则更改为引用
    primaryExp
    ,而不仅仅是
    Number

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

  • 可以再建议一次,作为结果的对数吗?我这样写:'log'{$value=Math.log($value);}并且我输出:-Infinity,我试图这样做Math10.log($value),但是没有用:logExp返回[double value]:l1=atomExp{$value=$l1.value;}('log'l2=atomExp{$value=Math.log10($l2.value);})*;现在仅显示以下消息:第1行:0在输入“log”处没有可行的替代方案。可以,原则上,不注意它,它工作得很好,但想知道为什么它会显示此消息