###### CNxiaolin
2018-11-27 12:19 阅读 680

# 一道python实现简单编译器的问题

*signop = oneOf('+ -')，用于标示正副符号。

arith_expr = operatorPrecedence(operand,
[(signop, 1, opAssoc.RIGHT, EvalSignOp),
(multop, 2, opAssoc.LEFT, EvalMultOp),
])
EvalSignOp类：处理符号数的类，以识别出来的符号tokens列表的第0项为处理对象，该项包含了符号及数值。因此，类初始化函数中要从tokens[0]中提取出sign和value。在eval方法中，根据sign和value得到实际的值。

digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
nonzero = "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
integer = nonzero, { digit } ;
real = integer, ".", integer
operand = integer | real
operator = "+" | "-" | "*" | "/";
expression = operand | "(", expression, operator, expression, ")";

def main(strExpr):
integer = "0"|Word(nums[1:],nums)
real = Combine(integer + "." + Word(nums))
variable = Word(alphas)
operand = real | integer | variable
multop = oneOf('* / // %')
plusop = oneOf('+ -')
operand.setParseAction(EvalConstant)
arith_expr = operatorPrecedence(operand,
[(multop, 2, opAssoc.LEFT, EvalMultOp),
])
ret = arith_expr.parseString(strExpr, parseAll=True)[0]
result = ret.eval()
return result

class EvalConstant():
def init(self, tokens):
self.value = tokens[0]
def eval(self):
try:
return int(self.value)
except:
return float(self.value)
def operatorOperands(tokenlist):
it = iter(tokenlist)
while 1:
try:
o1 = next(it)
o2 = next(it)
yield (o1, o2)
except StopIteration:
break
class EvalMultOp():
def init(self, tokens):
self.value = tokens[0]
def eval(self):
prod = self.value[0].eval()
for op, val in operatorOperands(self.value[1:]):
if op == '*':
prod *= val.eval()
if op == '/':
prod /= val.eval()
return prod
def init(self, tokens):
self.value = tokens[0]
def eval(self):
sum = self.value[0].eval()
for op, val in operatorOperands(self.value[1:]):
if op == '+':
sum += val.eval()
if op == '-':
sum -= val.eval()
return sum

from pyparsing import Word, nums, alphas, Combine, oneOf, opAssoc, operatorPrecedence
class EvalConstant():
def init(self, tokens):
self.value = tokens[0]
def eval(self):
try:
return int(self.value)
except:
return float(self.value)
class EvalSignOp(object):
def init(self, tokens):
# 请在此添加代码，补全函数__init__
#-----------Begin----------
#------------End-----------
def eval(self):
# 请在此添加代码，补全函数eval
#-----------Begin----------
#------------End-----------
def operatorOperands(tokenlist):
it = iter(tokenlist)
while 1:
try:
o1 = next(it)
o2 = next(it)
yield (o1, o2)
except StopIteration:
break
class EvalMultOp():
def init(self, tokens):
self.value = tokens[0]
def eval(self):
prod = self.value[0].eval()
for op, val in operatorOperands(self.value[1:]):
if op == '*':
prod = val.eval()
if op == '/':
prod /= val.eval()
return prod
def init(self, tokens):
self.value = tokens[0]
def eval(self):
sum = self.value[0].eval()
for op, val in operatorOperands(self.value[1:]):
if op == '+':
sum += val.eval()
if op == '-':
sum -= val.eval()
return sum
def main(strExpr):
integer = "0"|Word(nums[1:],nums)
real = Combine(integer + "." + Word(nums))
variable = Word(alphas)
operand = real | integer | variable
multop = oneOf('
/ // %')
plusop = oneOf('+ -')
signop = oneOf('+ -')
operand.setParseAction(EvalConstant)
arith_expr = operatorPrecedence(operand,
[(signop, 1, opAssoc.RIGHT, EvalSignOp),
(multop, 2, opAssoc.LEFT, EvalMultOp),
])
ret = arith_expr.parseString(strExpr, parseAll=True)[0]
result = ret.eval()
return result
if name == '__main__':
exprs = ['-12*(3*(-3))-100+(-55)', '90/(-12-(-13))', '1+2+3+4+(-10)-(-11)']
for expr in exprs:
print(main(expr))

• 点赞
• 写回答
• 关注问题
• 收藏
• 复制链接分享