1

ANTLR4 で代数式を解析しようとしています。私がパーサーで達成しようとした機能の 1 つは、パーセント式の「インテリジェントな」処理です。

編集:目標は、レストランでの割引やチップの計算を簡単にすることです。たとえば、「30% オフ」という広告が表示された場合、「価格 - 30%」と入力すると正しい結果が得られます。または、レストランでは、食事の価格に 15% を加えた金額を入力して、15% のチップを含めて支払わなければならない金額を受け取ることができます。ただし、この解釈は、式が「式 1 (- または +) 式 2」のように見える場合にのみ発生します。その他のすべての場合、パーセント記号は通常どおり解釈されます。Google 検索ボックス計算機はそのように動作します。/編集

100-30%70を返す必要があります70
100-(20+10)%も返す必要があります73を返す必要がありますが、 0.05を返す必要があります0.10を返す必要があります
3+(100-(20+10)%)

5%
(5+5)%

私の文法は次のようになります。

expr:
 e EOF   
;

e:
   '-'a=e                          
 | '(' a=e ')'                     
 | a=e op=(ADD|SUB) b=e '%'        
 | a=e op=(ADD|SUB) b=e            
 | a=e'%'                          //**PERCENTRULE**
 | FLT                             
 ;

ADD :  '+' ;
SUB :  '-' ;
FLT: [0-9]+(('.'|',')[0-9]+)?;
NEWLINE:'\r'? '\n' ;
WS : [ \t\n]+ -> skip ;

式については、このツリー100-30%期待します:
式の予期される解析ツリー

しかし、私はこれを取得します:
式の解析ツリー
どうすれば正しいツリーを取得できますか(PERCENTRULEを削除せずに)?

4

1 に答える 1

0

元の文法ベースの回答を削除しました。あなたが達成しようとしている処理の種類について、非常に異なる考えを持っていることに気付いたからです。代わりに、フォーム内の何かにX op Y %なりたいようです。X * (1 op (Y/100))それは正確ですか?

私がパーサーで実現しようとした機能の 1 つは、パーセント式の「インテリジェントな」処理です。

これに対するあなたの仕様は、コーディングを開始するのに十分なほどしっかりしていますか? %特に単位指定に似ているため、私にはかなり混乱しているように見えます。

たとえば、50-30%次のいずれかになると予想していました。

  • (50 - 0.3) = 49.3
  • (50 - 30) / 100 = 0.20

...しかし、あなたが求めていることはまだ奇妙に聞こえます: 50 * (1 - 0.3) = 35.

それはさらなる奇妙さを開きます。これらは両方とも真実ではないでしょうか?

  • 0+5%になるだろう0 * (1 + 0.05) = 0
  • 5%になるだろう5 / 100 = 0.05

通常、ゼロを追加しても数値の意味は変わらないため、これは奇妙です。


より限定的なバージョン

ユーザーがあいまいさを避ける場合にのみパーセンテージベースの変更を許可するのはどうですか? A -% B1 つの方法は、 orのような新しい 2 項演算子を作成することですA +% Bが、これは人間中心ではないため、次のようにします。

expr: e EOF ;

e
 : SUB e                          
 | parenExpr
 | percentOp        
 | binaryOp
 | FLT                             
 ;
parenExpr
 : LPAREN e RPAREN
 ;
percentOp
 : (FLT|parenExpr) (ADD|SUB) (FLT|parenExpr) PCT
 ;
binaryOp
 : e (ADD|SUB|MUL|DIV) e
 ;

PCT : '%';
LPAREN : '(';
RPAREN : ')';
ADD :  '+' ;
SUB :  '-' ;
MUL :  '*' ;
DIV :  '/' ;
FLT: [0-9]+(('.'|',')[0-9]+)?;
NEWLINE:'\r'? '\n' ;
WS : [ \t\n]+ -> skip ;

これは次のことを意味します。

  • 50-5-4%100-(5-4%)は45.2 を取得するものとして扱われます。
  • 5%は有効ではありません (それ自体では)
  • 5%+4有効じゃない
于 2013-09-22T03:43:16.907 に答える