U E D R , A S I H C RSS

Seminar How To Program It/Pipe/Vending Machine Parser.py


#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()`
Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2009-05-27 07:09:19
Processing time 0.0951 sec