/usr/share/pyshared/csa/csaobject.py is in python-csa 0.1.0-1.1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | #
# This file is part of the Connection-Set Algebra (CSA).
# Copyright (C) 2010,2011,2012 Mikael Djurfeldt
#
# CSA is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# CSA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
try:
from lxml import etree
from lxml.builder import E
except ImportError:
pass
csa_tag = 'CSA'
csa_namespace = 'http://software.incf.org/software/csa/1.0'
CSA = '{%s}' % csa_namespace
CUSTOM = -4
OPERATOR = -3
BINDOPERATOR = -2
SINGLETON = -1
def to_xml (obj):
if isinstance (obj, str):
return E (obj)
elif isinstance (obj, (int, float)):
return E ('cn', str (obj))
elif isinstance (obj, CSAObject):
return obj._to_xml ()
else:
raise RuntimeError, "don't know how to turn %s into xml" % obj
# precedence levels:
#
# 0 + -
# 1 *
# 2 ~
class CSAObject (object):
tag_map = {}
def __init__ (self, name, precedence = 3):
self.name = name
self.precedence = precedence
def __repr__ (self):
return 'CSA(%s)' % self.repr ()
def repr (self):
if hasattr (self, 'name'):
return self.name
else:
return self.__class__.__name__
def _repr_as_op2 (self, parentPrecedence):
if self.precedence <= parentPrecedence:
return '(%s)' % self.repr ()
else:
return self.repr ()
def _repr_applyop (self, op_repr, obj):
return '%s*%s' % (op_repr, obj._repr_as_op2 (1))
def to_xml (self):
return E (csa_tag, self._to_xml (), xmlns=csa_namespace)
def _to_xml (self):
return E (self.name)
@classmethod
def apply (cls, operator, *operands):
return E ('apply', to_xml (operator), *map (to_xml, operands))
@classmethod
def formalFromXML (cls, element):
assert element.tag == CSA + 'bvar'
nodes = element.getchildren ()
assert nodes[0].tag == CSA + 'ci'
return nodes[0].text
@classmethod
def from_xml (cls, element, env = {}):
if element.tag == CSA + 'cn':
return eval (element.text)
elif element.tag == CSA + 'ci':
#*fixme* Implement env as lists of dictionaries
return env[element.text]
elif element.tag == CSA + 'apply':
nodes = element.getchildren ()
operator = nodes[0].tag
operands = [ cls.from_xml (e, env) for e in nodes[1:] ]
if operator == CSA + 'plus':
return operands[0].__add__ (operands[1])
elif operator == CSA + 'minus':
return operands[0].__sub__ (operands[1])
elif operator == CSA + 'times':
return operands[0].__mul__ (operands[1])
elif operator == CSA + 'complement':
return operands[0].__invert__ ()
else:
# Function or operator application
entry = CSAObject.tag_map[operator]
obj = entry[0]
if entry[1] == OPERATOR:
return obj * operands[1]
else:
return obj (*operands)
elif element.tag == CSA + 'bind':
nodes = element.getchildren ()
tag = nodes[0].tag
entry = CSAObject.tag_map[tag]
if entry[1] != BINDOPERATOR:
raise RuntimeError, "unknown binding operator tag %s" % tag
bindingOperator = entry[0]
bvars = [ CSAObject.formalFromXML (e) for e in nodes[1:-1] ]
return bindingOperator (bvars, nodes[-1])
elif element.tag in CSAObject.tag_map:
entry = CSAObject.tag_map[element.tag]
obj = entry[0]
if entry[1] == SINGLETON:
return obj
elif entry[1] == CUSTOM:
return obj.from_xml (element, env)
else:
return obj ()
else:
raise RuntimeError, "don't know how parse tag %s" % element.tag
def xml (e):
print etree.tostring (e)
def write(self, file):
doc = self.to_xml ()
etree.ElementTree(doc).write (file, encoding="UTF-8",
pretty_print=True, xml_declaration=True)
class BinaryCSAObject (CSAObject):
operator_table = {'+': 'plus', '-': 'minus', '*': 'times'}
def __init__ (self, name, op1, op2, precedence = 0):
CSAObject.__init__ (self, name, precedence)
self.op1 = op1
self.op2 = op2
def repr (self):
if isinstance (self.op1, CSAObject):
op1 = self.op1.repr ()
if self.op1.precedence < self.precedence:
op1 = "(%s)" % op1
else:
op1 = self.op1
if isinstance (self.op2, CSAObject):
op2 = self.op2._repr_as_op2 (self.precedence)
else:
op2 = self.op2
return "%s%s%s" % (op1, self.name, op2)
def _to_xml (self):
if isinstance (self.op1, CSAObject):
op1 = self.op1._to_xml ()
else:
op1 = self.op1
if isinstance (self.op2, CSAObject):
op2 = self.op2._to_xml ()
else:
op2 = self.op2
if self.name in BinaryCSAObject.operator_table:
op = BinaryCSAObject.operator_table[self.name]
else:
op = self.name
return E ('apply', E (op), op1, op2)
class OpExprValue (BinaryCSAObject):
def __init__ (self, operator, operand):
BinaryCSAObject.__init__ (self, '*', operator, operand, 1)
class Operator (CSAObject):
def __init__ (self, name='ioperator'):
CSAObject.__init__ (self, name)
def from_xml (root):
assert root.nsmap[None] == csa_namespace
return CSAObject.from_xml (root.getchildren ()[0])
def parse (filename):
doc = etree.parse (filename)
return from_xml (doc.getroot())
def registerTag (tag, obj, mode):
CSAObject.tag_map[CSA + tag] = (obj, mode)
|