## Creature Project ## CSC323 ## 4/17/10 ## IterParser.py: Defines a parser that implements an iterator that can ## be used to parse a file containing more than one S-expression class IterParser(): def __init__(self, handle): '''create a new IterParser by giving it a file handler''' with handle as handle: self.parse_many(handle.read()) def parse(self, stuff): """Parse a string and return the resulting s-expression. Only works on correctly formatted strings.""" #print("data is %s" % self.data) val = self.parse_kernel(stuff)[0] return val def parse_many(self, stuff): """Parse a string and return a list of the s expressions we've found. Only works on properly formatted strings.""" #print(stuff) self.expressions = [] while (stuff != ""): value,stuff = self.parse_kernel(stuff) stuff = stuff.lstrip() self.expressions.append(value) #print(self.expressions) return self.expressions def parse_kernel(self, stuff): """Parse a string and return a pair of what we've parsed and the remainder of the string. Only works correctly on correctly formatted strings.""" # Skip over whitespace. Needs improvement stuff = stuff.lstrip() # Special case: Nothing left if (len(stuff) == 0): return ("EMPTY","") # Handle nested/parenthesized stuff elif (stuff[0] == '('): contents = [] # drop the open paren stuff = stuff[1:].lstrip() while (len(stuff) > 0) and (stuff[0] != ')'): (value, rest) = self.parse_kernel(stuff) contents.append(value) stuff = rest.lstrip() # Drop the close paren stuff = stuff[1:] return (contents,stuff) # Unlikely special case elif (stuff[0] == ')'): return ("RIGHT",stuff) # Handle simple symbols/strings elif stuff[0].isalnum(): i = 1 while i < len(stuff) and stuff[i].isalnum(): i = i + 1 return (stuff[0:i], stuff[i:]) # Something's wrong else: raise Exception("Syntax Error!") def __iter__(self): '''return self as an iterator''' return self def __next__(self): if self.expressions == []: raise StopIteration return self.expressions.pop(0) if __name__=='__main__': i = IterParser(open('itertest')) for p in i: print(p)