Last active
August 29, 2015 20:09
-
-
Save adnelson/022048aac459fef221c2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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