Guest User

Untitled

a guest
Jan 21st, 2019
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.65 KB | None | 0 0
  1. #!/usr/bin/env python3
  2.  
  3. def tokenize(string):
  4. # Splits string into list of tokens
  5. string = string.replace('(', ' ( ')
  6. string = string.replace(')', ' ) ')
  7. return string.split()
  8.  
  9. def find_matching_paren_offset(tokens):
  10. # Return index for first unmatched close parentheses.
  11. stack = []
  12. for i, token in enumerate(tokens):
  13. if token == '(':
  14. stack.append(token)
  15. elif token == ')':
  16. if len(stack) == 0:
  17. return i
  18. else:
  19. stack.pop()
  20.  
  21. def create_ast(tokens):
  22. ast = []
  23. i = 0
  24. while i < len(tokens):
  25. token = tokens[i]
  26. if token == '(':
  27. i += 1 # advance index to token after open paren
  28. end_paren_idx = find_matching_paren_offset(tokens[i:]) + i
  29. ast.append(create_ast(tokens[i : end_paren_idx]))
  30. i = end_paren_idx + 1 # update index to token after close paren
  31. else:
  32. if token.isdigit():
  33. token = int(token)
  34. ast.append(token)
  35. i += 1
  36. return ast
  37.  
  38. def parse(string):
  39. assert string.startswith('(') and string.endswith(')')
  40. return create_ast(tokenize(string[1:-1]))
  41.  
  42. def evaluate(ast):
  43. return ast
  44.  
  45. def test():
  46. assert parse('(+ 20 30)') == ['+', 20, 30]
  47. assert parse('(+ (* 2 3) 4)') == ['+', ['*', 2, 3], 4]
  48. assert parse('(- 3 (* 4 5))') == ['-', 3, ['*', 4, 5]]
  49. assert parse('(+ (* 2 3) (- 6 4))') == ['+', ['*', 2, 3], ['-', 6, 4]]
  50. assert parse('(first (list 1 (+ 2 3) 9))') == ['first', ['list', 1, ['+', 2, 3], 9]]
  51.  
  52. if __name__ == '__main__':
  53. test()
  54. while True:
  55. line = input('> ')
  56. print(evaluate(parse(line)))
Add Comment
Please, Sign In to add comment