2011-09-21 6 views
3

私は式を評価するために文法を書こうとしています。
私は、ANTLRのウェブサイト(+、 - 、*を管理しています)の例から始めました。 私は部門を追加しました。しかし、私が0で割り切ろうとするとユーザに通知したいと思います。 さらに、評価者にpowを追加したいと思います(2^3 = 8など)。
それは理解できるのですホープ
はここに私の文法Expr.gです:。。。事前にANTLR:エクスプレッションエバリュエーター、除算、pow

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();} ; 

おかげ エド

答えて

3

eoutiが書いた:

私は部門を追加しました。しかし、私は彼があなたのmultExprルールインサイド0

で割るしようとすると、あなたが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、あなたはただ例外をスローする必要があります。

eoutiは書いた:

を私は乗算や除算よりも高い優先順位で(私の評価者に捕虜を追加したい

その後の間でpowExprルールを追加します。 multExprと​​とし、multExprには​​ルールの代わりにpowExprルールを使用してください。

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 [double value]returns [int value]を変更したい場合があります。

+0

ありがとうございました!はい、私は、ユーザーに警告し、分母= 0なら文法を停止したいと言っていたことを忘れてしまった。私は休憩を追加しようとした。 - >動作しません。 – eouti

+0

ようこそ。 –

+0

@eoutiは、 'N/0'の場合に解析を停止することを見ていませんでした。その場合、単に 'else'ブロックの中に' System.err ... 'の後に例外を投げてください。 –