<s> """<STR_LIT>""" <EOL> from __future__ import absolute_import , division , print_function <EOL> from . import lexer , error <EOL> from . import coretypes <EOL> __all__ = [ '<STR_LIT>' ] <EOL> class DataShapeParser ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , ds_str , sym ) : <EOL> self . ds_str = ds_str <EOL> self . sym = sym <EOL> self . lex = lexer . lex ( ds_str ) <EOL> self . tokens = [ ] <EOL> self . pos = - <NUM_LIT:1> <EOL> self . end_pos = None <EOL> self . advance_tok ( ) <EOL> def advance_tok ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . pos != self . end_pos : <EOL> self . pos = self . pos + <NUM_LIT:1> <EOL> try : <EOL> if self . pos >= len ( self . tokens ) : <EOL> self . tokens . append ( next ( self . lex ) ) <EOL> except StopIteration : <EOL> if len ( self . tokens ) > <NUM_LIT:0> : <EOL> span = ( self . tokens [ self . pos - <NUM_LIT:1> ] . span [ <NUM_LIT:1> ] , ) * <NUM_LIT:2> <EOL> else : <EOL> span = ( <NUM_LIT:0> , <NUM_LIT:0> ) <EOL> self . tokens . append ( lexer . Token ( None , None , span , None ) ) <EOL> self . end_pos = self . pos <EOL> @ property <EOL> def tok ( self ) : <EOL> return self . tokens [ self . pos ] <EOL> def raise_error ( self , errmsg ) : <EOL> raise error . DataShapeSyntaxError ( self . tok . span [ <NUM_LIT:0> ] , '<STR_LIT>' , <EOL> self . ds_str , errmsg ) <EOL> def parse_homogeneous_list ( self , parse_item , sep_tok_id , errmsg , <EOL> trailing_sep = False ) : <EOL> """<STR_LIT>""" <EOL> saved_pos = self . pos <EOL> items = [ ] <EOL> item = True <EOL> while item is not None : <EOL> item = parse_item ( ) <EOL> if item is not None : <EOL> items . append ( item ) <EOL> if self . tok . id == sep_tok_id : <EOL> self . advance_tok ( ) <EOL> else : <EOL> return items <EOL> else : <EOL> if len ( items ) > <NUM_LIT:0> : <EOL> if trailing_sep : <EOL> return items <EOL> else : <EOL> self . raise_error ( errmsg ) <EOL> else : <EOL> self . pos = saved_pos <EOL> return None <EOL> def syntactic_sugar ( self , symdict , name , dshapemsg , error_pos = None ) : <EOL> """<STR_LIT>""" <EOL> entry = symdict . get ( name ) <EOL> if entry is not None : <EOL> return entry <EOL> else : <EOL> if error_pos is not None : <EOL> self . pos = error_pos <EOL> self . raise_error ( ( '<STR_LIT>' + <EOL> '<STR_LIT>' ) % ( name , dshapemsg ) ) <EOL> def parse_datashape ( self ) : <EOL> """<STR_LIT>""" <EOL> tok = self . tok <EOL> constructors = { lexer . QUESTIONMARK : '<STR_LIT>' } <EOL> if tok . id in constructors : <EOL> self . advance_tok ( ) <EOL> saved_pos = self . pos <EOL> ds = self . parse_datashape_nooption ( ) <EOL> if ds is not None : <EOL> option = self . syntactic_sugar ( self . sym . dtype_constr , <EOL> constructors [ tok . id ] , <EOL> '<STR_LIT>' % <EOL> constructors [ tok . id ] , <EOL> saved_pos - <NUM_LIT:1> ) <EOL> return coretypes . DataShape ( option ( ds ) ) <EOL> else : <EOL> return self . parse_datashape_nooption ( ) <EOL> def parse_datashape_nooption ( self ) : <EOL> """<STR_LIT>""" <EOL> saved_pos = self . pos <EOL> dim = self . parse_dim ( ) <EOL> if dim is not None : <EOL> if self . tok . id == lexer . ASTERISK : <EOL> self . advance_tok ( ) <EOL> saved_pos = self . pos <EOL> dshape = self . parse_datashape ( ) <EOL> if dshape is None : <EOL> self . pos = saved_pos <EOL> self . raise_error ( '<STR_LIT>' ) <EOL> return coretypes . DataShape ( dim , * dshape . parameters ) <EOL> dtype = self . parse_dtype ( ) <EOL> if dtype : <EOL> return coretypes . DataShape ( dtype ) <EOL> else : <EOL> return None <EOL> def parse_dim ( self ) : <EOL> """<STR_LIT>""" <EOL> saved_pos = self . pos <EOL> tok = self . tok <EOL> if tok . id == lexer . NAME_UPPER : <EOL> val = tok . val <EOL> self . advance_tok ( ) <EOL> if self . tok . id == lexer . ELLIPSIS : <EOL> self . advance_tok ( ) <EOL> tconstr = self . syntactic_sugar ( self . sym . dim_constr , '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> saved_pos ) <EOL> return tconstr ( val ) <EOL> elif self . tok . id == lexer . ASTERISK : <EOL> tconstr = self . syntactic_sugar ( self . sym . dim_constr , '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> saved_pos ) <EOL> return tconstr ( val ) <EOL> else : <EOL> self . pos = saved_pos <EOL> return None <EOL> elif tok . id == lexer . NAME_LOWER : <EOL> name = tok . val <EOL> self . advance_tok ( ) <EOL> if self . tok . id == lexer . LBRACKET : <EOL> dim_constr = self . sym . dim_constr . get ( name ) <EOL> if dim_constr is None : <EOL> self . pos = saved_pos <EOL> return None <EOL> self . advance_tok ( ) <EOL> args = self . parse_type_arg_list ( ) <EOL> if self . tok . id == lexer . RBRACKET : <EOL> self . advance_tok ( ) <EOL> raise NotImplementedError ( <EOL> '<STR_LIT>' ) <EOL> else : <EOL> self . raise_error ( '<STR_LIT>' ) <EOL> else : <EOL> dim = self . sym . dim . get ( name ) <EOL> if dim is not None : <EOL> return dim <EOL> else : <EOL> self . pos = saved_pos <EOL> return None <EOL> elif tok . id == lexer . INTEGER : <EOL> val = tok . val <EOL> self . advance_tok ( ) <EOL> if self . tok . id != lexer . ASTERISK : <EOL> self . pos = saved_pos <EOL> return None <EOL> tconstr = self . syntactic_sugar ( self . sym . dim_constr , '<STR_LIT>' , <EOL> '<STR_LIT>' ) <EOL> return tconstr ( val ) <EOL> elif tok . id == lexer . ELLIPSIS : <EOL> self . advance_tok ( ) <EOL> dim = self . syntactic_sugar ( self . sym . dim , '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> saved_pos ) <EOL> return dim <EOL> else : <EOL> return None <EOL> def parse_dtype ( self ) : <EOL> """<STR_LIT>""" <EOL> saved_pos = self . pos <EOL> tok = self . tok <EOL> if tok . id == lexer . NAME_UPPER : <EOL> val = tok . val <EOL> self . advance_tok ( ) <EOL> tconstr = self . syntactic_sugar ( self . sym . dtype_constr , '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> saved_pos ) <EOL> return tconstr ( val ) <EOL> elif tok . id == lexer . NAME_LOWER : <EOL> name = tok . val <EOL> self . advance_tok ( ) <EOL> if self . tok . id == lexer . LBRACKET : <EOL> dtype_constr = self . sym . dtype_constr . get ( name ) <EOL> if dtype_constr is None : <EOL> self . pos = saved_pos <EOL> return None <EOL> self . advance_tok ( ) <EOL> args , kwargs = self . parse_type_arg_list ( ) <EOL> if self . tok . id == lexer . RBRACKET : <EOL> if len ( args ) == <NUM_LIT:0> and len ( kwargs ) == <NUM_LIT:0> : <EOL> self . raise_error ( '<STR_LIT>' + <EOL> '<STR_LIT>' ) <EOL> self . advance_tok ( ) <EOL> return dtype_constr ( * args , ** kwargs ) <EOL> else : <EOL> self . raise_error ( '<STR_LIT>' ) <EOL> else : <EOL> dtype = self . sym . dtype . get ( name ) <EOL> if dtype is not None : <EOL> return dtype <EOL> else : <EOL> self . pos = saved_pos <EOL> return None <EOL> elif tok . id == lexer . LBRACE : <EOL> return self . parse_struct_type ( ) <EOL> elif tok . id == lexer . LPAREN : <EOL> return self . parse_funcproto_or_tuple_type ( ) <EOL> else : <EOL> return None <EOL> def parse_type_arg_list ( self ) : <EOL> """<STR_LIT>""" <EOL> args = [ ] <EOL> arg = True <EOL> while arg is not None : <EOL> arg = self . parse_type_arg ( ) <EOL> if arg is not None : <EOL> if self . tok . id == lexer . COMMA : <EOL> self . advance_tok ( ) <EOL> args . append ( arg ) <EOL> else : <EOL> args . append ( arg ) <EOL> return ( args , { } ) <EOL> else : <EOL> break <EOL> kwargs = self . parse_homogeneous_list ( self . parse_type_kwarg , lexer . COMMA , <EOL> '<STR_LIT>' + <EOL> '<STR_LIT>' + <EOL> '<STR_LIT>' ) <EOL> return ( args , dict ( kwargs ) if kwargs else { } ) <EOL> def parse_type_arg ( self ) : <EOL> """<STR_LIT>""" <EOL> ds = self . parse_datashape ( ) <EOL> if ds is not None : <EOL> return ds <EOL> if self . tok . id in [ lexer . INTEGER , lexer . STRING , lexer . BOOLEAN ] : <EOL> val = self . tok . val <EOL> self . advance_tok ( ) <EOL> return val <EOL> elif self . tok . id == lexer . LBRACKET : <EOL> self . advance_tok ( ) <EOL> val = self . parse_datashape_list ( ) <EOL> if val is None : <EOL> val = self . parse_integer_list ( ) <EOL> if val is None : <EOL> val = self . parse_string_list ( ) <EOL> if val is None : <EOL> val = self . parse_boolean_list ( ) <EOL> if self . tok . id == lexer . RBRACKET : <EOL> self . advance_tok ( ) <EOL> return [ ] if val is None else val <EOL> else : <EOL> if val is None : <EOL> self . raise_error ( '<STR_LIT>' + <EOL> '<STR_LIT>' ) <EOL> else : <EOL> self . raise_error ( '<STR_LIT>' ) <EOL> else : <EOL> return None <EOL> def parse_type_kwarg ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . tok . id != lexer . NAME_LOWER : <EOL> return None <EOL> saved_pos = self . pos <EOL> name = self . tok . val <EOL> self . advance_tok ( ) <EOL> if self . tok . id != lexer . EQUAL : <EOL> self . pos = saved_pos <EOL> return None <EOL> self . advance_tok ( ) <EOL> arg = self . parse_type_arg ( ) <EOL> if arg is not None : <EOL> return ( name , arg ) <EOL> else : <EOL> self . raise_error ( '<STR_LIT>' ) <EOL> def parse_datashape_list ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . parse_homogeneous_list ( self . parse_datashape , lexer . COMMA , <EOL> '<STR_LIT>' + <EOL> '<STR_LIT>' + <EOL> '<STR_LIT>' ) <EOL> def parse_integer ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . tok . id == lexer . INTEGER : <EOL> val = self . tok . val <EOL> self . advance_tok ( ) <EOL> return val <EOL> else : <EOL> return None <EOL> def parse_integer_list ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . parse_homogeneous_list ( self . parse_integer , lexer . COMMA , <EOL> '<STR_LIT>' + <EOL> '<STR_LIT>' + <EOL> '<STR_LIT>' ) <EOL> def parse_boolean ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . tok . id == lexer . BOOLEAN : <EOL> val = self . tok . val <EOL> self . advance_tok ( ) <EOL> return val <EOL> else : <EOL> return None <EOL> def parse_boolean_list ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . parse_homogeneous_list ( self . parse_boolean , lexer . COMMA , <EOL> '<STR_LIT>' + <EOL> '<STR_LIT>' + <EOL> '<STR_LIT>' ) <EOL> def parse_string ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . tok . id == lexer . STRING : <EOL> val = self . tok . val <EOL> self . advance_tok ( ) <EOL> return val <EOL> else : <EOL> return None <EOL> def parse_string_list ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . parse_homogeneous_list ( self . parse_string , lexer . COMMA , <EOL> '<STR_LIT>' + <EOL> '<STR_LIT>' + <EOL> '<STR_LIT>' ) <EOL> def parse_struct_type ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . tok . id != lexer . LBRACE : <EOL> return None <EOL> saved_pos = self . pos <EOL> self . advance_tok ( ) <EOL> fields = self . parse_homogeneous_list ( self . parse_struct_field , lexer . COMMA , <EOL> '<STR_LIT>' , <EOL> trailing_sep = True ) or [ ] <EOL> if self . tok . id != lexer . RBRACE : <EOL> self . raise_error ( '<STR_LIT>' ) <EOL> self . advance_tok ( ) <EOL> names = [ f [ <NUM_LIT:0> ] for f in fields ] <EOL> types = [ f [ <NUM_LIT:1> ] for f in fields ] <EOL> tconstr = self . syntactic_sugar ( self . sym . dtype_constr , '<STR_LIT>' , <EOL> '<STR_LIT>' , saved_pos ) <EOL> return tconstr ( names , types ) <EOL> def parse_struct_field ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . tok . id not in [ lexer . NAME_LOWER , lexer . NAME_UPPER , <EOL> lexer . NAME_OTHER , lexer . STRING ] : <EOL> return None <EOL> name = self . tok . val <EOL> self . advance_tok ( ) <EOL> if self . tok . id != lexer . COLON : <EOL> self . raise_error ( '<STR_LIT>' + <EOL> '<STR_LIT>' ) <EOL> self . advance_tok ( ) <EOL> ds = self . parse_datashape ( ) <EOL> if ds is None : <EOL> self . raise_error ( '<STR_LIT>' ) <EOL> return ( name , ds ) <EOL> def parse_funcproto_or_tuple_type ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . tok . id != lexer . LPAREN : <EOL> return None <EOL> saved_pos = self . pos <EOL> self . advance_tok ( ) <EOL> dshapes = self . parse_homogeneous_list ( <EOL> self . parse_datashape , <EOL> lexer . COMMA , <EOL> '<STR_LIT>' , <EOL> trailing_sep = True , <EOL> ) or ( ) <EOL> if self . tok . id != lexer . RPAREN : <EOL> self . raise_error ( '<STR_LIT>' ) <EOL> self . advance_tok ( ) <EOL> if self . tok . id != lexer . RARROW : <EOL> tconstr = self . syntactic_sugar ( self . sym . dtype_constr , '<STR_LIT>' , <EOL> '<STR_LIT>' , saved_pos ) <EOL> return tconstr ( dshapes ) <EOL> else : <EOL> self . advance_tok ( ) <EOL> ret_dshape = self . parse_datashape ( ) <EOL> if ret_dshape is None : <EOL> self . raise_error ( '<STR_LIT>' + <EOL> '<STR_LIT>' ) <EOL> tconstr = self . syntactic_sugar ( self . sym . dtype_constr , '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> saved_pos ) <EOL> return tconstr ( dshapes , ret_dshape ) <EOL> def parse ( ds_str , sym ) : <EOL> """<STR_LIT>""" <EOL> dsp = DataShapeParser ( ds_str , sym ) <EOL> ds = dsp . parse_datashape ( ) <EOL> if ds is None : <EOL> dsp . raise_error ( '<STR_LIT>' ) <EOL> if dsp . pos != dsp . end_pos : <EOL> dsp . raise_error ( '<STR_LIT>' ) <EOL> return ds </s>
