Skip to content

Instantly share code, notes, and snippets.

@companje
Last active August 8, 2022 21:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save companje/dc814c18ae98071ed1d305d18023eb39 to your computer and use it in GitHub Desktop.
Save companje/dc814c18ae98071ed1d305d18023eb39 to your computer and use it in GitHub Desktop.
Expression Parser - Bauer-Samelson algorithm as described in BYTE magazine 1976-02
```
# Expression Parser - Bauer-Samelson algorithm as described in BYTE magazine 1976-02
# Python implementation: Rick Companje, 30 July 2022
# usage: main("20+4*(5-(6-3))/8")
import math,re
def precedence_check(operators,c):
if not operators or operators[-1] == '(':
return True
else:
order = "^*/+-"
return order.find(operators[-1]) > order.find(c)
def unstack(operators, operands):
op = operators.pop()
b = operands.pop()
a = 0 if op=="U" else operands.pop() # a=0 when unary operator
if op=="^": #power
operands.append(a**b)
elif op=="*":
operands.append(a*b)
elif op=="/":
operands.append(int(a/b))
elif op=="+":
operands.append(a+b)
elif op in "U-":
operands.append(a-b)
def parse(s,vars={}):
# keywords = ["sin"]
operands = []
operators = []
pc = "" #prev char
# token=""
# tokenType=""
for c in s:
if c==")":
while operators[-1]!="(":
unstack(operators,operands)
operators.pop() #remove (
if c.isnumeric():
if pc.isnumeric():
operands[-1] = int(str(operands[-1])+c)
else:
operands.append(int(c))
if c.isalpha():
operands.append(vars[c])
elif c=="(":
operators.append(c)
elif c in "^+*/-":
if c=="-" and not pc.isnumeric():
# print("unary")
operators.append("U") #unary
else:
while not precedence_check(operators,c):
unstack(operators,operands)
operators.append(c)
# print(c,"\t",operands,"\t",operators)
pc=c # prev char for multidigit numbers
while operators:
# print(operators,operands)
unstack(operators,operands)
return operands[-1]
vars = {
"t": 10,
"i": 85,
"x": 5,
"y": 5
}
print(parse("t*(i/y)",vars))
```
@companje
Copy link
Author

companje commented Jul 30, 2022

TODO: add support for unary operators such as the - in -5 and -3:

-5-(-3-4)

TODO2: add support for variables:

-8*(y-x)+t

TODO3: functions like sin()

sin(t)

@companje
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment