Add logging and improve runtime error print

pull/3/head
J Morgan 1 year ago
parent 95b48ca1e3
commit 2d0642fac5
  1. 47
      pypeg2/__init__.py

@ -16,6 +16,9 @@ try:
except NameError:
pass
import logging
logger = logging.getLogger("pyPEG2")
__version__ = 2.15
__author__ = "Volker Birk"
@ -167,6 +170,7 @@ class RegEx(object):
"""
def __init__(self, value, **kwargs):
logger.debug(f"New Regex({value})")
self.regex = re.compile(value, re.U)
self.search = self.regex.search
self.match = self.regex.match
@ -199,6 +203,7 @@ class Literal(object):
_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):
pass
else:
@ -239,6 +244,7 @@ class Plain(object):
"""Construct a plain object with an optional name and optional other
attributes
"""
logger.debug(f"New Plain({name})")
if name is not None:
self.name = Symbol(name)
for k, v in kwargs:
@ -259,6 +265,7 @@ class List(list):
"""Construct a List, and construct its attributes from keyword
arguments.
"""
logger.debug(f"New List({args}, {kwargs})")
_args = []
if len(args) == 1:
if isinstance(args[0], str):
@ -333,6 +340,7 @@ class Namespace(_UserDict):
Arguments are being put into the Namespace, keyword arguments give the
attributes of the Namespace.
"""
logger.debug(f"New Namespace({args}, {kwargs})")
if args:
self.data = OrderedDict(args)
else:
@ -387,6 +395,7 @@ class Enum(Namespace):
def __init__(self, *things, **kwargs):
"""Construct an Enum using a tuple of things."""
logger.debug(f"New Enum({things})")
self.data = OrderedDict()
for thing in things:
if type(thing) == str:
@ -435,6 +444,7 @@ class Symbol(str):
TypeError if namespace is given and not a Namespace
"""
logger.debug(f"New Symbol({name})")
if Symbol.check_keywords and name in Keyword.table:
raise ValueError(repr(name)
+ " is a Keyword, but is used as a Symbol")
@ -657,6 +667,7 @@ def parse(text, thing, filename=None, whitespace=whitespace, comment=None,
if grammar contains an illegal cardinality value
"""
logger.debug(f"parse({repr(text)}, {thing})")
parser = Parser()
parser.whitespace = whitespace
parser.comment = comment
@ -693,6 +704,7 @@ def compose(thing, grammar=None, indent=" ", autoblank=True):
if grammar contains an illegal cardinality value
"""
logger.debug(f"compose({thing}, {grammar})")
parser = Parser()
parser.indent = indent
parser.autoblank = autoblank
@ -729,7 +741,7 @@ class Parser(object):
attribute instead of dumping them
"""
def __init__(self):
def __init__(self, name=None):
"""Initialize instance variables to their defaults."""
self.whitespace = whitespace
self.comment = None
@ -744,6 +756,12 @@ class Parser(object):
self._got_endl = True
self._contiguous = False
self._got_regex = False
self._name = hex(id(self)) if name is None else name
logger.debug(f"New Parser(name={name})")
@property
def name(self):
return self._name
def clear_memory(self, thing=None):
"""Clear cache memory for packrat parsing.
@ -784,6 +802,7 @@ class Parser(object):
if grammar contains an illegal cardinality value
"""
logger.debug(f"Parser({self.name}).parse({repr(text)}, {thing})")
self.text = text
if filename:
self.filename = filename
@ -807,6 +826,7 @@ class Parser(object):
def _skip(self, text, pos=None):
# Skip whitespace and comments from input text
logger.debug(f"Parser({self.name})._skip({repr(text)}, {pos})")
t2 = None
t = text
result = []
@ -854,15 +874,17 @@ class Parser(object):
def _parse(self, text, thing, pos=[1, 0]):
# 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
if not pos:
return
if text == t:
return
d_text = text[:len(text) - len(t)]
pos[0] += d_text.count("\n")
pos[1] += len(d_text)
old_pos = pos
if pos and text != t:
d_text = text[:len(text) - len(t)]
pos[0] += d_text.count("\n")
pos[1] += len(d_text)
logger.debug(f"Parser({self.name})._parse.update_pos(" + f"{pos})" if old_pos == pos else f"{old_pos}->{pos})")
try:
return self._memory[id(thing)][text]
@ -913,7 +935,7 @@ class Parser(object):
result = t, r
update_pos(text, t, pos)
else:
result = text, syntax_error("expecting " + repr(thing))
result = text, syntax_error("expecting " + repr(thing) + f" in '{text}'")
elif isinstance(thing, (RegEx, _RegEx)):
m = thing.match(text)
@ -924,7 +946,7 @@ class Parser(object):
update_pos(text, t, pos)
else:
result = text, syntax_error("expecting match on "
+ thing.pattern)
+ thing.pattern + f" in '{text}'")
elif isinstance(thing, (str, Literal)):
if text.startswith(str(thing)):
@ -933,7 +955,7 @@ class Parser(object):
result = t, r
update_pos(text, t, pos)
else:
result = text, syntax_error("expecting " + repr(thing))
result = text, syntax_error("expecting " + repr(thing) + f" in '{text}'")
elif _issubclass(thing, Symbol):
m = thing.regex.match(text)
@ -961,7 +983,7 @@ class Parser(object):
result = t, r
update_pos(text, t, pos)
else:
result = text, syntax_error("expecting " + thing.__name__)
result = text, syntax_error("expecting " + thing.__name__ + f" in '{text}'")
# non-terminal constructs
@ -1273,6 +1295,7 @@ class Parser(object):
GrammarValueError
if grammar contains an illegal cardinality value
"""
logger.debug(f"Parser({self.name}).compose({thing}, {grammar})")
if __debug__:
# make sure that we're not having this typing error
compose = None

Loading…
Cancel
Save