No older revisions available
No older revisions available
#VendingMachineParser.py
import shlex,sys
from cStringIO import StringIO
from VendingMachine import *
# //putCoin
# //pushButton
# //verifyCoin
# //verifyButton
"""
class VendingMachine:
def putCoin(self, anAmount):
print '%d inserted' % anAmount
def pushButton(self, aButtonType):
print aButtonType + ' pushed'
def verifyCoin(self, anAmount):
print anAmount
def verifyButton(self, aStatus):
print aStatus
"""
v=VendingMachine()
class VendingCmd:
def __init__(self,cmd,**kwargs):
self.cmd = cmd
self.vm=v
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 + ' )'
def action(self):
raise NotImplementedError
class PutCmd(VendingCmd):
def action(self):
self.amount=self.arg
self.vm.putCoin(self.amount)
class PushCmd(VendingCmd):
def action(self):
self.buttonType = self.arg
self.vm.pushButton(self.buttonType)
class VerifyMoneyCmd(VendingCmd):
def action(self):
print self.vm.verifyCoin(self.amount)
class VerifyButtonCmd(VendingCmd):
def action(self):
print self.vm.verifyButton(self.status)
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 PutCmd('put',arg=money)
def parse_push(self):
button=self.next_button()
if button: return PushCmd('push',arg=button)
def parse_verify(self):
verify=self.next_verify()
if verify=='button':
status=self.next_status()
return VerifyButtonCmd('verify', arg=verify, status=status )
else:
money = self.next_money()
return VerifyMoneyCmd('verify', arg=verify, amount=money )
def next_status(self):
tok=self.lexer.get_token()
if tok not in ('on', 'off'):
return self.err('Unexpected button status')
return tok
def next_verify(self):
tok=self.lexer.get_token()
if tok not in ('money', 'button'):
return self.err('Unexpected verify type')
# print tok
return tok
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 10 put 50 put 1000")
print cmds
print `err.getvalue()`