Commits

Anonymous committed 9223ad0

kick out collections.UserDict because of clashes with metaclass

Comments (0)

Files changed (5)

 	PYTHONPATH=`pwd` $(PYTHON) pypeg2/test/test_xmlast.py
 	PYTHONPATH=`pwd` $(PYTHON) samples/sample1.py
 	PYTHONPATH=`pwd` $(PYTHON) samples/sample2.py
+
+install: dist
+	$(PYTHON) setup.py install --user

docs/heading.en.yinc2

 div id="headline" {
     p > pyPEG – a PEG Parser-Interpreter in Python
     div class="small" {
-        "pyPEG 2.2.0 of Sa May 26 2012 – Copyleft 2009-2012, "
+        "pyPEG 2.3.0 of Sa May 26 2012 – Copyleft 2009-2012, "
         a "http://fdik.org", "Volker Birk";
     }
     div id=python1 p {

pypeg2/__init__.py

 This program is under GNU General Public License 2.0.
 """
 
-__version__ = 2.2
+__version__ = 2.3
 __author__ = "Volker Birk"
 __license__ = "This program is under GNU General Public License 2.0."
 __url__ = "http://fdik.org/pyPEG"
 word = re.compile(r"\w+")
 """Regular expression for scanning a word."""
 
-RegEx = type(word)
-"""Type of compiled regex."""
+_RegEx = type(word)
 
 restline = re.compile(r".*")
 """Regular expression for rest of line."""
                 yield a
 
 
+class RegEx:
+    """Regular Expression.
+
+    Instance Variables:
+        regex       pre-compiled object from re.compile()
+    """
+
+    def __init__(self, value):
+        self.value = value
+        self.regex = re.compile(value)
+        self.search = self.regex.search
+        self.match = self.regex.match
+        self.split = self.regex.split
+        self.findall = self.regex.findall
+        self.finditer = self.regex.finditer
+        self.sub = self.regex.sub
+        self.subn = self.regex.subn
+        self.flags = self.regex.flags
+        self.groups = self.regex.groups
+        self.groupindex = self.regex.groupindex
+        self.pattern = value
+
+    def __str__(self):
+        return self.value
+
 class List(list):
     """A List of things."""
 
         """Construct a List, and construct its attributes from keyword
         arguments.
         """
-        if len(args) == 1 and isinstance(args, collections.Iterable):
-            super().__init__(args[0])
+        if len(args) == 1:
+            if isinstance(args[0], str):
+                self.append(args[0])
+            else:
+                super().__init__(args[0])
         else:
             super().__init__(args)
+
         for k, v in kwargs:
             setattr(self, k, v)
 
         return ''.join((type(self).__name__, "(", super().__repr__(), ")"))
 
 
-class Namespace(collections.UserDict):
+class _UserDict:
+    # collections.UserDict cannot be used because of metaclass conflicts
+    def __init__(self, *args, **kwargs):
+        self.data = dict(args, kwargs)
+    def __len__(self):
+        return len(self.data)
+    def __getitem__(self, key):
+        return self.data[key]
+    def __setitem__(self, key, value):
+        self.data[key] = value
+    def __delitem__(self, key):
+        del self.data[key]
+    def __iter__(self):
+        return self.data.keys()
+    def __contains__(self, item):
+        return item in self.data
+    def items(self):
+        return self.data.items()
+    def keys(self):
+        return self.data.keys()
+    def values(self):
+        return self.data.values()
+    def clear(self):
+        self.data.clear()
+    def copy(self):
+        return self.data.copy()
+
+
+class Namespace(_UserDict):
     """A dictionary of things, indexed by their name."""
 
     def __init__(self, *args, **kwargs):
 """Shortcut for Keyword."""
 
 
+class Concat(List):
+    """Concatenation of things.
+
+    This class exists as a mutable alternative to using a tuple.
+    """
+
+
 def name():
     """Generate a grammar for a symbol with name."""
     return attr("name", Symbol)
                     if grammar contains an illegal cardinality value
     """
 
-    if type(grammar) == list:
-        return reduce(lambda a, b: max(how_many(a), how_many(b)), grammar)
+    if grammar is None:
+        return 0
 
-    elif type(grammar) == tuple:
+    elif _issubclass(grammar, Symbol) or isinstance(grammar, (RegEx, _RegEx)):
+        return 1
+
+    elif isinstance(grammar, str):
+        return 0
+
+    elif isinstance(grammar, attr.Class):
+        return 0
+
+    elif type(grammar) == FunctionType:
+        return 0
+
+    elif isinstance(grammar, (tuple, Concat)):
         length, card = 0, 1
         for e in grammar:
             if type(e) == int:
                     return 2
         return length
 
-    elif type(grammar) == str or isinstance(grammar, Keyword):
-        return 0
-
-    elif isinstance(grammar, Symbol) or isinstance(grammar, RegEx):
-        return 1
-
-    elif isinstance(grammar, attr.Class):
-        return 0
-
-    elif type(grammar) == FunctionType:
-        return 0
+    elif isinstance(grammar, list):
+        return reduce(lambda a, b: max(how_many(a), how_many(b)), grammar)
 
     elif _issubclass(grammar, object):
         try:
             else:
                 result = text, syntax_error("expecting " + repr(thing))
 
-        elif isinstance(thing, str):
-            if text.startswith(thing):
-                t, r = text[len(thing):], None
-                t = self._skip(t)
-                result = t, r
-                update_pos(text, t, pos)
-            else:
-                result = text, syntax_error("expecting " + repr(thing))
-
-        elif isinstance(thing, RegEx):
+        elif isinstance(thing, (RegEx, _RegEx)):
             m = thing.match(text)
             if m:
                 t, r = text[len(m.group(0)):], m.group(0)
                 result = text, syntax_error("expecting match on "
                         + thing.pattern)
 
+        elif isinstance(thing, str):
+            if text.startswith(thing):
+                t, r = text[len(thing):], None
+                t = self._skip(t)
+                result = t, r
+                update_pos(text, t, pos)
+            else:
+                result = text, syntax_error("expecting " + repr(thing))
+
         elif _issubclass(thing, Symbol):
             m = thing.regex.match(text)
             if m:
                 else:
                     result = t, attr(thing.name, r)
 
-        elif isinstance(thing, tuple):
+        elif isinstance(thing, (tuple, Concat)):
             L = []
             t = text
             flag = True
             t, r = self._parse(text, g, pos)
             if type(r) != SyntaxError:
                 obj = thing()
-                for e in r:
-                    if type(e) == attr.Class:
-                        setattr(obj, e.name, e.thing)
+                if type(r) == list:
+                    for e in r:
+                        if type(e) == attr.Class:
+                            setattr(obj, e.name, e.thing)
+                        else:
+                            obj.append(e)
+                else:
+                    if type(r) == attr.Class:
+                        setattr(obj, r.name, r.thing)
                     else:
-                        obj.append(e)
+                        obj.append(r)
                 try:
                     obj.polish()
                 except AttributeError:
             else:
                 result = self.compose(thing, grammar(thing, self))
 
-        elif isinstance(grammar, str):
-            result = terminal_indent() + str(grammar)
-
-        elif isinstance(grammar, RegEx):
+        elif isinstance(grammar, (RegEx, _RegEx)):
             m = grammar.match(str(thing))
             if m:
                 result = terminal_indent() + str(thing)
             else:
                 raise ValueError(repr(thing) + " does not match " + grammar.pattern)
 
+        elif isinstance(grammar, str):
+            result = terminal_indent() + str(grammar)
+
         elif isinstance(grammar, Enum):
             if thing in grammar:
                 result = terminal_indent() + str(thing)
             else:
                 result = self.compose(getattr(thing, grammar.name), grammar.thing)
 
-        elif isinstance(grammar, list):
-            found = False
-            for g in grammar:
-                try:
-                    result = self.compose(thing, g)
-                    found = True
-                    break
-                except GrammarTypeError:
-                    raise
-                except AttributeError:
-                    pass
-                except KeyError:
-                    pass
-                except TypeError:
-                    pass
-                except ValueError:
-                    pass
-            if not found:
-                raise ValueError("none of the options in " + repr(grammar)
-                        + " found")
-
-        elif isinstance(grammar, tuple):
+        elif isinstance(grammar, (tuple, Concat)):
             def compose_tuple(thing, things, grammar):
                 text = []
                 multiple, card = 1, 1
             else:
                 result = compose_tuple(thing, thing, grammar)
 
+        elif isinstance(grammar, list):
+            found = False
+            for g in grammar:
+                try:
+                    result = self.compose(thing, g)
+                    found = True
+                    break
+                except GrammarTypeError:
+                    raise
+                except AttributeError:
+                    pass
+                except KeyError:
+                    pass
+                except TypeError:
+                    pass
+                except ValueError:
+                    pass
+            if not found:
+                raise ValueError("none of the options in " + repr(grammar)
+                        + " found")
+
         elif _issubclass(grammar, object):
             if isinstance(thing, grammar):
                 try:
 This program is under GNU General Public License 2.0.
 """
 
-__version__ = 2.2
+__version__ = 2.3
 __author__ = "Volker Birk"
 __license__ = "This program is under GNU General Public License 2.0."
 __url__ = "http://fdik.org/pyPEG"
 
 setup(
     name='pyPEG2',
-    version='2.2.0',
+    version='2.3.0',
     author='Volker Birk',
     author_email='vb@dingens.org',
     packages=['pypeg2', 'pypeg2.test'],