Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python3
- def tokenize(string):
- # Splits string into list of tokens
- string = string.replace('(', ' ( ')
- string = string.replace(')', ' ) ')
- return string.split()
- def find_matching_paren_offset(tokens):
- # Return index for first unmatched close parentheses.
- stack = []
- for i, token in enumerate(tokens):
- if token == '(':
- stack.append(token)
- elif token == ')':
- if len(stack) == 0:
- return i
- else:
- stack.pop()
- def create_ast(tokens):
- ast = []
- i = 0
- while i < len(tokens):
- token = tokens[i]
- if token == '(':
- i += 1 # advance index to token after open paren
- end_paren_idx = find_matching_paren_offset(tokens[i:]) + i
- ast.append(create_ast(tokens[i : end_paren_idx]))
- i = end_paren_idx + 1 # update index to token after close paren
- else:
- if token.isdigit():
- token = int(token)
- ast.append(token)
- i += 1
- return ast
- def parse(string):
- assert string.startswith('(') and string.endswith(')')
- return create_ast(tokenize(string[1:-1]))
- def evaluate(ast):
- return ast
- def test():
- assert parse('(+ 20 30)') == ['+', 20, 30]
- assert parse('(+ (* 2 3) 4)') == ['+', ['*', 2, 3], 4]
- assert parse('(- 3 (* 4 5))') == ['-', 3, ['*', 4, 5]]
- assert parse('(+ (* 2 3) (- 6 4))') == ['+', ['*', 2, 3], ['-', 6, 4]]
- assert parse('(first (list 1 (+ 2 3) 9))') == ['first', ['list', 1, ['+', 2, 3], 9]]
- if __name__ == '__main__':
- test()
- while True:
- line = input('> ')
- print(evaluate(parse(line)))
Add Comment
Please, Sign In to add comment