Re: [Pyparsing] Parsing multiple items into the same Dict
Brought to you by:
ptmcg
From: George P. <ge...@ga...> - 2006-10-25 01:05:46
|
> George - > > Is it really necessary to create the dict directly in the ParseResults? > This could probably be done in some tricky parse actions, but things might > be simpler if your ParseResults just reflect the expression structure, and > then walk the structure to build up your nested dict. Below is one way. > > -- Paul > > > from pyparsing import * > > s = \ > """ > a.clk = "----____----____" > a.rst = "--------________" > > b.clk = "____----____----" > b.x = "________--------" > """ > > TIMING_SPEC = Combine('"' + Word('_-') + '"' ) > ident = Word(alphas, alphanums) > > SIGNAL_DEF = ident.setResultsName("GROUP") + \ > '.' + ident.setResultsName("SIGNAME") + \ > '=' + \ > TIMING_SPEC.setResultsName("TIMING_SPEC") > > GRAMMAR = OneOrMore( Group(SIGNAL_DEF) ) > > results = GRAMMAR.parseString(s) > > d = {} > for toks in results: > if toks.GROUP not in d: > d[toks.GROUP] = {} > d[toks.GROUP][toks.SIGNAME] = toks.TIMING_SPEC > > print d > print d.keys() > for k in d.keys(): > print k, d[k].keys() > > > Prints out: > {'a': {'rst': '"--------________"', 'clk': '"----____----____"'}, 'b': {'x': > '"________--------"', 'clk': '"____----____----"'}} > ['a', 'b'] > a ['rst', 'clk'] > b ['x', 'clk'] > d['a']['rst'] -> "--------________" > d['a']['clk'] -> "----____----____" > d['b']['x'] -> "________--------" > d['b']['clk'] -> "____----____----" > > Paul, Thanks for your fantastic help! Your detailed example taught me a lot. No, I didn't need to create the dict in the parse results directly. I'm glad you questioned that because I was starting to go insane ;-) Here's an excerpt of the solution you helped guide me to. (Note: I accidentally used quotes in my timing spec string in the previous email). If you're curious what I'm doing this for, I'm making a tool for MyHDL to increase the fun factor in the design and testing of complex electronic systems: http://myhdl.jandecaluwe.com/doku.php/users:george_pantazopoulos Kudos, George http://www.gammaburst.net # --------------------- from pyparsing import * def parse_ats_block(ats_block): """ Example input: a.clk = ----____----____ a.rst = --------________ b.clk = ____----____---- b.x = ________-------- For the Timing Diagram portion: Input Parser output --------------------------------------- "--__" => ['-', '-', '_', '_'] "1..72." => ['1..', '72.'] """ # pyparsing grammar # Special thanks to Paul McGuire # The OneOrMore() will split up the timing spec into a list of tokens TIMING_SPEC = OneOrMore(Regex('[-_]') | Regex('[0-9]+\.+')) identifier = Word(alphas, alphanums) SIGNAL_DEF = identifier.setResultsName("GROUP") + \ '.' + identifier.setResultsName("SIGNAME") + \ '=' + TIMING_SPEC.setResultsName("TIMING_SPEC") ATS_GRAMMAR = OneOrMore(Group(SIGNAL_DEF)) # The parse results can be treated as a list of lists of the following # form: (Each sublist represents a signal definition) # [groupname, '.', signame, '=', timingspec] # In addition, thanks to the use of setResultsName() # the components can also be accessed using attribute syntax # Each signal definition entry in the results will contain # a .GROUP, .SIGNAME, and .TIMING_SPEC attribute. # Parse results = ATS_GRAMMAR.parseString(ats_block) # From the parse results create a nested dict. # The top level dict contains a dict for each group, keyed by the # group name. # # Each group dict contains key/value pairs where key = signal name # and value = the signal's timing spec d = dict() for toks in results: if toks.GROUP not in d: d[toks.GROUP] = dict() d[toks.GROUP][toks.SIGNAME] = toks.TIMING_SPEC results_dict = d return results_dict |