我修改了this pyparsing program,接受t作为变量:
from pyparsing import Literal,CaselessLiteral,Word,Combine,Group,Optional,\
ZeroOrMore,Forward,nums,alphas
from numpy import *
import operator
exprStack = []
def pushFirst( strg, loc, toks ):
exprStack.append( toks[0] )
def pushUMinus( strg, loc, toks ):
if toks and toks[0]=='-':
exprStack.append( 'unary -' )
#~ exprStack.append( '-1' )
#~ exprStack.append( '*' )
bnf = None
def BNF():
"""
expop :: '^'
multop :: '*' | '/'
addop :: '+' | '-'
integer :: ['+' | '-'] '0'..'9'+
atom :: PI | E | real | T | fn '(' expr ')' | '(' expr ')'
factor :: atom [ expop factor ]*
term :: factor [ multop factor ]*
expr :: term [ addop term ]*
"""
global bnf
if not bnf:
point = Literal( "." )
e = CaselessLiteral( "E" )
fnumber = Combine( Word( "+-"+nums, nums ) +
Optional( point + Optional( Word( nums ) ) ) +
Optional( e + Word( "+-"+nums, nums ) ) )
ident = Word(alphas, alphas+nums+"_$")
plus = Literal( "+" )
minus = Literal( "-" )
mult = Literal( "*" )
div = Literal( "/" )
lpar = Literal( "(" ).suppress()
rpar = Literal( ")" ).suppress()
addop = plus | minus
multop = mult | div
expop = Literal( "^" )
pi = CaselessLiteral( "PI" )
t = CaselessLiteral( "T" )
expr = Forward()
atom = (Optional("-") + ( pi | e | t | fnumber | ident + lpar + expr + rpar ).setParseAction( pushFirst ) | ( lpar + expr.suppress() + rpar )).setParseAction(pushUMinus)
# by defining exponentiation as "atom [ ^ factor ]..." instead of "atom [ ^ atom ]...", we get right-to-left exponents, instead of left-to-righ
# that is, 2^3^2 = 2^(3^2), not (2^3)^2.
factor = Forward()
factor << atom + ZeroOrMore( ( expop + factor ).setParseAction( pushFirst ) )
term = factor + ZeroOrMore( ( multop + factor ).setParseAction( pushFirst ) )
expr << term + ZeroOrMore( ( addop + term ).setParseAction( pushFirst ) )
bnf = expr
return bnf
# map operator symbols to corresponding arithmetic operations
epsilon = 1e-12
opn = { "+" : operator.add,
"-" : operator.sub,
"*" : operator.mul,
"/" : operator.truediv,
"^" : operator.pow }
fn = { "sin" : sin,
"cos" : cos,
"tan" : tan,
"abs" : abs,
"trunc" : lambda a: int(a),
"round" : round,
"sgn" : lambda a: abs(a)>epsilon and cmp(a,0) or 0}
def evaluateStack( s ):
op = s.pop()
if op == 'unary -':
return -evaluateStack( s )
if op in "+-*/^":
op2 = evaluateStack( s )
op1 = evaluateStack( s )
return opn[op]( op1, op2 )
elif op == "PI":
return math.pi # 3.1415926535
elif op == "E":
return math.e # 2.718281828
elif op == "T":
return linspace(-4 * pi, 4 * pi, 200)
elif op in fn:
return fn[op]( evaluateStack( s ) )
elif op[0].isalpha():
return 0
else:
return float( op )
def compute(s):
global exprStack
exprStack = []
results = BNF().parseString( s )
val = evaluateStack( exprStack[:] )
return val
fun=raw_input("Please input a function to be evaluated: ")
print compute(fun)
例如,该程序执行以下操作:
Please input a function to be evaluated: 2+sin(t)
[ 2. 2.12595971 2.24991296 2.36988529 2.4839656 2.59033669
2.68730414 2.77332333 2.84702403 2.90723225 2.95298891 2.98356514
2.99847388 2.99747765 2.98059231 2.94808684 2.90047903 2.83852724
2.7632183 2.67575185 2.57752115 2.47009096 2.35517255 2.2345965
2.1102835 1.98421376 1.85839548 1.73483286 1.61549416 1.50228037
1.39699489 1.30131485 1.21676437 1.14469026 1.08624063 1.04234653
1.01370716 1.00077873 1.00376718 1.0226249 1.05705151 1.1064986
1.17017854 1.24707694 1.33596886 1.43543832 1.54390084 1.6596287
1.78077842 1.90542019 2.03156855 2.15721404 2.28035523 2.39903056
2.51134962 2.61552324 2.70989202 2.79295273 2.86338228 2.92005876
2.96207936 2.98877473 2.99971963 2.99473972 2.97391431 2.93757514
2.88630108 2.82090888 2.74244018 2.65214495 2.55146151 2.44199369
2.32548523 2.20379202 2.07885255 1.95265701 1.82721561 1.70452655
1.58654417 1.47514784 1.37211203 1.27907802 1.19752779 1.12876036
1.07387115 1.03373451 1.00898979 1.00003115 1.0070013 1.0297892
1.06803187 1.12112012 1.1882083 1.26822773 1.35990378 1.46177609
1.57222193 1.68948197 1.81168833 1.93689437 2.06310563 2.18831167
2.31051803 2.42777807 2.53822391 2.64009622 2.73177227 2.8117917
2.87887988 2.93196813 2.9702108 2.9929987 2.99996885 2.99101021
2.96626549 2.92612885 2.87123964 2.80247221 2.72092198 2.62788797
2.52485216 2.41345583 2.29547345 2.17278439 2.04734299 1.92114745
1.79620798 1.67451477 1.55800631 1.44853849 1.34785505 1.25755982
1.17909112 1.11369892 1.06242486 1.02608569 1.00526028 1.00028037
1.01122527 1.03792064 1.07994124 1.13661772 1.20704727 1.29010798
1.38447676 1.48865038 1.60096944 1.71964477 1.84278596 1.96843145
2.09457981 2.21922158 2.3403713 2.45609916 2.56456168 2.66403114
2.75292306 2.82982146 2.8935014 2.94294849 2.9773751 2.99623282
2.99922127 2.98629284 2.95765347 2.91375937 2.85530974 2.78323563
2.69868515 2.60300511 2.49771963 2.38450584 2.26516714 2.14160452
2.01578624 1.8897165 1.7654035 1.64482745 1.52990904 1.42247885
1.32424815 1.2367817 1.16147276 1.09952097 1.05191316 1.01940769
1.00252235 1.00152612 1.01643486 1.04701109 1.09276775 1.15297597
1.22667667 1.31269586 1.40966331 1.5160344 1.63011471 1.75008704
1.87404029 2. ]
所以基本上compute 函数将评估简单的表达式,并在您使用t 时提供一个linspace (var)。如果你愿意,你可以扩展它。我认为你可以从这里合并你需要的东西来使你的程序工作。 :)