No older revisions available
No older revisions available
#VendingMachineParser.py
import shlex,sys
from cStringIO import StringIO
class VendingCmd:
def __init__(self,cmd,**kwargs):
self.cmd = cmd
self.__dict__.update(kwargs)
def __repr__(self):
s = '%s(' % self.cmd
for item in self.__dict__.items():
if item[0] != 'cmd':
s += ' %s=%s' % item
return s + ' )'
class Parser:
def __init__(self,aStream=sys.stderr):
self.outstream=aStream
def next_token(self):
tok = self.lexer.get_token()
if not tok:
self.err('Unexpected end of file')
return tok
def next_number(self,func=int):
tok = self.next_token()
if tok:
try: tok = func(tok)
except ValueError:
return self.err('Expected a number, not '+tok)
return tok
def next_money(self):
num=self.next_number()
if num not in (10,50,100,500,1000):
return self.err('Unexpected money type')
return num
def next_button(self):
tok=self.lexer.get_token()
if tok not in ('black','white','sugar_black','sugar_white'):
return self.err('Unexpected button type')
return tok
def err(self,msg):
self.outstream.write(self.lexer.error_leader()+msg+'\n')
def parse_put(self):
money = self.next_money()
if money: return VendingCmd('put',arg=money)
def parse_push(self):
button=self.next_button()
if button: return VendingCmd('push',arg=button)
def parse(self,aString=None,aStream=None,aName=None):
if aString:
aStream=StringIO(aString)
lexer=shlex.shlex(aStream,aName)
lexer.source = 'include'
lexer.wordchars += '.,-'
self.lexer=lexer
cmds = []
while 1:
tok = lexer.get_token()
if not tok:
break
try:
parser = getattr(self,'parse_%s'%tok)
except:
self.err('Unknown command: '+tok)
continue
cmd=parser()
if cmd is None:
continue
cmds.append(cmd)
return cmds
if __name__=='__main__':
err=StringIO()
p=Parser(err)
cmds=p.parse("put 30 put 50 put 1000")
print cmds
print `err.getvalue()`