Python utility for parsing blocks?
Question: I have a file that starts something like:

    
    
    databaseCons = {
        main = {
            database = "readable_name",
            hostname = "hostdb1.serv.com",
            instances= {
                slaves = {
                    conns = "8"
                }
            }
            maxconns = "5",
            user = "user",
            pass = "pass"
        }
    }
    

So, what I'd like to do is parse this out into a `dict` of sub-`dict`s,
something like:

`{'main': {'database': 'readable_name', 'hostname': 'hostdb1.serv.com',
'maxconns': '5', 'instances': {'slave': {'maxCount': '8'}}, 'user': 'user',
'pass': 'pass'}} `

I think the above makes sense... but please feel free to edit this if it
doesn't. Basically I want the equivalent of:

    
    
    conns = '8'
    
    slave = dict()
    slave['maxCount'] = conns
    
    instances = dict()
    instances['slave'] = slave
    
    database = 'readable_name'
    hostname = 'hostdb1.serv.com'
    maxconns = '5'
    user = 'user'
    pas = 'pass'
    main = dict()
    main['database'] = database
    main['hostname'] = hostname
    main['instances'] = instances
    main['maxconns'] = maxconns
    main['user'] = user
    main['pass'] = pas
    
    databaseCons = dict()
    databaseCons['main'] = main
    

Are there any modules out there that can handle this sort of parsing? Even
what I've suggested above looks messy.. there's got to be a better way I'd
imagine.


Answer: Here is a [pyparsing](https://pyparsing.wikispaces.com/) parser for your
config file:

    
    
    from pyparsing import *
    
    def to_dict(t):
        return {k:v for k,v in t}
    
    series = Forward()
    struct = Suppress('{') + series + Suppress('}')
    value = quotedString.setParseAction(removeQuotes) | struct
    token = Word(alphanums)
    assignment = Group(token + Suppress('=') + value + Suppress(Optional(",")))
    series << ZeroOrMore(assignment).setParseAction(to_dict)
    language = series + stringEnd
    
    def config_file_to_dict(filename):
        return language.parseFile(filename)[0]
    
    if __name__=="__main__":
        from pprint import pprint
        pprint(config_file_to_dict('config.txt'))
    

