beam: fix safe_eval unary minus precedence vs **
This commit is contained in:
1 parent
bf5238169e
commit
7706712fbc
2 files changed
+14
-12
No files matched your search
@@ -141,10 +141,10 @@ class _Parser:
|
|||||||
return value
|
return value
|
||||||
|
|
||||||
def term(self):
|
def term(self):
|
||||||
value = self.power()
|
value = self.unary()
|
||||||
while self.peek()[0] == _OP and self.peek()[1] in ("*", "/", "//", "%"):
|
while self.peek()[0] == _OP and self.peek()[1] in ("*", "/", "//", "%"):
|
||||||
op = self.advance()[1]
|
op = self.advance()[1]
|
||||||
rhs = self.power()
|
rhs = self.unary()
|
||||||
if op == "*":
|
if op == "*":
|
||||||
value = value * rhs
|
value = value * rhs
|
||||||
elif op == "/":
|
elif op == "/":
|
||||||
@@ -161,20 +161,20 @@ class _Parser:
|
|||||||
value = value % rhs
|
value = value % rhs
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def power(self):
|
|
||||||
base = self.unary()
|
|
||||||
if self.peek()[0] == _OP and self.peek()[1] == "**":
|
|
||||||
self.advance()
|
|
||||||
exp = self.power() # right-assoc
|
|
||||||
return base ** exp
|
|
||||||
return base
|
|
||||||
|
|
||||||
def unary(self):
|
def unary(self):
|
||||||
if self.peek()[0] == _OP and self.peek()[1] in ("+", "-"):
|
if self.peek()[0] == _OP and self.peek()[1] in ("+", "-"):
|
||||||
op = self.advance()[1]
|
op = self.advance()[1]
|
||||||
val = self.unary()
|
val = self.power() # unary lower precedence than ** (python semantics)
|
||||||
return -val if op == "-" else val
|
return -val if op == "-" else val
|
||||||
return self.primary()
|
return self.power()
|
||||||
|
|
||||||
|
def power(self):
|
||||||
|
base = self.primary()
|
||||||
|
if self.peek()[0] == _OP and self.peek()[1] == "**":
|
||||||
|
self.advance()
|
||||||
|
exp = self.unary() # right-assoc, exponent may be signed
|
||||||
|
return base ** exp
|
||||||
|
return base
|
||||||
|
|
||||||
def primary(self):
|
def primary(self):
|
||||||
t = self.peek()
|
t = self.peek()
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ cases = [
|
|||||||
("2+3*4", 14),
|
("2+3*4", 14),
|
||||||
("(2+3)*4", 20),
|
("(2+3)*4", 20),
|
||||||
("2**3**2", 512), # right assoc
|
("2**3**2", 512), # right assoc
|
||||||
|
("-2**2", -4), # unary lower than **
|
||||||
|
("2**-2", 0.25), # signed exponent
|
||||||
("10//3", 3),
|
("10//3", 3),
|
||||||
("10%3", 1),
|
("10%3", 1),
|
||||||
("-5+2", -3),
|
("-5+2", -3),
|
||||||
|
|||||||
Reference in new issue
Block a user