Прикреплённый файл «ocalc.py»
Загрузка 1 #!/usr/bin/python
2 # coding: utf-8
3 '''
4 Реализовать калькулятор для выражений, записанных в польской инверсной записи. В качестве разделителя лексем допускать произвольное количество пробелов. Решить задачу с использованием объектно-ориентированного подхода:
5
6 * для каждого типа операндов определить свой класс, в котором определить:
7 o метод-распознаватель текстового представления объекта, который умеет найти его в начале некоторой строки, и если он нашелся, то сконструировать нужный объект и удалить использованную часть строки (для продолжения анализа).
8 o методы-операции, поддерживающие обработку разных типов объектов-операндов. '''
9
10 import re,sys
11
12 class Obj:
13 re=re.compile("\S+")
14 type=str
15 @classmethod
16 def Parse(self, line):
17 v=self.re.match(line)
18 if v:
19 return self(v.group()),line[len(v.group()):].strip()
20 else:
21 return (None, line)
22 def __init__(self, word):
23 self.repr=word
24 self.value=self.type(word)
25 def __repr__(self):
26 return "<{0}:{1}>".format(self.__class__,self.repr)
27
28 class Int(Obj):
29 re=re.compile(r"\d+")
30 type=int
31
32 class Real(Obj):
33 re=re.compile(r"\d+[.]\d*")
34 type=float
35
36 class Str(Obj):
37 re=re.compile(r'"[^"]+"')
38 def __init__(self, word):
39 Obj.__init__(self, word)
40 self.value=self.value[1:-1]
41
42 class Op(Obj):
43 methods={
44 "+":"__add__",
45 "-":"__sub__",
46 "*":"__mul__",
47 "/":"__div__",
48 "**":"__pow__",
49 }
50 re=re.compile(r"[+*/-]|\*\*")
51
52 Classes=(Real, Int, Str)
53 Stack=[]
54
55 while True:
56 print ">",
57 line=raw_input()
58 if not line: sys.exit()
59 while line:
60 for C in Classes+(Op,):
61 obj, line = C.Parse(line)
62 if obj: break
63 else:
64 print "### Cannot parse:",line
65 line=""
66 break
67 if obj.__class__ in Classes:
68 Stack.append(obj)
69 else: # Op
70 function=getattr(Stack[-2].value,Op.methods[obj.repr])
71 res=function(Stack[-1].value)
72 # TODO: использовать Parse вместо сопоставления с типами
73 for C in Classes:
74 if C.type == type(res):
75 Stack.pop()
76 Stack.pop()
77 Stack.append(C(res))
78 break
79 else:
80 print "### Cannot convert {0}={1}".format(type(res),res)
81 line=""
82 continue
83 else:
84 print Stack.pop().value
85 if Stack: print "### Non-empty atack:",Stack
Прикреплённые файлы
Для ссылки на прикреплённый файл в тексте страницы напишите attachment:имяфайла, как показано ниже в списке файлов. Не используйте URL из ссылки «[получить]», так как он чисто внутренний и может измениться.- [получить | показать] (2011-09-26 11:35:38, 2.8 KB) [[attachment:Sav_arbuz_ch.py]]
- [получить | показать] (2011-09-26 11:35:38, 2.3 KB) [[attachment:arbuz2.py]]
- [получить | показать] (2011-09-26 11:35:38, 3.0 KB) [[attachment:ocalc.py]]
Вам нельзя прикреплять файлы к этой странице.