# Path: pyrser/meta.py
# def enum(*sequential, **named):
# def checktypes(func):
#     def check_type(sig, arg_name, arg_type, arg_value):
#     def wrapper(*args, **kwargs):
# def set_one(chainmap, thing_name, callobject):
# def _get_base_class(cls):
# def add_method(cls):
#     def wrapper(f):
# def hook(cls, hookname=None, erase=False):
#     def wrapper(f):
# def rule(cls, rulename=None, erase=False):
#     def wrapper(f):
# def directive(directname=None):
#     def wrapper(f):
# def decorator(directname=None):
#     def wrapper(f):
# 
# Path: pyrser/error.py
# class LocationInfo:
# class Notification:
# class Diagnostic(Exception):
#     def __init__(self, filepath: str, line: int, col: int, size: int=1):
#     def from_stream(stream: 'Stream', is_error=False) -> 'LocationInfo':
#     def from_maxstream(stream: 'Stream', is_error=False) -> 'LocationInfo':
#     def from_here(pos=1):
#     def get_content(self) -> str:
#     def __init__(self, severity: Severity, msg: str,
#                  location: LocationInfo=None, details: str=None):
#     def get_content(self, with_locinfos=False, with_details=False) -> str:
#     def __init__(self):
#     def __bool__(self):
#     def __str__(self) -> str:
#     def notify(self, severity: Severity, msg: str,
#                location: LocationInfo=None, details: str=None) -> int:
#     def add(self, n: Notification) -> int:
#     def get_content(self, with_locinfos=True, with_details=False) -> str:
#     def get_infos(self) -> {Severity, int}:
#     def have_errors(self) -> bool:
# 
# Path: pyrser/parsing/node.py
# class Node(dict):
#     """Base class for node manipulation."""
# 
#     def __bool__(self):
#         return True
# 
#     def __repr__(self):
#         #TODO: use to_yml
#         items = []
#         if len(self) > 0:
#             items.append(repr(self.items()))
#         for k, v in vars(self).items():
#             items.append("{} = {}".format(k, repr(v)))
#         return "{}({})".format(self.__class__.__name__, ', '.join(items))
# 
#     def check(self, ndict: dict, info="") -> bool:
#         """
#         Debug method, help detect cycle and/or
#         other incoherence in a tree of Node
#         """
#         def iscycle(thing, ndict: dict, info: str) -> bool:
#             # check if not already here
#             idthing = id(thing)
#             ndict[info] = idthing
#             if idthing not in ndict:
#                 # add myself
#                 ndict[idthing] = "%s:%s no cycle" % (type(thing), info)
#                 return False
#             else:
#                 ndict[idthing] += "\n%s:%s cycle" % (type(thing), info)
#                 return True
# 
#         def recurs(thing, ndict: dict, info: str) -> bool:
#             if not iscycle(thing, ndict, info):
#                 res = False
#                 if isinstance(thing, list):
#                     idx = 0
#                     for i in thing:
#                         res |= recurs(i, ndict, "%s[%d]" % (info, idx))
#                         idx += 1
#                 elif isinstance(thing, Node):
#                     res |= thing.check(ndict, info)
#                 elif isinstance(thing, dict):
#                     for k, v in thing.items():
#                         res |= recurs(v, ndict, "%s[%s]" % (info, k))
#                 return res
#             return True
#         # add ME FIRST
#         if len(ndict) == 0:
#             ndict['self'] = id(self)
#             info = 'self'
#         if not iscycle(self, ndict, info):
#             res = False
#             if len(self) > 0:
#                 if hasattr(self, 'keys'):
#                     keys = list(self.keys())
#                     for k in keys:
#                         ndict["[" + repr(k) + "]"] = id(self[k])
#                         res |= recurs(self[k], ndict, "%s[%s]" % (info, k))
#             keys = list(vars(self).keys())
#             for k in keys:
#                 ndict["." + k] = id(getattr(self, k))
#                 res |= recurs(getattr(self, k), ndict, "%s.%s" % (info, k))
#             return res
#         return True
# 
#     def clean(self):
#         if len(self) > 0:
#             keys = list(self.keys())
#             for k in keys:
#                 del self[k]
#         keys = list(vars(self).keys())
#         for k in keys:
#             delattr(self, k)
# 
#     def set(self, othernode):
#         """allow to completly mutate the node into any subclasses of Node"""
#         self.__class__ = othernode.__class__
#         self.clean()
#         if len(othernode) > 0:
#             for k, v in othernode.items():
#                 self[k] = v
#         for k, v in vars(othernode).items():
#             setattr(self, k, v)


import collections
import os
from pyrser import meta
from pyrser import error
from pyrser.parsing.stream import Stream
from pyrser.parsing.stream import Tag
from pyrser.parsing.node import Node
            cls._hooks.update(namespace['_hooks'])
        # store in global registry
        _MetaBasicParser[name] = cls
        return cls


class BasicParser(metaclass=MetaBasicParser):
    """Empty basic parser, contains no rule nor hook.

    Unless you know what you are doing, use Parser instead of this class.

    """

    _rules = collections.ChainMap()
    _hooks = collections.ChainMap()

    def __init__(
            self,
            content: str='',
            stream_name: str=None,
            raise_diagnostic=True
    ):
        self._ignores = [BasicParser.ignore_blanks]
        self._streams = [Stream(content, stream_name)]
        self.rule_nodes = None
        self.push_rule_nodes()
        self._lastIgnoreIndex = 0
        self._lastIgnore = False
        self._lastRule = ""
        self.raise_diagnostic = raise_diagnostic

# Path: pyrser/meta.py
# def enum(*sequential, **named):
# def checktypes(func):
#     def check_type(sig, arg_name, arg_type, arg_value):
#     def wrapper(*args, **kwargs):
# def set_one(chainmap, thing_name, callobject):
# def _get_base_class(cls):
# def add_method(cls):
#     def wrapper(f):
# def hook(cls, hookname=None, erase=False):
#     def wrapper(f):
# def rule(cls, rulename=None, erase=False):
#     def wrapper(f):
# def directive(directname=None):
#     def wrapper(f):
# def decorator(directname=None):
#     def wrapper(f):
# 
# Path: pyrser/error.py
# class LocationInfo:
# class Notification:
# class Diagnostic(Exception):
#     def __init__(self, filepath: str, line: int, col: int, size: int=1):
#     def from_stream(stream: 'Stream', is_error=False) -> 'LocationInfo':
#     def from_maxstream(stream: 'Stream', is_error=False) -> 'LocationInfo':
#     def from_here(pos=1):
#     def get_content(self) -> str:
#     def __init__(self, severity: Severity, msg: str,
#                  location: LocationInfo=None, details: str=None):
#     def get_content(self, with_locinfos=False, with_details=False) -> str:
#     def __init__(self):
#     def __bool__(self):
#     def __str__(self) -> str:
#     def notify(self, severity: Severity, msg: str,
#                location: LocationInfo=None, details: str=None) -> int:
#     def add(self, n: Notification) -> int:
#     def get_content(self, with_locinfos=True, with_details=False) -> str:
#     def get_infos(self) -> {Severity, int}:
#     def have_errors(self) -> bool:
# 
# Path: pyrser/parsing/node.py
# class Node(dict):
#     """Base class for node manipulation."""
# 
#     def __bool__(self):
#         return True
# 
#     def __repr__(self):
#         #TODO: use to_yml
#         items = []
#         if len(self) > 0:
#             items.append(repr(self.items()))
#         for k, v in vars(self).items():
#             items.append("{} = {}".format(k, repr(v)))
#         return "{}({})".format(self.__class__.__name__, ', '.join(items))
# 
#     def check(self, ndict: dict, info="") -> bool:
#         """
#         Debug method, help detect cycle and/or
#         other incoherence in a tree of Node
#         """
#         def iscycle(thing, ndict: dict, info: str) -> bool:
#             # check if not already here
#             idthing = id(thing)
#             ndict[info] = idthing
#             if idthing not in ndict:
#                 # add myself
#                 ndict[idthing] = "%s:%s no cycle" % (type(thing), info)
#                 return False
#             else:
#                 ndict[idthing] += "\n%s:%s cycle" % (type(thing), info)
#                 return True
# 
#         def recurs(thing, ndict: dict, info: str) -> bool:
#             if not iscycle(thing, ndict, info):
#                 res = False
#                 if isinstance(thing, list):
#                     idx = 0
#                     for i in thing:
#                         res |= recurs(i, ndict, "%s[%d]" % (info, idx))
#                         idx += 1
#                 elif isinstance(thing, Node):
#                     res |= thing.check(ndict, info)
#                 elif isinstance(thing, dict):
#                     for k, v in thing.items():
#                         res |= recurs(v, ndict, "%s[%s]" % (info, k))
#                 return res
#             return True
#         # add ME FIRST
#         if len(ndict) == 0:
#             ndict['self'] = id(self)
#             info = 'self'
#         if not iscycle(self, ndict, info):
#             res = False
#             if len(self) > 0:
#                 if hasattr(self, 'keys'):
#                     keys = list(self.keys())
#                     for k in keys:
#                         ndict["[" + repr(k) + "]"] = id(self[k])
#                         res |= recurs(self[k], ndict, "%s[%s]" % (info, k))
#             keys = list(vars(self).keys())
#             for k in keys:
#                 ndict["." + k] = id(getattr(self, k))
#                 res |= recurs(getattr(self, k), ndict, "%s.%s" % (info, k))
#             return res
#         return True
# 
#     def clean(self):
#         if len(self) > 0:
#             keys = list(self.keys())
#             for k in keys:
#                 del self[k]
#         keys = list(vars(self).keys())
#         for k in keys:
#             delattr(self, k)
# 
#     def set(self, othernode):
#         """allow to completly mutate the node into any subclasses of Node"""
#         self.__class__ = othernode.__class__
#         self.clean()
#         if len(othernode) > 0:
#             for k, v in othernode.items():
#                 self[k] = v
#         for k, v in vars(othernode).items():
#             setattr(self, k, v)


# Path: pyrser/parsing/base.py
import collections
import os
from pyrser import meta
from pyrser import error
from pyrser.parsing.stream import Stream
from pyrser.parsing.stream import Tag
from pyrser.parsing.node import Node

            cls._hooks.update(namespace['_hooks'])
        # store in global registry
        _MetaBasicParser[name] = cls
        return cls


class BasicParser(metaclass=MetaBasicParser):
    """Empty basic parser, contains no rule nor hook.

    Unless you know what you are doing, use Parser instead of this class.

    """

    _rules = collections.ChainMap()
    _hooks = collections.ChainMap()

    def __init__(
            self,
            content: str='',
            stream_name: str=None,
            raise_diagnostic=True
    ):
        self._ignores = [BasicParser.ignore_blanks]
        self._streams = [Stream(content, stream_name)]
        self.rule_nodes = None
        self.push_rule_nodes()
        self._lastIgnoreIndex = 0
        self._lastIgnore = False
        self._lastRule = ""
        self.raise_diagnostic = raise_diagnostic

        self.diagnostic = error.Diagnostic()