Browse Source

Initial pass at removing Py2 compatability

Version 2.50
remove_py2
Jason Morgan 6 months ago
parent
commit
825495c887
7 changed files with 140 additions and 64 deletions
  1. +2
    -1
      CHANGES.txt
  2. +1
    -1
      README.md
  3. +58
    -44
      pypeg2/__init__.py
  4. +63
    -8
      pypeg2/test/test_pyPEG2.py
  5. +14
    -7
      pypeg2/test/test_xmlast.py
  6. +1
    -1
      pypeg2/xmlast.py
  7. +1
    -2
      setup.py

+ 2
- 1
CHANGES.txt View File

@ -1 +1,2 @@
v2.0, 05/12/2012 -- Initial release of rewrite for Python 3.x
v2.0, 05/12/2012 -- Initial release of rewrite for Python 3.x
v2.50, 18/11/2021 -- Remove support for Python 2

+ 1
- 1
README.md View File

@ -1,4 +1,4 @@
pyPEG 2 for Python 2.7 and 3.x
pyPEG 2 for Python 3.5+
==============================
Python is a nice scripting language. It even gives you access to its own parser


+ 58
- 44
pypeg2/__init__.py View File

@ -2,26 +2,18 @@
pyPEG parsing framework
pyPEG offers a packrat parser as well as a framework to parse and output
languages for Python 2.7 and 3.x, see http://fdik.org/pyPEG2
languages for Python 3.5+, see http://fdik.org/pyPEG2
Copyleft 2012, Volker Birk.
This program is under GNU General Public License 2.0.
"""
from __future__ import unicode_literals
import collections
try:
range = xrange
str = unicode
except NameError:
pass
import logging
logger = logging.getLogger("pyPEG2")
__version__ = 2.15
__version__ = 2.50
__author__ = "Volker Birk"
__license__ = "This program is under GNU General Public License 2.0."
__url__ = "http://fdik.org/pyPEG"
@ -29,19 +21,13 @@ __url__ = "http://fdik.org/pyPEG"
import re
import sys
try:
maxsize = sys.maxint
except AttributeError:
maxsize = sys.maxsize
import weakref
if __debug__:
import warnings
from types import FunctionType
from collections import namedtuple
try:
from collections import OrderedDict
except ImportError:
from ordereddict import OrderedDict
from collections import OrderedDict
from collections import UserString
word = re.compile(r"\w+")
@ -111,6 +97,7 @@ def _csl(separator, *thing):
L.append(tuple(L2))
return tuple(L)
try:
# Python 3.x
_exec = eval("exec")
@ -139,6 +126,7 @@ def attr(name, thing=word, subtype=None):
# + repr(name), SyntaxWarning)
return attr.Class(name, thing, subtype)
attr.Class = namedtuple("Attribute", ("name", "thing", "subtype"))
@ -203,6 +191,7 @@ class Literal(object):
"""Literal value."""
_basic_types = (bool, int, float, complex, str, bytes, bytearray, list,
tuple, slice, set, frozenset, dict)
def __init__(self, value, **kwargs):
logger.debug(f"New Literal({value})")
if isinstance(self, Literal._basic_types):
@ -237,7 +226,8 @@ class Literal(object):
else:
return False
class Str(collections.UserString):
class Str(UserString):
"""A mutable string like object"""
def __new__(cls, x):
@ -258,6 +248,7 @@ class Str(collections.UserString):
except AttributeError:
return self.__class__.__name__ + f"(data={self.data})"
class Plain(object):
"""A plain object"""
@ -328,39 +319,54 @@ class _UserDict(object):
# 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."""
name_by = lambda value: "#" + str(id(value))
@staticmethod
def name_by(value):
return "#" + str(id(value))
def __init__(self, *args, **kwargs):
"""Initialize an OrderedDict containing the data of the Namespace.
Arguments are being put into the Namespace, keyword arguments give the
attributes of the Namespace.
"""
super().__init__(*args, **kwargs)
logger.debug(f"New Namespace({args}, {kwargs})")
if args:
self.data = OrderedDict(args)
@ -405,7 +411,8 @@ class Namespace(_UserDict):
result += "]"
try:
result += ", name=" + repr(self.name)
except:
# BUG(JM): self.name is not an attribute of Namespace
except NameError:
pass
return result + ")"
@ -416,6 +423,7 @@ class Enum(Namespace):
def __init__(self, *things, **kwargs):
"""Construct an Enum using a tuple of things."""
super().__init__(*things, **kwargs)
logger.debug(f"New Enum({things})")
self.data = OrderedDict()
for thing in things:
@ -433,7 +441,8 @@ class Enum(Namespace):
result = type(self).__name__ + "(" + repr(v)
try:
result += ", name=" + repr(self.name)
except:
# BUG(JM): self.name is not an attribute of Namespace
except NameError:
pass
return result + ")"
@ -496,6 +505,7 @@ class Keyword(Symbol):
def __init__(self, keyword):
"""Adds keyword to the keyword table."""
super().__init__(keyword)
if keyword not in Keyword.table:
Keyword.table[keyword] = self
self.name = keyword
@ -526,6 +536,7 @@ class Concat(List):
This class exists as a mutable alternative to using a tuple.
"""
pass
def name():
@ -568,11 +579,15 @@ def omit(*thing):
return _card(-6, thing)
endl = lambda thing, parser: "\n"
"""End of line marker for composing text."""
def endl(thing, parser):
"""End of line marker for composing text."""
return "\n"
def blank(thing, parser):
"""Space marker for composing text."""
return " "
blank = lambda thing, parser: " "
"""Space marker for composing text."""
class GrammarError(Exception):
@ -625,8 +640,7 @@ def how_many(grammar):
for e in grammar:
if type(e) == int:
if e < -6:
raise GrammarValueError(
"illegal cardinality value in grammar: " + str(e))
raise GrammarValueError("illegal cardinality value in grammar: " + str(e))
if e in (-5, -4, -3):
pass
elif e in (-1, -2):
@ -655,8 +669,8 @@ def how_many(grammar):
return 1
else:
raise GrammarTypeError("grammar contains an illegal type: "
+ type(grammar).__name__ + ": " + repr(grammar))
err = f"grammar contains an illegal type: {type(grammar).__name__}: {repr(grammar)}"
raise GrammarTypeError(err)
def parse(text, thing, filename=None, whitespace=whitespace, comment=None,
@ -896,6 +910,7 @@ class Parser(object):
# Parser implementation
logger.debug(f"Parser({self.name})._parse([{type(thing)}]: {repr(text)}, {thing}, {pos})")
def update_pos(text, t, pos):
# Calculate where we are in the text
old_pos = pos
@ -906,12 +921,11 @@ class Parser(object):
logger.debug(f"Parser({self.name})._parse.update_pos(" + f"{pos})" if old_pos == pos else f"{old_pos}->{pos})")
try:
ret = self._memory[id(thing)][text]
logger.debug(f"Parser({self.name})._parse() -> cached ret: {repr(ret)}")
return ret
except:
except (IndexError, KeyError):
pass
if pos:
@ -1067,9 +1081,9 @@ class Parser(object):
elif e == -3:
pass
elif e == -2:
_min, _max = 1, maxsize
_min, _max = 1, sys.maxsize
elif e == -1:
_min, _max = 0, maxsize
_min, _max = 0, sys.maxsize
elif e == 0:
_min, _max = 0, 1
else:
@ -1371,7 +1385,7 @@ class Parser(object):
if grammar is None:
result = ""
#
elif type(grammar) == FunctionType:
if grammar == endl:
result = endl(thing, self)
@ -1380,7 +1394,7 @@ class Parser(object):
result = terminal_indent() + blank(thing, self)
else:
result = self.compose(thing, grammar(thing, self))
#
elif isinstance(grammar, (RegEx, _RegEx)):
m = grammar.match(str(thing))
if m:
@ -1389,14 +1403,14 @@ class Parser(object):
raise ValueError(repr(thing) + " does not match "
+ grammar.pattern)
self._got_regex = True
#
elif isinstance(grammar, Keyword):
result = terminal_indent(do_blank=self._got_regex) + str(grammar)
self._got_regex = True
#
elif isinstance(grammar, (str, int, Literal)):
result = terminal_indent() + str(grammar)
#
elif isinstance(grammar, Enum):
if thing in grammar:
if isinstance(thing, Keyword):
@ -1406,7 +1420,7 @@ class Parser(object):
result = terminal_indent() + str(thing)
else:
raise ValueError(repr(thing) + " is not in " + repr(grammar))
#
elif isinstance(grammar, attr.Class):
if grammar.subtype == "Flag":
if getattr(thing, grammar.name):
@ -1416,7 +1430,7 @@ class Parser(object):
else:
result = self.compose(getattr(thing, grammar.name),
grammar.thing, attr_of=thing)
#
elif isinstance(grammar, (tuple, list)):
def compose_tuple(thing, things, grammar):
text = []
@ -1437,7 +1451,7 @@ class Parser(object):
+ str(g))
card = g
if g in (-2, -1):
multiple = maxsize
multiple = sys.maxsize
elif g in (-5, -4, -3, 0):
multiple = 1
if g == -3:
@ -1527,7 +1541,7 @@ class Parser(object):
else:
L = [thing]
result = compose_tuple(thing, L, grammar)
#
elif _issubclass(grammar, object):
if isinstance(thing, grammar):
try:
@ -1544,7 +1558,7 @@ class Parser(object):
result = self.compose(str(thing), Symbol.regex)
else:
raise ValueError(repr(thing) + " is not a " + repr(grammar))
#
else:
raise GrammarTypeError("in grammar: " + repr(grammar))


+ 63
- 8
pypeg2/test/test_pyPEG2.py View File

@ -1,9 +1,8 @@
from __future__ import unicode_literals
import unittest
import pypeg2
import re
class GrammarTestCase1(unittest.TestCase):
def runTest(self):
x = pypeg2.some("thing")
@ -13,6 +12,7 @@ class GrammarTestCase1(unittest.TestCase):
self.assertEqual(y, (-1, "thing"))
self.assertEqual(z, (0, ("hello", "world")))
class GrammarTestCase2(unittest.TestCase):
def runTest(self):
L1 = pypeg2.csl("thing")
@ -20,26 +20,31 @@ class GrammarTestCase2(unittest.TestCase):
self.assertEqual(L1, ("thing", -1, (",", pypeg2.blank, "thing")))
self.assertEqual(L2, ("hello", "world", -1, (",", pypeg2.blank, "hello", "world")))
class ParserTestCase(unittest.TestCase): pass
class TypeErrorTestCase(ParserTestCase):
def runTest(self):
parser = pypeg2.Parser()
with self.assertRaises(pypeg2.GrammarTypeError):
parser.parse("hello, world", 23)
class ParseTerminalStringTestCase1(ParserTestCase):
def runTest(self):
parser = pypeg2.Parser()
r = parser.parse("hello, world", "hello")
self.assertEqual(r, (", world", None))
class ParseTerminalStringTestCase2(ParserTestCase):
def runTest(self):
parser = pypeg2.Parser()
with self.assertRaises(SyntaxError):
r = parser.parse("hello, world", "world")
class ParseKeywordTestCase1(ParserTestCase):
def runTest(self):
parser = pypeg2.Parser()
@ -47,6 +52,7 @@ class ParseKeywordTestCase1(ParserTestCase):
self.assertEqual(r, (", world", None))
pypeg2.Keyword.table[pypeg2.K("hallo")]
class ParseKeywordTestCase2(ParserTestCase):
def runTest(self):
parser = pypeg2.Parser()
@ -54,6 +60,7 @@ class ParseKeywordTestCase2(ParserTestCase):
r = parser.parse("hello, world", pypeg2.K("werld"))
pypeg2.Keyword.table[pypeg2.K("werld")]
class ParseKeywordTestCase3(ParserTestCase):
def runTest(self):
parser = pypeg2.Parser()
@ -61,30 +68,35 @@ class ParseKeywordTestCase3(ParserTestCase):
r = parser.parse(", world", pypeg2.K("hallo"))
pypeg2.Keyword.table[pypeg2.K("hallo")]
class ParseRegexTestCase1(ParserTestCase):
def runTest(self):
parser = pypeg2.Parser()
r = parser.parse("hello, world", re.compile(r"h.[lx]l\S", re.U))
self.assertEqual(r, (", world", "hello"))
class ParseRegexTestCase2(ParserTestCase):
def runTest(self):
parser = pypeg2.Parser()
with self.assertRaises(SyntaxError):
r = parser.parse("hello, world", re.compile(r"\d", re.U))
class ParseSymbolTestCase1(ParserTestCase):
def runTest(self):
parser = pypeg2.Parser()
r = parser.parse("hello, world", pypeg2.Symbol)
self.assertEqual(r, (", world", pypeg2.Symbol("hello")))
class ParseSymbolTestCase2(ParserTestCase):
def runTest(self):
parser = pypeg2.Parser()
with self.assertRaises(SyntaxError):
r = parser.parse(", world", pypeg2.Symbol)
class ParseAttributeTestCase(ParserTestCase):
def runTest(self):
parser = pypeg2.Parser()
@ -93,11 +105,11 @@ class ParseAttributeTestCase(ParserTestCase):
r,
(
', world',
pypeg2.attr.Class(name='some', thing=pypeg2.Symbol('hello'),
subtype=None)
pypeg2.attr.Class(name='some', thing=pypeg2.Symbol('hello'), subtype=None)
)
)
class ParseTupleTestCase1(ParserTestCase):
def runTest(self):
parser = pypeg2.Parser()
@ -107,68 +119,76 @@ class ParseTupleTestCase1(ParserTestCase):
(
'',
[
pypeg2.attr.Class(name='name',
thing=pypeg2.Symbol('hello'), subtype=None),
pypeg2.attr.Class(name='name',
thing=pypeg2.Symbol('world'), subtype=None)
pypeg2.attr.Class(name='name', thing=pypeg2.Symbol('hello'), subtype=None),
pypeg2.attr.Class(name='name', thing=pypeg2.Symbol('world'), subtype=None)
]
)
)
class ParseTupleTestCase2(ParserTestCase):
def runTest(self):
parser = pypeg2.Parser()
with self.assertRaises(ValueError):
parser.parse("hello, world", (-23, "x"))
class ParseSomeTestCase1(ParserTestCase):
def runTest(self):
parser = pypeg2.Parser()
r = parser.parse("hello, world", pypeg2.some(re.compile(r"\w", re.U)))
self.assertEqual(r, (', world', ['h', 'e', 'l', 'l', 'o']))
class ParseSomeTestCase2(ParserTestCase):
def runTest(self):
parser = pypeg2.Parser()
with self.assertRaises(SyntaxError):
r = parser.parse("hello, world", pypeg2.some(re.compile(r"\d", re.U)))
class ParseMaybeSomeTestCase1(ParserTestCase):
def runTest(self):
parser = pypeg2.Parser()
r = parser.parse("hello, world", pypeg2.maybe_some(re.compile(r"\w", re.U)))
self.assertEqual(r, (', world', ['h', 'e', 'l', 'l', 'o']))
class ParseMaybeSomeTestCase2(ParserTestCase):
def runTest(self):
parser = pypeg2.Parser()
r = parser.parse("hello, world", pypeg2.maybe_some(re.compile(r"\d", re.U)))
self.assertEqual(r, ('hello, world', []))
class ParseCardinalityTestCase1(ParserTestCase):
def runTest(self):
parser = pypeg2.Parser()
r = parser.parse("hello, world", (5, re.compile(r"\w", re.U)))
self.assertEqual(r, (', world', ['h', 'e', 'l', 'l', 'o']))
class ParseCardinalityTestCase2(ParserTestCase):
def runTest(self):
parser = pypeg2.Parser()
with self.assertRaises(SyntaxError):
r = parser.parse("hello, world", (6, re.compile(r"\w", re.U)))
class ParseOptionsTestCase1(ParserTestCase):
def runTest(self):
parser = pypeg2.Parser()
r = parser.parse("hello, world", [re.compile(r"\d+", re.U), pypeg2.word])
self.assertEqual(r, (', world', 'hello'))
class ParseOptionsTestCase2(ParserTestCase):
def runTest(self):
parser = pypeg2.Parser()
with self.assertRaises(SyntaxError):
r = parser.parse("hello, world", ["x", "y"])
class ParseListTestCase1(ParserTestCase):
class Chars(pypeg2.List):
grammar = pypeg2.some(re.compile(r"\w", re.U)), pypeg2.attr("comma", ",")
@ -182,6 +202,7 @@ class ParseListTestCase1(ParserTestCase):
)
self.assertEqual(r[1].comma, None)
class ParseListTestCase2(ParserTestCase):
class Digits(pypeg2.List):
grammar = pypeg2.some(re.compile(r"\d", re.U))
@ -191,6 +212,7 @@ class ParseListTestCase2(ParserTestCase):
with self.assertRaises(SyntaxError):
r = parser.parse("hello, world", ParseListTestCase2.Digits)
class ParseClassTestCase1(ParserTestCase):
class Word(str):
grammar = pypeg2.word
@ -201,6 +223,7 @@ class ParseClassTestCase1(ParserTestCase):
self.assertEqual(type(r[1]), ParseClassTestCase1.Word)
self.assertEqual(r[1], "hello")
class ParseClassTestCase2(ParserTestCase):
class Word(str):
grammar = pypeg2.word, pypeg2.attr("comma", ",")
@ -217,13 +240,16 @@ class ParseClassTestCase2(ParserTestCase):
self.assertTrue(r[1].polished)
self.assertEqual(r[1].comma, None)
class Parm(object):
grammar = pypeg2.name(), "=", pypeg2.attr("value", int)
class Parms(pypeg2.Namespace):
grammar = (pypeg2.csl(Parm), pypeg2.flag("fullstop", "."),
pypeg2.flag("semicolon", ";"))
class ParseNLTestCase1(ParserTestCase):
def runTest(self):
parser = pypeg2.Parser()
@ -234,21 +260,25 @@ class ParseNLTestCase1(ParserTestCase):
self.assertEqual(parms.fullstop, False)
self.assertEqual(parms.semicolon, True)
class EnumTest(pypeg2.Symbol):
grammar = pypeg2.Enum( pypeg2.K("int"), pypeg2.K("long") )
class ParseEnumTestCase1(ParserTestCase):
def runTest(self):
parser = pypeg2.Parser()
t, r = parser.parse("int", EnumTest)
self.assertEqual(r, "int")
class ParseEnumTestCase2(ParserTestCase):
def runTest(self):
parser = pypeg2.Parser()
with self.assertRaises(SyntaxError):
t, r = parser.parse("float", EnumTest)
class ParseInvisibleTestCase(ParserTestCase):
class C1(str):
grammar = pypeg2.ignore("!"), pypeg2.restline
@ -257,51 +287,63 @@ class ParseInvisibleTestCase(ParserTestCase):
self.assertEqual(str(r), "all")
self.assertEqual(r._ignore1, None)
class ParseOmitTestCase(ParserTestCase):
def runTest(self):
r = pypeg2.parse("hello", pypeg2.omit(pypeg2.word))
self.assertEqual(r, None)
class ComposeTestCase(unittest.TestCase): pass
class ComposeString(object):
grammar = "something"
class ComposeStringTestCase(ComposeTestCase):
def runTest(self):
x = ComposeString()
t = pypeg2.compose(x)
self.assertEqual(t, "something")
class ComposeRegex(str):
grammar = pypeg2.word
class ComposeRegexTestCase(ComposeTestCase):
def runTest(self):
x = ComposeRegex("something")
t = pypeg2.compose(x)
self.assertEqual(t, "something")
class ComposeKeyword(object):
grammar = pypeg2.K("hallo")
class ComposeKeywordTestCase(ComposeTestCase):
def runTest(self):
x = ComposeKeyword()
t = pypeg2.compose(x)
self.assertEqual(t, "hallo")
class ComposeSymbol(pypeg2.Symbol): pass
class ComposeSymbolTestCase(ComposeTestCase):
def runTest(self):
x = ComposeSymbol("hello")
t = pypeg2.compose(x)
self.assertEqual(t, "hello")
class ComposeAttribute(object):
grammar = pypeg2.name()
class ComposeAttributeTestCase(ComposeTestCase):
def runTest(self):
x = ComposeAttribute()
@ -309,9 +351,11 @@ class ComposeAttributeTestCase(ComposeTestCase):
t = pypeg2.compose(x)
self.assertEqual(t, "hello")
class ComposeFlag(object):
grammar = pypeg2.flag("mark", "MARK")
class ComposeFlagTestCase1(ComposeTestCase):
def runTest(self):
x = ComposeFlag()
@ -319,6 +363,7 @@ class ComposeFlagTestCase1(ComposeTestCase):
t = pypeg2.compose(x)
self.assertEqual(t, "MARK")
class ComposeFlagTestCase2(ComposeTestCase):
def runTest(self):
x = ComposeFlag()
@ -326,32 +371,39 @@ class ComposeFlagTestCase2(ComposeTestCase):
t = pypeg2.compose(x)
self.assertEqual(t, "")
class ComposeTuple(pypeg2.List):
grammar = pypeg2.csl(pypeg2.word)
class ComposeTupleTestCase(ComposeTestCase):
def runTest(self):
x = ComposeTuple(["hello", "world"])
t = pypeg2.compose(x)
self.assertEqual(t, "hello, world")
class ComposeList(str):
grammar = [ re.compile(r"\d+", re.U), pypeg2.word ]
class ComposeListTestCase(ComposeTestCase):
def runTest(self):
x = ComposeList("hello")
t = pypeg2.compose(x)
self.assertEqual(t, "hello")
class ComposeIntTestCase(ComposeTestCase):
def runTest(self):
x = pypeg2.compose(23, int)
self.assertEqual(x, "23")
class C2(str):
grammar = pypeg2.attr("some", "!"), pypeg2.restline
class ComposeInvisibleTestCase(ParserTestCase):
def runTest(self):
r = pypeg2.parse("!all", C2)
@ -360,11 +412,13 @@ class ComposeInvisibleTestCase(ParserTestCase):
t = pypeg2.compose(r, C2)
self.assertEqual(t, "!all")
class ComposeOmitTestCase(ParserTestCase):
def runTest(self):
t = pypeg2.compose('hello', pypeg2.omit(pypeg2.word))
self.assertEqual(t, "")
class CslPython32Compatibility(ParserTestCase):
def runTest(self):
try:
@ -373,5 +427,6 @@ class CslPython32Compatibility(ParserTestCase):
return
self.assertEqual(g, ("hello", "world", -1, (";", pypeg2.blank, "hello", "world")))
if __name__ == '__main__':
unittest.main()

+ 14
- 7
pypeg2/test/test_xmlast.py View File

@ -1,19 +1,15 @@
from __future__ import unicode_literals
try:
str = unicode
except NameError:
pass
import unittest
import re, sys
import pypeg2, pypeg2.xmlast
class Another(object):
grammar = pypeg2.name(), "=", pypeg2.attr("value")
class Something(pypeg2.List):
grammar = pypeg2.name(), pypeg2.some(Another), str
class Thing2etreeTestCase1(unittest.TestCase):
def runTest(self):
s = Something()
@ -40,9 +36,11 @@ class Thing2etreeTestCase1(unittest.TestCase):
else:
self.assertEqual(pypeg2.xmlast.etree.tostring(root), b'<Something name="hello"><Another name="bla" value="blub"/><Another name="foo" value="bar"/>hello, world</Something>')
class SomethingElse(pypeg2.Namespace):
grammar = pypeg2.name(), pypeg2.some(Another)
class Thing2etreeTestCase2(unittest.TestCase):
def runTest(self):
s = SomethingElse()
@ -68,6 +66,7 @@ class Thing2etreeTestCase2(unittest.TestCase):
else:
self.assertEqual(pypeg2.xmlast.etree.tostring(root), b'<SomethingElse name="hello"><Another name="bla" value="blub"/><Another name="foo" value="bar"/></SomethingElse>')
class Thing2XMLTestCase3(unittest.TestCase):
class C1(str):
grammar = pypeg2.ignore("!"), pypeg2.restline
@ -76,9 +75,11 @@ class Thing2XMLTestCase3(unittest.TestCase):
xml = pypeg2.xmlast.thing2xml(r)
self.assertEqual(xml, b"<C1>all</C1>")
class Key(str):
grammar = pypeg2.name(), "=", pypeg2.restline
class XML2ThingTestCase1(unittest.TestCase):
def runTest(self):
xml = b'<Key name="foo">bar</Key>'
@ -86,17 +87,22 @@ class XML2ThingTestCase1(unittest.TestCase):
self.assertEqual(thing.name, pypeg2.Symbol("foo"))
self.assertEqual(thing, "bar")
class Instruction(str): pass
class Parameter(object):
grammar = pypeg2.attr("typing", str), pypeg2.name()
class Parameters(pypeg2.Namespace):
grammar = pypeg2.optional(pypeg2.csl(Parameter))
class Function(pypeg2.List):
grammar = pypeg2.name(), pypeg2.attr("parms", Parameters), "{", pypeg2.maybe_some(Instruction), "}"
class XML2ThingTestCase2(unittest.TestCase):
def runTest(self):
xml = b'<Function name="f"><Parameters><Parameter name="a" typing="int"/></Parameters><Instruction>do_this</Instruction></Function>'
@ -106,5 +112,6 @@ class XML2ThingTestCase2(unittest.TestCase):
self.assertEqual(f.parms["a"].typing, pypeg2.Symbol("int"))
self.assertEqual(f[0], "do_this")
if __name__ == '__main__':
unittest.main()

+ 1
- 1
pypeg2/xmlast.py View File

@ -15,7 +15,7 @@ except NameError:
pass
__version__ = 2.15
__version__ = 2.50
__author__ = "Volker Birk"
__license__ = "This program is under GNU General Public License 2.0."
__url__ = "http://fdik.org/pyPEG"


+ 1
- 2
setup.py View File

@ -1,6 +1,6 @@
from setuptools import setup
_version = '2.15.2'
_version = '2.50.1'
setup(
name='pyPEG2',
@ -23,7 +23,6 @@ setup(
'License :: OSI Approved :: GNU General Public License v2 (GPLv2)',
'Operating System :: OS Independent',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 2',
'Topic :: Software Development :: Compilers',
'Topic :: Software Development :: Interpreters',
'Topic :: Software Development :: Libraries :: Python Modules',


Loading…
Cancel
Save