3

我正在尝试编写一个语法来评估表达式。
我从 ANTLR 网站上的给定示例开始(它管理 +、- 和 *)。我添加了分区。但是如果他试图除以 0,我想通知用户。此外,我想在我的评估器中添加 pow(优先级高于乘法和除法。(例如 2^3=8)。
希望这是可以理解的.
这是我的语法 Expr.g :

grammar Expr;

@header {  
import java.util.HashMap;  
}

@members {  
/** Map variable name to Integer object holding value */  
HashMap memory = new HashMap();  
}

prog:   stat+ ;

stat:   expr NEWLINE {System.out.println($expr.value);}  
    |   ID '=' expr NEWLINE  
        {memory.put($ID.text, new Integer($expr.value));}  
    |   NEWLINE  
    ;

expr returns [int value]
    :   e=multExpr {$value = $e.value;}
        ((   '+' e=multExpr {$value += $e.value;}
        |   '-' e=multExpr {$value -= $e.value;}
        ))*
    ;

multExpr returns [int value]
    :   e=atom {$value = $e.value;} 
        ('*' e=atom {$value *= $e.value;}
        |'/' e=atom {if (e != 0) $value /= $e.value; 
                else System.err.println("Division par 0 !");}
        )*
    ; 

atom returns [int value]
    :   INT {$value = Integer.parseInt($INT.text);}
    |   ID
        {
        Integer v = (Integer)memory.get($ID.text);
        if ( v!=null ) $value = v.intValue();
        else System.err.println("Variable indéfinie "+$ID.text);
        }
    |   '(' expr ')' {$value = $expr.value;}
    ;

ID  :   ('a'..'z'|'A'..'Z')+ ;
INT :   '0'..'9'+ ;
NEWLINE:'\r'? '\n' ;
WS  :   (' '|'\t')+ {skip();} ;

提前致谢。埃德。

4

1 回答 1

3

euti 写道:

我添加了分区。但如果他试图除以 0,我想通知用户。

在您的multExpr规则中,您不应该这样做if (e != 0) ...,但您应该访问e'value属性。此外,表达式的左侧被调用e,而右侧也被调用e。你最好给他们唯一的名字:

multExpr returns [int value]
    :   e1=atom {$value = $e1.value;} 
        ( '*' e2=atom {$value *= $e2.value;}
        | '/' e2=atom {if ($e2.value != 0) $value /= $e2.value; 
                       else System.err.println("Division par 0 !");}
        )*
    ; 

但是,您真的要警告用户吗?在此警告之后,计算将继续进行。IMO,您应该只抛出异常。

euti 写道:

我想在我的评估器中添加 pow (优先级高于乘法和除法。

然后在and之间添加一条powExpr规则,并让使用此规则而不是规则:multExpratommultExprpowExpratom

multExpr returns [int value]
    :   e1=powExpr       {...} 
        ( '*' e2=powExpr {...}
        | '/' e2=powExpr {...}
        )*
    ;  

powExpr returns [int value]
    :   atom      {...} 
        ('^' atom {...} 
        )*
    ;

atom returns [int value]
    :   INT          {...}
    |   ID           {...}
    |   '(' expr ')' {...}
    ;

powExpr当然不需要介于这些规则之间......)

此外,您可能想要更改returns [int value]returns [double value],尤其是因为您使用的是除法。

于 2011-09-21T14:38:55.103 回答