python简单计算器综合实验报告_项目一:简单计算器

小小的改进:

运行程序时,输入的字符串有时不小心带有空格。

可以在Buffer的__init__函数内,将self.data = data改为self.data = ''.join(data.split(' '))

代码如下:

#!/usr/bin/env python

# -*- coding: utf-8 -*-

"""

程序分解为以下几个步骤:

1. 输入表达式:使用raw_input获得输入字符串

2. 从表达式字符串中提取整数及操作符,得到 Token列表 (表达式中的元素,有两种类型:操作符元素和整数元素)

3. 从 Token 列表生成表达式树

4. 遍历表达式树求值

5. 输出计算结果

"""

# 输入字符串处理

class Buffer(object):

def __init__(self, data):

self.data = ''.join(data.split(' '))

self.offset = 0

# 提取offset位置处的一个字符

def peek(self):

# 如果没有后续字符,返回None

if self.offset >= len(self.data):

return None

return self.data[self.offset]

# 取字符的位置向后移一位

def advance(self):

self.offset += 1

# 自定义Token

class Token(object):

def consume(self, buffer):

pass

# 整数类型的Token

class IntToken(Token):

# 从字符串读取字符直到字符不是整数

def consume(self, buffer):

accum = ''

while True:

ch = buffer.peek()

if ch is None or ch not in '0123456789':

break

else:

accum += ch

buffer.advance()

# 如果读取的内容不为空则返回整数,否则返回None

if accum != '':

return 'int', int(accum)

else:

return None

# 操作('+','-')类型的Token

class OperatorToken(Token):

# 读取一个字符,然后返回这个字符,如果字符不是+-,则返回None

def consume(self, buffer):

ch = buffer.peek()

if ch is not None and ch in '+-':

buffer.advance()

return 'ope', ch

return None

# 表达式二叉树的节点

class Node(object):

pass

# 整数节点

class IntNode(Node):

def __init__(self, value):

self.value = value

# 操作符节点('+'或'-')

class BinaryOpNode(Node):

def __init__(self, kind):

self.kind = kind

self.left = None # 左节点

self.right = None # 右节点

# 从字符串中获取整数及操作的Token

def tokenize(string):

buffer = Buffer(string)

tk_int = IntToken()

tk_op = OperatorToken()

tokens = []

while buffer.peek():

token = None

# 用两种类型的Token进行测试

for tk in (tk_int, tk_op):

token = tk.consume(buffer)

if token:

tokens.append(token)

break

# 如果不存在可以识别的Token表示输入错误

if not token:

raise ValueError('Error in syntax')

return tokens

# 从Token列表生成表达式二叉树

def parse(tokens):

if tokens[0][0] != 'int':

raise ValueError('Must start with an int')

# 取出tokens[0],该Token类型为整数

node = IntNode(tokens[0][1])

nbo = None

last = tokens[0][0]

# 从第二个Token开始循环取出

for token in tokens[1:]:

# 相邻两个Token的类型一样则为错误

if token[0] == last:

raise ValueError('Error in syntax')

last = token[0]

# 如果Token为操作符,则保存为操作符节点,把前一个整数Token作为左子节点

if token[0] == 'ope':

nbo = BinaryOpNode(token[1])

nbo.left = node

# 如果Token为整数,则将该Token保存为右节点

if token[0] == 'int':

nbo.right = IntNode(token[1])

node = nbo

return node

# 采用递归的方法计算表达式二叉树的值

def calculate(nbo):

# 如果左节点是二叉树,则先计算左节点二叉树的值

if isinstance(nbo.left, BinaryOpNode):

left_val = calculate(nbo.left)

else:

left_val = nbo.left.value

# 根据操作符节点加还是减计算

if nbo.kind == '-':

return left_val - nbo.right.value

elif nbo.kind == '+':

return left_val + nbo.right.value

else:

raise ValueError('Wrong operator')

# 判断是否只输入了一个整数

def evaluate(node):

# 如果表达式中只有一个整数,则直接返回值

if isinstance(node, IntNode):

return node.value

else:

return calculate(node)

if __name__ == '__main__':

while True:

# 获取输入字符串

my_input = raw_input('Input(q to quit):')

if my_input.lower() == 'q':

break

# 从字符串获取Token列表

tokens = tokenize(my_input)

# 从Token列表生成表达式树

node = parse(tokens)

# 遍历计算并输出结果

print 'Result:%s:' % evaluate(node)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值