# Path: pydsl/parser/parser.py
# class TopDownParser(Parser):
#     """Top down parser like descent parser"""
#     def _reduce_terminal(self, symbol, data, showerrors = False):
#         from pydsl.check import check
#         from pydsl.tree import ParseTree
#         result = check(symbol.gd, [data])
#         if result:
#             return [ParseTree(0,1, symbol , data)]
#         if showerrors and not result:
#             return [ParseTree(0,1, symbol , data, valid = False)]
#         return []
# 
# Path: pydsl/tree.py
# class ParseTree(object):
# 
#     """Stores the position of the original tree"""
# 
#     def __init__(self, left, right, symbol, content, childlist=None, valid=True):
#         self.symbol = symbol
#         if not isinstance(left, int) and left is not None:
#             raise TypeError
#         if not isinstance(right, int) and right is not None:
#             raise TypeError
#         self.childlist = childlist or []
#         self.left = left
#         self.right = right
#         self.content = content
#         self.valid = valid
# 
#     def __eq__(self, other):
#         try:
#             return self.left == other.left and self.right == other.right and self.valid == other.valid and self.content == other.content 
#         except AttributeError:
#             return False
# 
#     def __bool__(self):
#         """checks if it is a null result"""
#         return self.valid
# 
#     def __nonzero__(self):
#         return self.__bool__()
# 
#     def shift(self, amount):
#         """ shifts position """
#         if self.left is not None:
#             self.left += amount
#         if self.left is not None:
#             self.right += amount
# 
#     def __len__(self):
#         if self.right is None and self.left is None:
#             return 0
#         return self.right - self.left
# 
#     def append(self, dpr):
#         """appends dpr to childlist"""
#         self.childlist.append(dpr)
# 
# class PositionResultList(object):
#     """Contains a list of results"""
#     def __init__(self):
#         self.possible_items = []
# 
#     @property
#     def current_right(self):
#         if not self.possible_items:
#             return set([0])
#         return set(x['right'] for x in self.possible_items)
# 
#     def append(self, left, right, content, gd = None, check_position=True):
#         if left > right:
#             raise ValueError('Attempted to add negative length alement')
#         if check_position and left and left not in self.current_right:
#             raise ValueError("Unable to add element")
#         result = {'left':left, 'right':right, 'content':content}
#         if gd:
#             result['gd'] = gd
#         self.possible_items.append(result)
# 
#     def valid_sequences(self):
#         """Returns list"""
#         valid_sets = [[x] for x in self.possible_items if x['left'] == 0]
#         change = True
#         niter = 200
#         while change and niter > 0:
#             change = False
#             niter -=1
#             for possible in sorted(self.possible_items, key=lambda x:x['left']):
#                 for current_valid in valid_sets[:]:
#                     if possible['left'] == current_valid[-1]['right']:
#                         if current_valid + [possible] not in valid_sets:
#                             if current_valid[-1]['left'] != current_valid[-1]['right'] or possible['left'] != possible['right']: #avoids Null insertion twice
#                                 valid_sets.append(current_valid + [possible])
#                                 change = True
#         if not niter:
#             raise Exception('too many iterations')
#         return valid_sets
# 
#     def right_limit_list(self):
#         if not self.possible_items:
#             return [0]
#         return list(set([x[-1]['right'] for x in self.valid_sequences()]))
# 
# Path: pydsl/check.py
# def check(definition, data, *args, **kwargs):
#     """Checks if the input follows the definition"""
#     checker = checker_factory(definition)
#     return checker(data, *args, **kwargs)


import logging
from .parser import TopDownParser
from pydsl.tree import ParseTree, PositionResultList
from pydsl.check import check
        from pydsl.grammar.symbol import TerminalSymbol, NullSymbol, NonTerminalSymbol
                for x in alternativetree.valid_sequences():
                    validstack.append(x)
            result = []

            LOG.debug("iteration result collection finished:" + str(validstack))
            for alternative in self._productionset.getProductionsBySide(onlysymbol):
                nullcount = alternative.rightside.count(NullSymbol())
                for results in validstack:
                    nnullresults = 0
                    left = results[0]['left']
                    right = results[-1]['right']
                    nnullresults = len([x for x in results if x['content'].symbol == NullSymbol()])
                    if len(results) - nnullresults != len(alternative.rightside) - nullcount:
                        LOG.debug("Discarded: incorrect number of non null symbols")
                        continue
                    if right > len(data):
                        LOG.debug("Discarded: length mismatch")
                        continue
                    for x in range(min(len(alternative.rightside), len(results))):
                        if results[x]['content'] != alternative.rightside[x]:
                            LOG.debug("Discarded: rule doesn't match partial result")
                            continue
                    childlist = [x['content'] for x in results]
                    allvalid = all([x.valid for x in childlist])
                    if allvalid:
                        newresult = ParseTree(0, right - left, onlysymbol,
                                data[left:right], childlist = childlist)
                        newresult.valid = True
                        result.append(newresult)
            if showerrors and not result:

# Path: pydsl/parser/parser.py
# class TopDownParser(Parser):
#     """Top down parser like descent parser"""
#     def _reduce_terminal(self, symbol, data, showerrors = False):
#         from pydsl.check import check
#         from pydsl.tree import ParseTree
#         result = check(symbol.gd, [data])
#         if result:
#             return [ParseTree(0,1, symbol , data)]
#         if showerrors and not result:
#             return [ParseTree(0,1, symbol , data, valid = False)]
#         return []
# 
# Path: pydsl/tree.py
# class ParseTree(object):
# 
#     """Stores the position of the original tree"""
# 
#     def __init__(self, left, right, symbol, content, childlist=None, valid=True):
#         self.symbol = symbol
#         if not isinstance(left, int) and left is not None:
#             raise TypeError
#         if not isinstance(right, int) and right is not None:
#             raise TypeError
#         self.childlist = childlist or []
#         self.left = left
#         self.right = right
#         self.content = content
#         self.valid = valid
# 
#     def __eq__(self, other):
#         try:
#             return self.left == other.left and self.right == other.right and self.valid == other.valid and self.content == other.content 
#         except AttributeError:
#             return False
# 
#     def __bool__(self):
#         """checks if it is a null result"""
#         return self.valid
# 
#     def __nonzero__(self):
#         return self.__bool__()
# 
#     def shift(self, amount):
#         """ shifts position """
#         if self.left is not None:
#             self.left += amount
#         if self.left is not None:
#             self.right += amount
# 
#     def __len__(self):
#         if self.right is None and self.left is None:
#             return 0
#         return self.right - self.left
# 
#     def append(self, dpr):
#         """appends dpr to childlist"""
#         self.childlist.append(dpr)
# 
# class PositionResultList(object):
#     """Contains a list of results"""
#     def __init__(self):
#         self.possible_items = []
# 
#     @property
#     def current_right(self):
#         if not self.possible_items:
#             return set([0])
#         return set(x['right'] for x in self.possible_items)
# 
#     def append(self, left, right, content, gd = None, check_position=True):
#         if left > right:
#             raise ValueError('Attempted to add negative length alement')
#         if check_position and left and left not in self.current_right:
#             raise ValueError("Unable to add element")
#         result = {'left':left, 'right':right, 'content':content}
#         if gd:
#             result['gd'] = gd
#         self.possible_items.append(result)
# 
#     def valid_sequences(self):
#         """Returns list"""
#         valid_sets = [[x] for x in self.possible_items if x['left'] == 0]
#         change = True
#         niter = 200
#         while change and niter > 0:
#             change = False
#             niter -=1
#             for possible in sorted(self.possible_items, key=lambda x:x['left']):
#                 for current_valid in valid_sets[:]:
#                     if possible['left'] == current_valid[-1]['right']:
#                         if current_valid + [possible] not in valid_sets:
#                             if current_valid[-1]['left'] != current_valid[-1]['right'] or possible['left'] != possible['right']: #avoids Null insertion twice
#                                 valid_sets.append(current_valid + [possible])
#                                 change = True
#         if not niter:
#             raise Exception('too many iterations')
#         return valid_sets
# 
#     def right_limit_list(self):
#         if not self.possible_items:
#             return [0]
#         return list(set([x[-1]['right'] for x in self.valid_sequences()]))
# 
# Path: pydsl/check.py
# def check(definition, data, *args, **kwargs):
#     """Checks if the input follows the definition"""
#     checker = checker_factory(definition)
#     return checker(data, *args, **kwargs)


# Path: pydsl/parser/backtracing.py
import logging
from .parser import TopDownParser
from pydsl.tree import ParseTree, PositionResultList
from pydsl.check import check
        from pydsl.grammar.symbol import TerminalSymbol, NullSymbol, NonTerminalSymbol

                for x in alternativetree.valid_sequences():
                    validstack.append(x)
            result = []

            LOG.debug("iteration result collection finished:" + str(validstack))
            for alternative in self._productionset.getProductionsBySide(onlysymbol):
                nullcount = alternative.rightside.count(NullSymbol())
                for results in validstack:
                    nnullresults = 0
                    left = results[0]['left']
                    right = results[-1]['right']
                    nnullresults = len([x for x in results if x['content'].symbol == NullSymbol()])
                    if len(results) - nnullresults != len(alternative.rightside) - nullcount:
                        LOG.debug("Discarded: incorrect number of non null symbols")
                        continue
                    if right > len(data):
                        LOG.debug("Discarded: length mismatch")
                        continue
                    for x in range(min(len(alternative.rightside), len(results))):
                        if results[x]['content'] != alternative.rightside[x]:
                            LOG.debug("Discarded: rule doesn't match partial result")
                            continue
                    childlist = [x['content'] for x in results]
                    allvalid = all([x.valid for x in childlist])
                    if allvalid:
                        newresult = ParseTree(0, right - left, onlysymbol,
                                data[left:right], childlist = childlist)
                        newresult.valid = True
                        result.append(newresult)
            if showerrors and not result:

                erroresult = ParseTree(0,len(data), onlysymbol , data, valid = False)