<s> """<STR_LIT>""" <EOL> from jedi . _compatibility import unicode <EOL> from jedi . parser import representation as pr <EOL> from jedi import debug <EOL> from jedi . common import PushBackIterator <EOL> from jedi . evaluate . compiled import CompiledObject , create , builtin <EOL> class PythonGrammar ( object ) : <EOL> """<STR_LIT>""" <EOL> class MultiPart ( str ) : <EOL> def __new__ ( cls , first , second ) : <EOL> self = str . __new__ ( cls , first ) <EOL> self . second = second <EOL> return self <EOL> def __str__ ( self ) : <EOL> return str . __str__ ( self ) + '<STR_LIT:U+0020>' + self . second <EOL> FACTOR = '<STR_LIT:+>' , '<STR_LIT:->' , '<STR_LIT>' <EOL> POWER = '<STR_LIT>' , <EOL> TERM = '<STR_LIT:*>' , '<STR_LIT:/>' , '<STR_LIT:%>' , '<STR_LIT>' <EOL> ARITH_EXPR = '<STR_LIT:+>' , '<STR_LIT:->' <EOL> SHIFT_EXPR = '<STR_LIT>' , '<STR_LIT>' <EOL> AND_EXPR = '<STR_LIT:&>' , <EOL> XOR_EXPR = '<STR_LIT>' , <EOL> EXPR = '<STR_LIT:|>' , <EOL> COMPARISON = ( '<STR_LIT:<>' , '<STR_LIT:>>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> MultiPart ( '<STR_LIT>' , '<STR_LIT>' ) , MultiPart ( '<STR_LIT>' , '<STR_LIT>' ) , '<STR_LIT>' ) <EOL> NOT_TEST = '<STR_LIT>' , <EOL> AND_TEST = '<STR_LIT>' , <EOL> OR_TEST = '<STR_LIT>' , <EOL> TERNARY = '<STR_LIT>' , <EOL> SLICE = '<STR_LIT::>' , <EOL> ORDER = ( POWER , TERM , ARITH_EXPR , SHIFT_EXPR , AND_EXPR , XOR_EXPR , <EOL> EXPR , COMPARISON , AND_TEST , OR_TEST , TERNARY , SLICE ) <EOL> FACTOR_PRIORITY = <NUM_LIT:0> <EOL> LOWEST_PRIORITY = len ( ORDER ) <EOL> NOT_TEST_PRIORITY = LOWEST_PRIORITY - <NUM_LIT:4> <EOL> SLICE_PRIORITY = LOWEST_PRIORITY - <NUM_LIT:1> <EOL> class Precedence ( object ) : <EOL> def __init__ ( self , left , operator , right ) : <EOL> self . left = left <EOL> self . operator = operator <EOL> self . right = right <EOL> def parse_tree ( self , strip_literals = False ) : <EOL> def process ( which ) : <EOL> try : <EOL> which = which . parse_tree ( strip_literals ) <EOL> except AttributeError : <EOL> pass <EOL> if strip_literals and isinstance ( which , pr . Literal ) : <EOL> which = which . value <EOL> return which <EOL> return ( process ( self . left ) , self . operator , process ( self . right ) ) <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' % ( self . left , self . operator , self . right ) <EOL> class TernaryPrecedence ( Precedence ) : <EOL> def __init__ ( self , left , operator , right , check ) : <EOL> super ( TernaryPrecedence , self ) . __init__ ( left , operator , right ) <EOL> self . check = check <EOL> def create_precedence ( expression_list ) : <EOL> iterator = PushBackIterator ( iter ( expression_list ) ) <EOL> return _check_operator ( iterator ) <EOL> def _syntax_error ( element , msg = '<STR_LIT>' ) : <EOL> debug . warning ( '<STR_LIT>' % ( msg , element , element . start_pos ) ) <EOL> def _get_number ( iterator , priority = PythonGrammar . LOWEST_PRIORITY ) : <EOL> el = next ( iterator ) <EOL> if isinstance ( el , pr . Operator ) : <EOL> if el in PythonGrammar . FACTOR : <EOL> right = _get_number ( iterator , PythonGrammar . FACTOR_PRIORITY ) <EOL> elif el in PythonGrammar . NOT_TEST and priority >= PythonGrammar . NOT_TEST_PRIORITY : <EOL> right = _get_number ( iterator , PythonGrammar . NOT_TEST_PRIORITY ) <EOL> elif el in PythonGrammar . SLICE and priority >= PythonGrammar . SLICE_PRIORITY : <EOL> iterator . push_back ( el ) <EOL> return None <EOL> else : <EOL> _syntax_error ( el ) <EOL> return _get_number ( iterator , priority ) <EOL> return Precedence ( None , el , right ) <EOL> else : <EOL> return el <EOL> def _check_operator ( iterator , priority = PythonGrammar . LOWEST_PRIORITY ) : <EOL> try : <EOL> left = _get_number ( iterator , priority ) <EOL> except StopIteration : <EOL> return None <EOL> for el in iterator : <EOL> if not isinstance ( el , pr . Operator ) : <EOL> _syntax_error ( el ) <EOL> continue <EOL> operator = None <EOL> for check_prio , check in enumerate ( PythonGrammar . ORDER ) : <EOL> if check_prio >= priority : <EOL> iterator . push_back ( el ) <EOL> return left <EOL> try : <EOL> match_index = check . index ( el ) <EOL> except ValueError : <EOL> continue <EOL> match = check [ match_index ] <EOL> if isinstance ( match , PythonGrammar . MultiPart ) : <EOL> next_tok = next ( iterator ) <EOL> if next_tok != match . second : <EOL> iterator . push_back ( next_tok ) <EOL> if el == '<STR_LIT>' : <EOL> match = '<STR_LIT>' <EOL> else : <EOL> continue <EOL> operator = match <EOL> break <EOL> if operator is None : <EOL> _syntax_error ( el ) <EOL> continue <EOL> if operator in PythonGrammar . POWER : <EOL> check_prio += <NUM_LIT:1> <EOL> elif operator in PythonGrammar . TERNARY : <EOL> try : <EOL> middle = [ ] <EOL> for each in iterator : <EOL> if each == '<STR_LIT>' : <EOL> break <EOL> middle . append ( each ) <EOL> middle = create_precedence ( middle ) <EOL> except StopIteration : <EOL> _syntax_error ( operator , '<STR_LIT>' ) <EOL> right = _check_operator ( iterator , check_prio ) <EOL> if right is None and not operator in PythonGrammar . SLICE : <EOL> _syntax_error ( iterator . current , '<STR_LIT>' ) <EOL> else : <EOL> if operator in PythonGrammar . TERNARY : <EOL> left = TernaryPrecedence ( left , str ( operator ) , right , middle ) <EOL> else : <EOL> left = Precedence ( left , str ( operator ) , right ) <EOL> return left <EOL> def _literals_to_types ( evaluator , result ) : <EOL> for i , r in enumerate ( result ) : <EOL> if is_literal ( r ) : <EOL> cls = builtin . get_by_name ( r . name ) <EOL> result [ i ] = evaluator . execute ( cls ) [ <NUM_LIT:0> ] <EOL> return list ( set ( result ) ) <EOL> def calculate ( evaluator , left_result , operator , right_result ) : <EOL> result = [ ] <EOL> if left_result is None and right_result : <EOL> for right in right_result : <EOL> result . append ( _factor_calculate ( evaluator , operator , right ) ) <EOL> return result <EOL> else : <EOL> if not left_result or not right_result : <EOL> result = ( left_result or [ ] ) + ( right_result or [ ] ) <EOL> result = _literals_to_types ( evaluator , result ) <EOL> else : <EOL> if len ( left_result ) * len ( right_result ) > <NUM_LIT:6> : <EOL> result = _literals_to_types ( evaluator , left_result + right_result ) <EOL> else : <EOL> for left in left_result : <EOL> for right in right_result : <EOL> result += _element_calculate ( evaluator , left , operator , right ) <EOL> return result <EOL> def _factor_calculate ( evaluator , operator , right ) : <EOL> if _is_number ( right ) : <EOL> if operator == '<STR_LIT:->' : <EOL> return create ( evaluator , - right . obj ) <EOL> return right <EOL> def _is_number ( obj ) : <EOL> return isinstance ( obj , CompiledObject ) and isinstance ( obj . obj , ( int , float ) ) <EOL> def _is_string ( obj ) : <EOL> return isinstance ( obj , CompiledObject ) and isinstance ( obj . obj , ( str , unicode ) ) <EOL> def is_literal ( obj ) : <EOL> return _is_number ( obj ) or _is_string ( obj ) <EOL> def _element_calculate ( evaluator , left , operator , right ) : <EOL> if operator == '<STR_LIT:*>' : <EOL> from jedi . evaluate import iterable <EOL> if isinstance ( left , iterable . Array ) or _is_string ( left ) : <EOL> return [ left ] <EOL> elif operator == '<STR_LIT:+>' : <EOL> if _is_number ( left ) and _is_number ( right ) or _is_string ( left ) and _is_string ( right ) : <EOL> return [ create ( evaluator , left . obj + right . obj ) ] <EOL> elif operator == '<STR_LIT:->' : <EOL> if _is_number ( left ) and _is_number ( right ) : <EOL> return [ create ( evaluator , left . obj - right . obj ) ] <EOL> return [ left , right ] </s>
