I have an S-expression in Python which I need to convert it into tuple with operators (add,multiply) inside the semi-colon ie as a string.
I have the following code snippet:
This code works fine, but the requirement of the work is that the user doesnot input tuple like ('add', ('multiply', 3, 4), 5) instead pass an s-expression like "(add (multiply 2 3) 2)" from the system command line.
The command to put an input will be like this:
python calc.py "(add (multiply 2 3) 2)"
For now I have already defined expression in the code, but the users will be giving the expression and we fetch it using sys.argv . So how to convert the user input "(add (multiply 2 3) 2)" to ('add', ('multiply', 3, 4), 5) so that I can use the above code easily.
Update:
I tried the following code but it didnt give the desired result.
def from_expression_string(expression_string):
tokens = expression_string.strip().split()
#['(add', '(multiply', '2', '3)', '2)']
stack = []
for token in tokens:
if token == '(':
# print("hello")
pass
elif token == ')':
args = [stack.pop(), stack.pop()]
stack.append((stack.pop(), *reversed(args)))
else:
try:
stack.append(int(token))
except ValueError:
stack.append(token)
return stack[0]
The output of this snippet gives (add. The above code seems easy to understand but is not working.
You can tokenize the input s-expression with a regex of an alternation pattern, iterate through the tokens while appending each token to a stack, but if the token is a left parenthesis, push the current size of the stack to another stack recording the stack positions of left parentheses, and if the token is a right parenthesis, pop the left parentheses stack for the nearest position of a left parenthesis and replace the items from the position with a new sub-list of these items. As long as the s-expression is well-formed, the stack should be left with a single item of the desired list output when all tokens are processed:
This outputs:
Demo: https://replit.com/@blhsing/ProfitableColorfulProlog