<s> """<STR_LIT>""" <EOL> import re <EOL> import sys <EOL> import copy <EOL> import string <EOL> from re import ( I , IGNORECASE , L , LOCALE , M , MULTILINE , <EOL> S , DOTALL , U , UNICODE , X , VERBOSE ) <EOL> if sys . version_info [ <NUM_LIT:0> ] < <NUM_LIT:3> : <EOL> from StringIO import StringIO <EOL> else : <EOL> from io import StringIO <EOL> from functools import partial <EOL> from collections import OrderedDict <EOL> class Dummy ( ) : <EOL> """<STR_LIT:U+0020>""" <EOL> pass <EOL> _FORMATTER = string . Formatter ( ) <EOL> _REG = { None : ( '<STR_LIT>' , str ) , <EOL> '<STR_LIT:s>' : ( '<STR_LIT>' , str ) , <EOL> '<STR_LIT:d>' : ( '<STR_LIT>' , int ) , <EOL> '<STR_LIT:b>' : ( '<STR_LIT>' , partial ( int , base = <NUM_LIT:2> ) ) , <EOL> '<STR_LIT:o>' : ( '<STR_LIT>' , partial ( int , base = <NUM_LIT:8> ) ) , <EOL> '<STR_LIT:x>' : ( '<STR_LIT>' , partial ( int , base = <NUM_LIT:16> ) ) , <EOL> '<STR_LIT:X>' : ( '<STR_LIT>' , partial ( int , base = <NUM_LIT:16> ) ) , <EOL> '<STR_LIT:e>' : ( '<STR_LIT>' , float ) , <EOL> '<STR_LIT:E>' : ( '<STR_LIT>' , float ) , <EOL> '<STR_LIT:f>' : ( '<STR_LIT>' , float ) , <EOL> '<STR_LIT:F>' : ( '<STR_LIT>' , float ) , <EOL> '<STR_LIT:g>' : ( '<STR_LIT>' , float ) , <EOL> '<STR_LIT>' : ( '<STR_LIT>' , float ) , <EOL> '<STR_LIT:%>' : ( '<STR_LIT>' , lambda x : float ( x [ : - <NUM_LIT:1> ] ) / <NUM_LIT:100> ) } <EOL> _FMT = re . compile ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> def fmt_to_regex ( fmt ) : <EOL> """<STR_LIT>""" <EOL> ( align , fill , sign , alternate , <EOL> zero , width , comma , precision , ctype ) = _FMT . search ( fmt ) . groups ( ) <EOL> try : <EOL> reg , fun = _REG [ ctype ] <EOL> except KeyError : <EOL> raise ValueError ( '<STR_LIT>' . format ( ctype ) ) <EOL> if alternate : <EOL> if ctype in ( '<STR_LIT:o>' , '<STR_LIT:x>' , '<STR_LIT:X>' , '<STR_LIT:b>' ) : <EOL> reg = '<STR_LIT:0>' + ctype + reg <EOL> else : <EOL> raise ValueError ( '<STR_LIT>' . format ( ctype ) ) <EOL> if sign == '<STR_LIT:->' or sign is None : <EOL> reg = '<STR_LIT>' + reg <EOL> elif sign == '<STR_LIT:+>' : <EOL> reg = '<STR_LIT>' + reg <EOL> elif sign == '<STR_LIT:U+0020>' : <EOL> reg = '<STR_LIT>' + reg <EOL> else : <EOL> raise ValueError ( '<STR_LIT>' . format ( sign ) ) <EOL> return reg , fun <EOL> def split_field_name ( name ) : <EOL> """<STR_LIT>""" <EOL> first = True <EOL> for namepart in name . split ( '<STR_LIT:.>' ) : <EOL> keyparts = namepart . split ( '<STR_LIT:[>' ) <EOL> key = keyparts [ <NUM_LIT:0> ] <EOL> if key == '<STR_LIT>' : <EOL> raise ValueError ( "<STR_LIT>" . format ( name ) ) <EOL> if first : <EOL> first = False <EOL> yield ( '<STR_LIT>' , key ) <EOL> else : <EOL> yield ( '<STR_LIT>' , key ) <EOL> for key in keyparts [ <NUM_LIT:1> : ] : <EOL> endbracket = key . find ( '<STR_LIT:]>' ) <EOL> if endbracket < <NUM_LIT:0> or endbracket != len ( key ) - <NUM_LIT:1> : <EOL> raise ValueError ( "<STR_LIT>" . format ( name ) ) <EOL> key = key [ : - <NUM_LIT:1> ] <EOL> try : <EOL> key = int ( key ) <EOL> except ValueError : <EOL> pass <EOL> yield ( '<STR_LIT>' , key ) <EOL> def build_hierarchy ( field_parts , top ) : <EOL> """<STR_LIT>""" <EOL> for typ , name in reversed ( list ( field_parts ) ) : <EOL> if typ == '<STR_LIT>' : <EOL> tmp = Dummy ( ) <EOL> setattr ( tmp , name , top ) <EOL> top = tmp <EOL> elif typ == '<STR_LIT>' : <EOL> tmp = dict ( ) <EOL> tmp [ name ] = top <EOL> top = tmp <EOL> return top <EOL> def append_to_hierarchy ( bottom , field_parts , top ) : <EOL> """<STR_LIT>""" <EOL> for typ_ , name in field_parts : <EOL> if isinstance ( bottom , dict ) : <EOL> if not typ_ == '<STR_LIT>' : <EOL> raise ValueError ( "<STR_LIT>" . format ( typ_ , name ) ) <EOL> try : <EOL> bottom = bottom [ name ] <EOL> except KeyError : <EOL> bottom [ name ] = build_hierarchy ( field_parts , top ) <EOL> elif isinstance ( bottom , Dummy ) : <EOL> if not typ_ == '<STR_LIT>' : <EOL> raise ValueError ( "<STR_LIT>" . format ( typ_ , name ) ) <EOL> try : <EOL> bottom = getattr ( bottom , name ) <EOL> except AttributeError : <EOL> setattr ( bottom , name , <EOL> build_hierarchy ( field_parts , top ) ) <EOL> else : <EOL> raise ValueError ( "<STR_LIT>" . format ( typ_ , name ) ) <EOL> def set_in_hierarchy ( bottom , field_parts , top ) : <EOL> """<STR_LIT>""" <EOL> for typ_ , name in field_parts : <EOL> if isinstance ( bottom , dict ) : <EOL> if bottom [ name ] is None : <EOL> bottom [ name ] = top <EOL> else : <EOL> set_in_hierarchy ( bottom [ name ] , field_parts , top ) <EOL> elif isinstance ( bottom , Dummy ) : <EOL> if getattr ( bottom , name ) is None : <EOL> setattr ( bottom , name , top ) <EOL> else : <EOL> set_in_hierarchy ( getattr ( bottom , name ) , field_parts , top ) <EOL> elif isinstance ( bottom , list ) : <EOL> if bottom [ int ( name ) ] is None : <EOL> bottom [ int ( name ) ] = top <EOL> else : <EOL> set_in_hierarchy ( bottom [ int ( name ) ] , field_parts , top ) <EOL> def convert ( obj ) : <EOL> """<STR_LIT>""" <EOL> if obj is None : <EOL> return obj <EOL> elif isinstance ( obj , dict ) : <EOL> try : <EOL> keys = [ int ( key ) for key in obj . keys ( ) ] <EOL> if min ( keys ) == <NUM_LIT:0> and max ( keys ) == len ( keys ) - <NUM_LIT:1> : <EOL> return [ convert ( obj [ str ( key ) ] ) for key in keys ] <EOL> except : <EOL> pass <EOL> for key , value in obj . items ( ) : <EOL> obj [ key ] = convert ( value ) <EOL> return obj <EOL> elif isinstance ( obj , Dummy ) : <EOL> for key , value in obj . __dict__ . items ( ) : <EOL> setattr ( obj , key , convert ( value ) ) <EOL> return obj <EOL> class Parser ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , format_string , flags = <NUM_LIT:0> ) : <EOL> self . _fields = [ ] <EOL> self . _output_dict = False <EOL> pattern = StringIO ( ) <EOL> number = <NUM_LIT:0> <EOL> template = OrderedDict ( ) <EOL> for literal , field , fmt , conv in _FORMATTER . parse ( format_string ) : <EOL> pattern . write ( re . escape ( literal ) ) <EOL> if field is None and fmt is None and conv is None : <EOL> continue <EOL> if fmt is None or fmt == '<STR_LIT>' : <EOL> reg , fun = _REG [ '<STR_LIT:s>' ] <EOL> else : <EOL> reg , fun = fmt_to_regex ( fmt ) <EOL> if field == '<STR_LIT:_>' : <EOL> pattern . write ( '<STR_LIT>' + reg + '<STR_LIT:)>' ) <EOL> continue <EOL> if not field or field [ <NUM_LIT:0> ] in ( '<STR_LIT:.>' , '<STR_LIT:[>' ) : <EOL> field = str ( number ) + field <EOL> number += <NUM_LIT:1> <EOL> pattern . write ( '<STR_LIT:(>' + reg + '<STR_LIT:)>' ) <EOL> self . _fields . append ( ( field , fun ) ) <EOL> append_to_hierarchy ( template , split_field_name ( field ) , None ) <EOL> self . _template = convert ( template ) <EOL> self . _regex = re . compile ( '<STR_LIT>' + pattern . getvalue ( ) + '<STR_LIT:$>' , flags ) <EOL> def __call__ ( self , text ) : <EOL> mobj = self . _regex . search ( text ) <EOL> if mobj is None : <EOL> raise ValueError ( "<STR_LIT>" <EOL> "<STR_LIT>" . format ( text , self . _regex . pattern ) ) <EOL> parsed = copy . deepcopy ( self . _template ) <EOL> for group , ( field , fun ) in zip ( mobj . groups ( ) , self . _fields ) : <EOL> set_in_hierarchy ( parsed , split_field_name ( field ) , fun ( group ) ) <EOL> if isinstance ( parsed , list ) and len ( parsed ) == <NUM_LIT:1> : <EOL> return parsed [ <NUM_LIT:0> ] <EOL> return parsed </s>
