shapes.py 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. # shapes.py
  2. #
  3. # A sample program showing how parse actions can convert parsed
  4. # strings into a data type or object.
  5. #
  6. # Copyright 2012, Paul T. McGuire
  7. #
  8. # define class hierarchy of Shape classes, with polymorphic area method
  9. class Shape(object):
  10. def __init__(self, tokens):
  11. self.__dict__.update(tokens.asDict())
  12. def area(self):
  13. raise NotImplementedException()
  14. def __str__(self):
  15. return "<{0}>: {1}".format(self.__class__.__name__, self.__dict__)
  16. class Square(Shape):
  17. def area(self):
  18. return self.side**2
  19. class Rectangle(Shape):
  20. def area(self):
  21. return self.width * self.height
  22. class Circle(Shape):
  23. def area(self):
  24. return 3.14159 * self.radius**2
  25. from pyparsing import *
  26. number = Regex(r'-?\d+(\.\d*)?').setParseAction(lambda t:float(t[0]))
  27. # Shape expressions:
  28. # square : S <centerx> <centery> <side>
  29. # rectangle: R <centerx> <centery> <width> <height>
  30. # circle : C <centerx> <centery> <diameter>
  31. squareDefn = "S" + number('centerx') + number('centery') + number('side')
  32. rectDefn = "R" + number('centerx') + number('centery') + number('width') + number('height')
  33. circleDefn = "C" + number('centerx') + number('centery') + number('diameter')
  34. squareDefn.setParseAction(Square)
  35. rectDefn.setParseAction(Rectangle)
  36. def computeRadius(tokens):
  37. tokens['radius'] = tokens.diameter/2.0
  38. circleDefn.setParseAction(computeRadius, Circle)
  39. shapeExpr = squareDefn | rectDefn | circleDefn
  40. tests = """\
  41. C 0 0 100
  42. R 10 10 20 50
  43. S -1 5 10""".splitlines()
  44. for t in tests:
  45. shape = shapeExpr.parseString(t)[0]
  46. print(shape)
  47. print("Area:", shape.area())
  48. print()