Прикреплённый файл «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 из ссылки «[получить]», так как он чисто внутренний и может измениться.

Вам нельзя прикреплять файлы к этой странице.