[Pyparsing] Lists and Groups
Brought to you by:
ptmcg
From: Michael F. <nob...@gm...> - 2010-11-12 18:26:25
|
Hello all, First, thanks for the wonderful programming API. I'm having a long of fun with it. I have a question, I feel like I'm ruining the BNF expression when overly massage the input. Should I stick to BNF or start tokenizing? Allow me to explain. I've always been fascinated with interfaces which seem to understand human language, kind of like gmail's "quick-add" featurer for its calender. So, to learn how to do this better, I'm writing a little diddy to interpret simple commands into creating a shopping list. Here is a list of generic input I expect it to understand #test grammar tests= """\ buy chocolate milk, eggs and bread at store get eggs at @Vons need headache medicine and cough medicine from downtown drug store buy nails, claw hammer, and studs at @homedepot buy ragjoint at car parts store buy laptop at electronics store get candy @Sees get a clue""".splitlines() My evil mashup is as follows... # define grammar KW = Keyword and_ = Literal(" and ") comma = Literal(",") at = KW("from") | KW("at") label = Literal("@") + Word(alphanums) buy = KW("buy") | KW("get") | KW("need") item = Group( OneOrMore( ~ (at | and_) + (Word(alphas + "-"))) + Suppress(Optional(comma))) | Suppress(Optional(and_)) items = Group( OneOrMore( item ) ) store = KW("store") | KW("market") | KW("grocery") storetype = Suppress(at) + Group(OneOrMore( Word(alphas))) storelabel = label storename = storetype | storelabel shlisti = Suppress(buy) + items + Optional( storename ) What I wish to do is interpret a sentence starts with some synonym of "buy", interprets everything after that as a list of things to buy (accepting and as a synonym for a comma) until it reaches some synonym of "from", and then everything after that is interpreted as a store name. All I want to keep is the list of items, and the storename. What I wind up doing is as follows: buy chocolate milk, eggs and bread at store -> [[['chocolate', 'milk']]] get eggs at @Vons -> [[['eggs']]] need headache medicine and cough medicine from downtown drug store -> [[['headache', 'medicine', 'and', 'cough', 'medicine']], ['downtown', 'drug', 'store']] buy nails, claw hammer, and studs at @homedepot -> [[['nails']]] buy ragjoint at car parts store -> [[['ragjoint']], ['car', 'parts', 'store']] buy laptop at electronics store -> [[['laptop']], ['electronics', 'store']] get candy @Sees -> [[['candy']], '@', 'Sees'] get a clue -> [[['a', 'clue']]] Is there a way to express it in the nice BNF form or did I already jump off that reservation with the grouping and suppressing? |