SimpleCalc.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. # SimpleCalc.py
  2. #
  3. # Demonstration of the parsing module,
  4. # Sample usage
  5. #
  6. # $ python SimpleCalc.py
  7. # Type in the string to be parse or 'quit' to exit the program
  8. # > g=67.89 + 7/5
  9. # 69.29
  10. # > g
  11. # 69.29
  12. # > h=(6*g+8.8)-g
  13. # 355.25
  14. # > h + 1
  15. # 356.25
  16. # > 87.89 + 7/5
  17. # 89.29
  18. # > ans+10
  19. # 99.29
  20. # > quit
  21. # Good bye!
  22. #
  23. #
  24. # Uncomment the line below for readline support on interactive terminal
  25. # import readline
  26. from pyparsing import ParseException, Word, alphas, alphanums
  27. import math
  28. # Debugging flag can be set to either "debug_flag=True" or "debug_flag=False"
  29. debug_flag=False
  30. variables = {}
  31. from fourFn import BNF, exprStack, fn, opn
  32. def evaluateStack( s ):
  33. op = s.pop()
  34. if op == 'unary -':
  35. return -evaluateStack( s )
  36. if op in "+-*/^":
  37. op2 = evaluateStack( s )
  38. op1 = evaluateStack( s )
  39. return opn[op]( op1, op2 )
  40. elif op == "PI":
  41. return math.pi # 3.1415926535
  42. elif op == "E":
  43. return math.e # 2.718281828
  44. elif op in fn:
  45. return fn[op]( evaluateStack( s ) )
  46. elif op[0].isalpha():
  47. if op in variables:
  48. return variables[op]
  49. raise Exception("invalid identifier '%s'" % op)
  50. else:
  51. return float( op )
  52. arithExpr = BNF()
  53. ident = Word(alphas, alphanums).setName("identifier")
  54. assignment = ident("varname") + '=' + arithExpr
  55. pattern = assignment | arithExpr
  56. if __name__ == '__main__':
  57. # input_string
  58. input_string=''
  59. # Display instructions on how to quit the program
  60. print("Type in the string to be parsed or 'quit' to exit the program")
  61. input_string = input("> ")
  62. while input_string.strip().lower() != 'quit':
  63. if input_string.strip().lower() == 'debug':
  64. debug_flag=True
  65. input_string = input("> ")
  66. continue
  67. # Reset to an empty exprStack
  68. del exprStack[:]
  69. if input_string != '':
  70. # try parsing the input string
  71. try:
  72. L=pattern.parseString(input_string, parseAll=True)
  73. except ParseException as err:
  74. L=['Parse Failure', input_string, (str(err), err.line, err.column)]
  75. # show result of parsing the input string
  76. if debug_flag: print(input_string, "->", L)
  77. if len(L)==0 or L[0] != 'Parse Failure':
  78. if debug_flag: print("exprStack=", exprStack)
  79. # calculate result , store a copy in ans , display the result to user
  80. try:
  81. result=evaluateStack(exprStack)
  82. except Exception as e:
  83. print(str(e))
  84. else:
  85. variables['ans']=result
  86. print(result)
  87. # Assign result to a variable if required
  88. if L.varname:
  89. variables[L.varname] = result
  90. if debug_flag: print("variables=", variables)
  91. else:
  92. print('Parse Failure')
  93. err_str, err_line, err_col = L[-1]
  94. print(err_line)
  95. print(" "*(err_col-1) + "^")
  96. print(err_str)
  97. # obtain new input string
  98. input_string = input("> ")
  99. # if user type 'quit' then say goodbye
  100. print("Good bye!")