def _sequence(*parsers): '''same as 'sequence', but less efficient (due to having to ALWAYS go over all 'parsers'. ''' def flatten(tree): try: return tree if len(tree) != 2 else flatten(tree[0]) + [tree[1]] except TypeError: return tree return syntax_tree(flatten)(reduce(and_, parsers, mzero))
def string(s): '''Parses a string 's'. Returns it. ''' return syntax_tree(mkString)(sequence(*map(char, s)))
''' return choice(*map(char, chars)) def noneOf(chars): '''Succeeds if the current character is NOT in 'chars'. Returns the parsed character. ''' return satisfy(lambda ch: ch not in chars, errorMsg=FOUND_MESSAGE, noneof=chars) toString = syntax_tree(mkString) isUpper = lambda ch: ch >= 'A' and ch <= 'Z' isLower = lambda ch: ch >= 'a' and ch <= 'z' isDigit = lambda ch: ch >= '0' and ch <= '9' DIGITS = ''.join(map(str, xrange(10))) anyChar = satisfy(lambda _: True) upper = satisfy(isUpper, errorMsg=UNEXPECTED_MESSAGE, expected=ascii_uppercase) lower = satisfy(isLower, errorMsg=UNEXPECTED_MESSAGE, expected=ascii_lowercase) letter = lower | upper letters = toString(many1(letter)) digit = satisfy(isDigit, errorMsg=UNEXPECTED_MESSAGE, expected=DIGITS)
def noneOf(chars): '''Succeeds if the current character is NOT in 'chars'. Returns the parsed character. ''' return satisfy(lambda ch: ch not in chars, errorMsg=FOUND_MESSAGE, noneof=chars) toString = syntax_tree(mkString) isUpper = lambda ch: ch >= 'A' and ch <= 'Z' isLower = lambda ch: ch >= 'a' and ch <= 'z' isDigit = lambda ch: ch >= '0' and ch <= '9' DIGITS = ''.join(map(str, xrange(10))) anyChar = satisfy(lambda _: True) upper = satisfy(isUpper, errorMsg=UNEXPECTED_MESSAGE, expected=ascii_uppercase) lower = satisfy(isLower, errorMsg=UNEXPECTED_MESSAGE, expected=ascii_lowercase)