This repo contains code to mirror other repos. It also contains the code that is getting mirrored.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

80 lines
1.5 KiB

  1. """
  2. Basic calculator
  3. ================
  4. A simple example of a REPL calculator
  5. This example shows how to write a basic calculator with variables.
  6. """
  7. from lark import Lark, Transformer, v_args
  8. try:
  9. input = raw_input # For Python2 compatibility
  10. except NameError:
  11. pass
  12. calc_grammar = """
  13. ?start: sum
  14. | NAME "=" sum -> assign_var
  15. ?sum: product
  16. | sum "+" product -> add
  17. | sum "-" product -> sub
  18. ?product: atom
  19. | product "*" atom -> mul
  20. | product "/" atom -> div
  21. ?atom: NUMBER -> number
  22. | "-" atom -> neg
  23. | NAME -> var
  24. | "(" sum ")"
  25. %import common.CNAME -> NAME
  26. %import common.NUMBER
  27. %import common.WS_INLINE
  28. %ignore WS_INLINE
  29. """
  30. @v_args(inline=True) # Affects the signatures of the methods
  31. class CalculateTree(Transformer):
  32. from operator import add, sub, mul, truediv as div, neg
  33. number = float
  34. def __init__(self):
  35. self.vars = {}
  36. def assign_var(self, name, value):
  37. self.vars[name] = value
  38. return value
  39. def var(self, name):
  40. return self.vars[name]
  41. calc_parser = Lark(calc_grammar, parser='lalr', transformer=CalculateTree())
  42. calc = calc_parser.parse
  43. def main():
  44. while True:
  45. try:
  46. s = input('> ')
  47. except EOFError:
  48. break
  49. print(calc(s))
  50. def test():
  51. print(calc("a = 1+2"))
  52. print(calc("1+a*-3"))
  53. if __name__ == '__main__':
  54. # test()
  55. main()