Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PythonPyFn示例:具有两个或多个参数的parse函数_Python_Pyparsing - Fatal编程技术网

PythonPyFn示例:具有两个或多个参数的parse函数

PythonPyFn示例:具有两个或多个参数的parse函数,python,pyparsing,Python,Pyparsing,我正在用它来写一个简单的计算器。在阅读了这个示例之后(并没有完全理解它!),我决定稍微修改它以满足我的需要 以下是我的代码(大部分代码取自): def夏季(p1、p2): 返回p1+p2 类NumericStringParser(对象): ''' 大部分代码来自fourFn.py解析示例 ''' def推送优先(自身、strg、loc、toks): self.exprStack.append(toks[0]) def pushUMinus(自身、strg、loc、toks): 如果toks和to

我正在用它来写一个简单的计算器。在阅读了这个示例之后(并没有完全理解它!),我决定稍微修改它以满足我的需要

以下是我的代码(大部分代码取自):

def夏季(p1、p2):
返回p1+p2
类NumericStringParser(对象):
'''
大部分代码来自fourFn.py解析示例
'''
def推送优先(自身、strg、loc、toks):
self.exprStack.append(toks[0])
def pushUMinus(自身、strg、loc、toks):
如果toks和toks[0]='-':
self.exprStack.append('一元-'))
定义初始化(自):
"""
expop::“^”
multop::“*”|“/”
addop::“+”|“-”
整数::['+'|'-']'0'..'9'+
原子::π| E | real | fn'('expr')'|'('expr')'
因子::原子[expop因子]*
术语::因子[多顶因子]*
expr::term[addop term]*
"""
点=文字(“.”)
e=无案例横向(“e”)
fnumber=组合(单词(“+-”+nums,nums)+
可选(点+可选(字(nums)))+
可选(e+字(“+-”+nums,nums)))
ident=Word(字母,字母+nums+“$”)
加号=文字(“+”)
减号=文字(“-”)
mult=文字(“*”)
div=文字(“/”)
lpar=Literal(“”.suppress()
rpar=Literal(“”)。suppress()
逗号=文字(',')。抑制()
addop=正|负
multop=mult | div
expop=Literal(“^”)
pi=无案例横向(“pi”)
expr=Forward()
atom=((可选(“-+”之一)+
(
pi | e | fnumber | ident+lpar+expr+rpar | ident+lpar+expr+逗号+expr+rpar)(
自我介绍(第一)
|可选(一个(“-+”))+组(lpar+expr+rpar)
).setParseAction(self.pushumius)
#通过将指数定义为“原子[^factor]…”而不是
#“atom[^atom]…”,我们得到的是从右到左的指数,而不是从左到右的指数
#也就是说,2^3^2=2^(3^2),而不是(2^3)^2。
因子=正向()
因素
def summer(p1, p2):
    return p1 + p2

class NumericStringParser(object):
    '''
    Most of this code comes from the fourFn.py pyparsing example

    '''

    def pushFirst(self, strg, loc, toks):
        self.exprStack.append(toks[0])

    def pushUMinus(self, strg, loc, toks):
        if toks and toks[0] == '-':
            self.exprStack.append('unary -')

    def __init__(self):
        """
        expop   :: '^'
        multop  :: '*' | '/'
        addop   :: '+' | '-'
        integer :: ['+' | '-'] '0'..'9'+
        atom    :: PI | E | real | fn '(' expr ')' | '(' expr ')'
        factor  :: atom [ expop factor ]*
        term    :: factor [ multop factor ]*
        expr    :: term [ addop term ]*
        """
        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()
        comma = Literal(',').suppress()
        addop = plus | minus
        multop = mult | div
        expop = Literal("^")
        pi = CaselessLiteral("PI")
        expr = Forward()
        atom = ((Optional(oneOf("- +")) +
                 (
                 pi | e | fnumber | ident + lpar + expr + rpar | ident + lpar + expr + comma + expr + rpar).setParseAction(
                     self.pushFirst))
                | Optional(oneOf("- +")) + Group(lpar + expr + rpar)
                ).setParseAction(self.pushUMinus)

        # by defining exponentiation as "atom [ ^ factor ]..." instead of
        # "atom [ ^ atom ]...", we get right-to-left exponents, instead of left-to-right
        # that is, 2^3^2 = 2^(3^2), not (2^3)^2.
        factor = Forward()
        factor << atom + ZeroOrMore((expop + factor).setParseAction(self.pushFirst))
        term = factor + ZeroOrMore((multop + factor).setParseAction(self.pushFirst))
        expr << term + ZeroOrMore((addop + term).setParseAction(self.pushFirst))
        # addop_term = ( addop + term ).setParseAction( self.pushFirst )
        # general_term = term + ZeroOrMore( addop_term ) | OneOrMore( addop_term)
        # expr <<  general_term
        self.bnf = expr
        # map operator symbols to corresponding arithmetic operations
        epsilon = 1e-12
        self.opn = {"+": operator.add,
                    "-": operator.sub,
                    "*": operator.mul,
                    "/": operator.truediv,
                    "^": operator.pow}
        self.fn = {"sin": math.sin,
                   "cos": math.cos,
                   "tan": math.tan,
                   "abs": abs,
                   "trunc": lambda a: int(a),
                   "round": round,
                   "sgn": lambda a: abs(a) > epsilon and cmp(a, 0) or 0}
        self.fn2 = {"sum": summer}

    def evaluateStack(self, s):
        op = s.pop()
        if op == 'unary -':
            res = self.evaluateStack(s)
            return -res
        if op in "+-*/^":
            op2 = self.evaluateStack(s)
            op1 = self.evaluateStack(s)
            res = self.opn[op](op1, op2)
            return res
        elif op == "PI":
            return math.pi  # 3.1415926535
        elif op == "E":
            return math.e  # 2.718281828
        elif op in self.fn:
            return self.fn[op](self.evaluateStack(s))
        elif op in self.fn2:
            op2 = self.evaluateStack(s)
            op1 = self.evaluateStack(s)
            return self.fn2[op](op1, op2)
        elif op[0].isalpha():
            return 0
        else:
            return float(op)

    def eval(self, num_string, parseAll=True):
        self.exprStack = []
        results = self.bnf.parseString(num_string, parseAll)

        val = self.evaluateStack(self.exprStack[:])
        return val


n = NumericStringParser()
print(n.eval('(4.0*sum(3,3))^1'))