我试图用ANTLR4解析代数表达式。我尝试用解析器完成的一个功能是"智能"处理百分比表达式。
修改:目标是让餐厅的折扣或小费更容易计算。例如。如果你看到广告" 30%折扣"你可以输入价格 - 30%"并得到正确的结果。或者在餐馆,您可以输入您的餐点价格加15%并获得您需要支付的金额,包括15%的小费。但是,只有当表达式看起来像"表达式1( - 或+)表达式2"时才会出现这种解释。在所有其他情况下,百分号应该像往常一样解释。 Google搜索框计算器的行为与此类似。 /编辑
100-30%
应该返回 70
100-(20+10)%
也应该返回 70
3+(100-(20+10)%)
应返回 73
的但
5%
应返回 0.05
(5+5)%
应返回 0.10
我的语法看起来像这样:
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)?
答案 0 :(得分:0)
我删除了原来基于语法的答案,因为我意识到我对你想要完成什么样的处理有一个非常不同的想法。听起来您希望X op Y %
形式的任何内容成为X * (1 op (Y/100))
。那是准确的吗?
我尝试使用解析器完成的一项功能是对表达式百分比进行“智能”处理:
你确定你的规格足够坚固甚至可以开始编码吗?这对我来说看起来很混乱,特别是因为%
更像是一个单位指定。
例如,我原本期望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 -% B
或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
无效