Skip to content

Instantly share code, notes, and snippets.

@adnelson
Last active August 29, 2015 20:09
Show Gist options
  • Save adnelson/022048aac459fef221c2 to your computer and use it in GitHub Desktop.
Save adnelson/022048aac459fef221c2 to your computer and use it in GitHub Desktop.
class ParseError(Exception):
pass
# Each parser function should take a list of characters and an index
# into that list, and return something that it parsed and a new index.
def parse_optionally(parser):
"""
Parses or returns None
"""
def _parse(chars, index):
try:
return parser(chars, index)
except ParseError:
return None, index
return _parse
def parse_0_or_more(parser):
"""
Takes a parser and returns a new parser which
parses 0 or more of the object that the parser
parses.
"""
def _parse(chars, index):
results = []
while True:
try:
item, new_index = parser(index)
results.append(item)
except ParseError:
return results
index = new_index
return _parse
def parse_at_least_one(parser):
"""
Takes a parser and returns a new parser which
parses one or more of the object that the parser
parses.
"""
def _parse(chars, index):
first, index2 = parser(chars, index)
rest, index3 = parse_0_or_more(parser)(chars, index2)
return [first] + rest, index3
return _parse
def parse_one_of(char_set):
"""
Given a set of characters, makes a parser which parses one
of the characters in the set
"""
def _parse(chars, index):
if chars[index] not in char_set:
raise ParseError('Expected one of ' + char_set)
return chars[index], index + 1
parse_char = lambda char: parse_one_of(set([char]))
parse_digit = parse_one_of(set('0123456789'))
parse_lower_letter = parse_one_of(set(string.ascii_lowercase))
parse_upper_letter = parse_one_of(set(string.ascii_uppercase))
def parse_number(chars, index):
"""
Parses an integer.
"""
neg, index2 = parse_optionally(parse_char('-'))(chars, index)
digits, index3 = parse_at_least_one(parse_digit)(chars, index2)
num = int(digits)
if neg is not None:
num = -num
return num, index3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment