# Path: pydsl/grammar/definition.py
# class String(Grammar, str):
#     def __init__(self, string):
#         if isinstance(string, list):
#             raise TypeError('Attempted to initialize a String with a list %s' % (string, ) )
#         Grammar.__init__(self, None)
# 
#     @property
#     def first(self):
#         return String(self[0])
# 
#     def enum(self):
#         yield self
# 
#     @property
#     def maxsize(self):
#         return len(self)
# 
#     @property
#     def minsize(self):
#         return len(self)
# 
#     @property
#     def alphabet(self):
#         from pydsl.encoding import ascii_encoding
#         return ascii_encoding
# 
# class Grammar(object):
# 
#     def __init__(self, base_alphabet = None):
#         self.__base_alphabet = base_alphabet
# 
#     def enum(self):
#         """Generates every possible accepted string"""
#         raise NotImplementedError
# 
#     @property
#     def first(self):
#         """Alphabet that matches every possible first element.
#         the returned value is a subset of the base_alphabet"""
#         return self.alphabet
# 
#     @property
#     def minsize(self):# -> int:
#         """Returns the minimum size in alphabet tokens"""
#         return 0
# 
#     @property
#     def maxsize(self):
#         """Returns the max size in alphabet tokens"""
#         return None
# 
#     @property
#     def alphabet(self):
#         if not self.__base_alphabet:
#             raise AttributeError
#         return self.__base_alphabet
# 
# Path: pydsl/grammar/PEG.py
# class ZeroOrMore(Grammar):
#     def __init__(self, element):
#         Grammar.__init__(self)
#         self.element = element
# 
#     def first(self):
#         return Choice([self.element])
# 
# class OneOrMore(Grammar):
#     def __init__(self, element):
#         Grammar.__init__(self)
#         self.element = element
# 
#     def first(self):
#         return Choice([self.element])
# 
# class Not(object):
#     def __init__(self, element):
#         self.element = element
# 
# class Sequence(Grammar, list):
#     def __init__(self, *args, **kwargs):
#         base_alphabet = kwargs.pop('base_alphabet', None)
#         Grammar.__init__(self, base_alphabet)
#         list.__init__(self, *args, **kwargs)
#         for x in self:
#             if not isinstance(x, Grammar):
#                 raise TypeError(x)
# 
#     def __hash__(self):
#         return hash(tuple(self))
# 
#     @classmethod
#     def from_string(cls, string):
#         from .definition import String
#         return cls([String(x) for x in string])
# 
# class Choice(set, Grammar):
#     """Uses a list of grammar definitions with common base alphabets"""
#     def __init__(self, grammarlist, calculate_base_alphabet = True):
#         set.__init__(self, grammarlist)
#         if calculate_base_alphabet:
#             base_alphabet = set()
#             for x in self:
#                 base_alphabet = base_alphabet.union(x.alphabet)
#         else:
#             base_alphabet = None
#         Grammar.__init__(self, base_alphabet)
# 
#     def __str__(self):
#         return str([str(x) for x in self])
# 
#     def __add__(self, other):
#         return Choice([x for x in self] + [x for x in other])
# 
#     def __hash__(self):
#         return hash(tuple(x for x in self))
# 
# 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 unittest
from pydsl.grammar.definition import String, Grammar
from pydsl.grammar.PEG import ZeroOrMore, OneOrMore, Not, Sequence, Choice
from pydsl.check import check

"""Tests PEG grammars"""

__author__ = "Nestor Arocha"
__copyright__ = "Copyright 2008-2014, Nestor Arocha"
__email__ = "nesaro@gmail.com"


class TestPEG(unittest.TestCase):
    def testOneOrMore(self):
        mygrammar = OneOrMore(String("a"))
        self.assertTrue(isinstance(mygrammar, Grammar))
        self.assertEqual(mygrammar.first(), Choice([String("a")]))
        self.assertTrue(check(mygrammar, "a"))
        self.assertTrue(check(mygrammar, "aa"))
        self.assertTrue(check(mygrammar, "aaaa"))
        self.assertFalse(check(mygrammar, ""))
        self.assertFalse(check(mygrammar, "b"))

    def testZeroOrMore(self):
        mygrammar = ZeroOrMore(String("a"))
        self.assertTrue(isinstance(mygrammar, Grammar))
        self.assertEqual(mygrammar.first(), Choice([String("a")]))
        self.assertTrue(check(mygrammar, "a"))
        self.assertTrue(check(mygrammar, "aa"))
        self.assertTrue(check(mygrammar, "aaaa"))
        self.assertTrue(check(mygrammar, ""))
        self.assertFalse(check(mygrammar, "b"))

    def testChoice(self):

# Path: pydsl/grammar/definition.py
# class String(Grammar, str):
#     def __init__(self, string):
#         if isinstance(string, list):
#             raise TypeError('Attempted to initialize a String with a list %s' % (string, ) )
#         Grammar.__init__(self, None)
# 
#     @property
#     def first(self):
#         return String(self[0])
# 
#     def enum(self):
#         yield self
# 
#     @property
#     def maxsize(self):
#         return len(self)
# 
#     @property
#     def minsize(self):
#         return len(self)
# 
#     @property
#     def alphabet(self):
#         from pydsl.encoding import ascii_encoding
#         return ascii_encoding
# 
# class Grammar(object):
# 
#     def __init__(self, base_alphabet = None):
#         self.__base_alphabet = base_alphabet
# 
#     def enum(self):
#         """Generates every possible accepted string"""
#         raise NotImplementedError
# 
#     @property
#     def first(self):
#         """Alphabet that matches every possible first element.
#         the returned value is a subset of the base_alphabet"""
#         return self.alphabet
# 
#     @property
#     def minsize(self):# -> int:
#         """Returns the minimum size in alphabet tokens"""
#         return 0
# 
#     @property
#     def maxsize(self):
#         """Returns the max size in alphabet tokens"""
#         return None
# 
#     @property
#     def alphabet(self):
#         if not self.__base_alphabet:
#             raise AttributeError
#         return self.__base_alphabet
# 
# Path: pydsl/grammar/PEG.py
# class ZeroOrMore(Grammar):
#     def __init__(self, element):
#         Grammar.__init__(self)
#         self.element = element
# 
#     def first(self):
#         return Choice([self.element])
# 
# class OneOrMore(Grammar):
#     def __init__(self, element):
#         Grammar.__init__(self)
#         self.element = element
# 
#     def first(self):
#         return Choice([self.element])
# 
# class Not(object):
#     def __init__(self, element):
#         self.element = element
# 
# class Sequence(Grammar, list):
#     def __init__(self, *args, **kwargs):
#         base_alphabet = kwargs.pop('base_alphabet', None)
#         Grammar.__init__(self, base_alphabet)
#         list.__init__(self, *args, **kwargs)
#         for x in self:
#             if not isinstance(x, Grammar):
#                 raise TypeError(x)
# 
#     def __hash__(self):
#         return hash(tuple(self))
# 
#     @classmethod
#     def from_string(cls, string):
#         from .definition import String
#         return cls([String(x) for x in string])
# 
# class Choice(set, Grammar):
#     """Uses a list of grammar definitions with common base alphabets"""
#     def __init__(self, grammarlist, calculate_base_alphabet = True):
#         set.__init__(self, grammarlist)
#         if calculate_base_alphabet:
#             base_alphabet = set()
#             for x in self:
#                 base_alphabet = base_alphabet.union(x.alphabet)
#         else:
#             base_alphabet = None
#         Grammar.__init__(self, base_alphabet)
# 
#     def __str__(self):
#         return str([str(x) for x in self])
# 
#     def __add__(self, other):
#         return Choice([x for x in self] + [x for x in other])
# 
#     def __hash__(self):
#         return hash(tuple(x for x in self))
# 
# 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: tests/unit/test_PEG.py
import unittest
from pydsl.grammar.definition import String, Grammar
from pydsl.grammar.PEG import ZeroOrMore, OneOrMore, Not, Sequence, Choice
from pydsl.check import check


"""Tests PEG grammars"""

__author__ = "Nestor Arocha"
__copyright__ = "Copyright 2008-2014, Nestor Arocha"
__email__ = "nesaro@gmail.com"


class TestPEG(unittest.TestCase):
    def testOneOrMore(self):
        mygrammar = OneOrMore(String("a"))
        self.assertTrue(isinstance(mygrammar, Grammar))
        self.assertEqual(mygrammar.first(), Choice([String("a")]))
        self.assertTrue(check(mygrammar, "a"))
        self.assertTrue(check(mygrammar, "aa"))
        self.assertTrue(check(mygrammar, "aaaa"))
        self.assertFalse(check(mygrammar, ""))
        self.assertFalse(check(mygrammar, "b"))

    def testZeroOrMore(self):
        mygrammar = ZeroOrMore(String("a"))
        self.assertTrue(isinstance(mygrammar, Grammar))
        self.assertEqual(mygrammar.first(), Choice([String("a")]))
        self.assertTrue(check(mygrammar, "a"))
        self.assertTrue(check(mygrammar, "aa"))
        self.assertTrue(check(mygrammar, "aaaa"))
        self.assertTrue(check(mygrammar, ""))
        self.assertFalse(check(mygrammar, "b"))

    def testChoice(self):

        mygrammar = Choice((String("a"), String("b")))