3
=
^*S                 @   s  d Z ddlmZ ddlmZ ddlmZ G dd deZG dd deeZ	e
d	kr
e Zej  dd
lmZmZ edkr
ej \ZZZZZddlmZ eeeZeejjjedj Zeee Zddl Z edd eD Zedd eD Zeee Ze!e dS )z8
spark grammar differences over Python2 for Python 2.6.
    )PythonParserSingle)DEFAULT_DEBUG)Python2Parserc                   sp   e Zd Zef fdd	Zdd Zdd Zdd Zd	d
 Zdd Z	dd Z
dd Z fddZ fddZ  ZS )Python26Parserc                s   t t| j| i | _d S )N)superr   __init__Z
customized)selfZdebug_parser)	__class__ W/home/psgendb/BIRCHDEV/python/lib/python3.6/site-packages/uncompyle6/parsers/parse26.pyr      s    zPython26Parser.__init__c             C   s   dS )aZ  
        except_stmt    ::= except_cond3 except_suite
        except_cond1   ::= DUP_TOP expr COMPARE_OP
                           JUMP_IF_FALSE POP_TOP POP_TOP POP_TOP POP_TOP
        except_cond3   ::= DUP_TOP expr COMPARE_OP
                           JUMP_IF_FALSE POP_TOP POP_TOP store POP_TOP

        except_handler ::= JUMP_FORWARD COME_FROM except_stmts
                           come_froms_pop END_FINALLY come_froms

        except_handler ::= JUMP_FORWARD COME_FROM except_stmts END_FINALLY
                           come_froms

        except_handler ::= jmp_abs COME_FROM except_stmts
                           POP_TOP END_FINALLY

        except_handler ::= jmp_abs COME_FROM except_stmts
                           END_FINALLY JUMP_FORWARD

        # Sometimes we don't put in COME_FROM to the next statement
        # like we do in 2.7. Perhaps we should?
        try_except     ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
                            except_handler

        tryelsestmt    ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
                           except_handler else_suite come_froms
        tryelsestmtl   ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
                            except_handler else_suitel
        tryelsestmtc   ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
                           except_handler else_suitec

        _ifstmts_jump  ::= c_stmts_opt JUMP_FORWARD COME_FROM POP_TOP

        except_suite   ::= c_stmts_opt JUMP_FORWARD come_from_pop
        except_suite   ::= c_stmts_opt jf_pop
        except_suite   ::= c_stmts_opt jmp_abs come_from_pop

        # This is what happens after a jump where
        # we start a new block. For reasons I don't fully
        # understand, there is also a value on the top of the stack
        come_from_pop   ::=  COME_FROM POP_TOP
        come_froms_pop  ::= come_froms POP_TOP
        Nr
   )r   argsr
   r
   r   p_try_except26   s    zPython26Parser.p_try_except26c             C   s   dS )a  

        # The are the equivalents of Python 2.7+'s
        # POP_JUMP_IF_TRUE and POP_JUMP_IF_FALSE
        jmp_true     ::= JUMP_IF_TRUE POP_TOP
        jmp_false    ::= JUMP_IF_FALSE POP_TOP

        jb_pop       ::= JUMP_BACK POP_TOP
        jf_pop       ::= JUMP_FORWARD POP_TOP

        jb_cont      ::= JUMP_BACK
        jb_cont      ::= CONTINUE

        jb_cf_pop ::= come_from_opt JUMP_BACK _come_froms POP_TOP
        ja_cf_pop ::= JUMP_ABSOLUTE come_froms POP_TOP
        jf_cf_pop ::= JUMP_FORWARD come_froms POP_TOP

        # The first optional COME_FROM when it appears is really
        # COME_FROM_LOOP, but in <= 2.6 we don't distinguish
        # this

        cf_jb_cf_pop ::= _come_froms JUMP_BACK come_froms POP_TOP

        bp_come_from    ::= POP_BLOCK COME_FROM
        jb_pb_come_from ::= JUMP_BACK bp_come_from

        _ifstmts_jump ::= c_stmts_opt JUMP_FORWARD COME_FROM POP_TOP
        _ifstmts_jump ::= c_stmts_opt JUMP_FORWARD come_froms POP_TOP COME_FROM

        # This is what happens after a jump where
        # we start a new block. For reasons I don't fully
        # understand, there is also a value on the top of the stack
        come_froms_pop  ::=  come_froms POP_TOP

        Nr
   )r   r   r
   r
   r   	p_jumps26B   s    zPython26Parser.p_jumps26c             C   s   dS )aN  
        stmt ::= ifelsestmtr

        # We use filler as a placeholder to keep nonterminal positions
        # the same across different grammars so that the same semantic actions
        # can be used
        filler ::=

        assert ::= assert_expr jmp_true LOAD_ASSERT RAISE_VARARGS_1 come_froms_pop
        assert2 ::= assert_expr jmp_true LOAD_ASSERT expr RAISE_VARARGS_2 come_froms_pop

        break ::= BREAK_LOOP JUMP_BACK

        # Semantic actions want else_suitel to be at index 3
        ifelsestmtl ::= testexpr c_stmts_opt cf_jb_cf_pop else_suitel
        ifelsestmtc ::= testexpr c_stmts_opt ja_cf_pop    else_suitec

        # Semantic actions want suite_stmts_opt to be at index 3
        with        ::= expr setupwith SETUP_FINALLY suite_stmts_opt
                        POP_BLOCK LOAD_CONST COME_FROM WITH_CLEANUP END_FINALLY

        # Semantic actions want store to be at index 2
        withasstmt ::= expr setupwithas store suite_stmts_opt
                       POP_BLOCK LOAD_CONST COME_FROM WITH_CLEANUP END_FINALLY

        # This is truly weird. 2.7 does this (not including POP_TOP) with
        # opcode SETUP_WITH

        setupwith     ::= DUP_TOP LOAD_ATTR ROT_TWO LOAD_ATTR CALL_FUNCTION_0 POP_TOP
        setupwithas   ::= DUP_TOP LOAD_ATTR ROT_TWO LOAD_ATTR CALL_FUNCTION_0 setup_finally

        setup_finally ::= STORE_FAST SETUP_FINALLY LOAD_FAST DELETE_FAST
        setup_finally ::= STORE_NAME SETUP_FINALLY LOAD_NAME DELETE_NAME

        while1stmt     ::= SETUP_LOOP l_stmts_opt come_from_opt JUMP_BACK _come_froms

        # Sometimes JUMP_BACK is misclassified as CONTINUE.
        # workaround until we have better control flow in place
        while1stmt     ::= SETUP_LOOP l_stmts_opt CONTINUE _come_froms

        whilestmt      ::= SETUP_LOOP testexpr l_stmts_opt jb_pop POP_BLOCK _come_froms
        whilestmt      ::= SETUP_LOOP testexpr l_stmts_opt jb_cf_pop bp_come_from
        whilestmt      ::= SETUP_LOOP testexpr l_stmts_opt jb_cf_pop POP_BLOCK
        whilestmt      ::= SETUP_LOOP testexpr returns POP_BLOCK COME_FROM

        # In the "whilestmt" below, there isn't a COME_FROM when the
        # "while" is the last thing in the module or function.

        whilestmt      ::= SETUP_LOOP testexpr returns POP_TOP POP_BLOCK

        whileelsestmt  ::= SETUP_LOOP testexpr l_stmts_opt jb_pop POP_BLOCK
                           else_suitel COME_FROM
        while1elsestmt ::= SETUP_LOOP l_stmts JUMP_BACK else_suitel COME_FROM

        return         ::= ret_expr RETURN_END_IF POP_TOP
        return         ::= ret_expr RETURN_VALUE POP_TOP
        return_if_stmt ::= ret_expr RETURN_END_IF POP_TOP

        iflaststmtl ::= testexpr c_stmts_opt jb_cf_pop
        iflaststmt  ::= testexpr c_stmts_opt JUMP_ABSOLUTE come_from_pop

        lastc_stmt ::= iflaststmt come_froms

        ifstmt         ::= testexpr_then _ifstmts_jump

        # Semantic actions want the else to be at position 3
        ifelsestmt     ::= testexpr_then c_stmts_opt jf_cf_pop else_suite come_froms
        ifelsestmt     ::= testexpr_then c_stmts_opt filler else_suitel come_froms POP_TOP
        ifelsestmt     ::= testexpr c_stmts_opt jf_cf_pop else_suite

        # We have no jumps to jumps, so no "come_froms" but a single "COME_FROM"
        ifelsestmt     ::= testexpr      c_stmts_opt jf_cf_pop else_suite COME_FROM

        # Semantic actions want else_suitel to be at index 3
        ifelsestmtl    ::= testexpr_then c_stmts_opt jb_cf_pop else_suitel
        ifelsestmtc    ::= testexpr_then c_stmts_opt ja_cf_pop else_suitec

        iflaststmt     ::= testexpr_then c_stmts_opt JUMP_ABSOLUTE come_froms POP_TOP
        iflaststmt     ::= testexpr      c_stmts_opt JUMP_ABSOLUTE come_froms POP_TOP

        # "if"/"else" statement that ends in a RETURN
        ifelsestmtr    ::= testexpr_then return_if_stmts returns

        testexpr_then  ::= testtrue_then
        testexpr_then  ::= testfalse_then
        testtrue_then  ::= expr jmp_true_then
        testfalse_then ::= expr jmp_false_then

        jmp_false_then ::= JUMP_IF_FALSE THEN POP_TOP
        jmp_true_then  ::= JUMP_IF_TRUE THEN POP_TOP

        # In the "while1stmt" below, there sometimes isn't a
        # "COME_FROM" when the "while1" is the last thing in the
        # module or function.

        while1stmt ::= SETUP_LOOP returns come_from_opt
        for_block  ::= returns _come_froms
        Nr
   )r   r   r
   r
   r   p_stmt26g   s    zPython26Parser.p_stmt26c             C   s   dS )a  
        list_for ::= expr for_iter store list_iter JUMP_BACK come_froms POP_TOP

        # The JUMP FORWARD below jumps to the JUMP BACK. It seems to happen
        # in rare cases that may have to with length of code
        # FIXME: we can add a reduction check for this

        list_for ::= expr for_iter store list_iter JUMP_FORWARD come_froms POP_TOP
                     COME_FROM JUMP_BACK

        list_for ::= expr for_iter store list_iter jb_cont

        # This is for a really funky:
        #   [  x for x in range(10) if x % 2 if x % 3 ]
        # the JUMP_ABSOLUTE is to the instruction after the last POP_TOP
        #  we have a reduction check for this

        list_for ::= expr for_iter store list_iter JUMP_ABSOLUTE come_froms
                     POP_TOP jb_pop

        list_iter  ::= list_if JUMP_BACK
        list_iter  ::= list_if JUMP_BACK COME_FROM POP_TOP
        list_comp  ::= BUILD_LIST_0 DUP_TOP
                       store list_iter del_stmt
        list_comp  ::= BUILD_LIST_0 DUP_TOP
	               store list_iter JUMP_BACK del_stmt
        lc_body    ::= LOAD_NAME expr LIST_APPEND
	lc_body    ::= LOAD_FAST expr LIST_APPEND

        comp_for ::= SETUP_LOOP expr for_iter store comp_iter jb_pb_come_from

        comp_body ::= gen_comp_body

        for_block ::= l_stmts_opt _come_froms POP_TOP JUMP_BACK

        # Make sure we keep indices the same as 2.7

        setup_loop_lf ::= SETUP_LOOP LOAD_FAST
        genexpr_func ::= setup_loop_lf FOR_ITER store comp_iter jb_pb_come_from
        genexpr_func ::= setup_loop_lf FOR_ITER store comp_iter JUMP_BACK come_from_pop
                         jb_pb_come_from

        # This is for a really funky:
        #   (x for x in range(10) if x % 2 if x % 3 )
        # the JUMP_ABSOLUTE is to the instruction after the last POP_TOP.
        # Add a reduction check for this?

        genexpr_func ::= setup_loop_lf FOR_ITER store comp_iter JUMP_ABSOLUTE come_froms
                         POP_TOP jb_pop jb_pb_come_from

        genexpr_func ::= setup_loop_lf FOR_ITER store comp_iter JUMP_BACK come_froms
                         POP_TOP jb_pb_come_from

        generator_exp ::= LOAD_GENEXPR MAKE_FUNCTION_0 expr GET_ITER CALL_FUNCTION_1 COME_FROM
        list_if ::= expr jmp_false_then list_iter
        Nr
   )r   r   r
   r
   r   p_comp26   s    zPython26Parser.p_comp26c             C   s   dS )a  
        ret_and      ::= expr jmp_false ret_expr_or_cond COME_FROM
        ret_or       ::= expr jmp_true ret_expr_or_cond COME_FROM
        if_exp_ret   ::= expr jmp_false_then expr RETURN_END_IF POP_TOP ret_expr_or_cond
        if_exp_ret   ::= expr jmp_false_then expr ret_expr_or_cond

        return_if_stmt ::= ret_expr RETURN_END_IF POP_TOP
        return ::= ret_expr RETURN_VALUE POP_TOP

        # FIXME: split into Python 2.5
        ret_or   ::= expr jmp_true ret_expr_or_cond come_froms
        Nr
   )r   r   r
   r
   r   p_ret26  s    zPython26Parser.p_ret26c             C   s   dS )z>
        except_suite ::= c_stmts_opt jmp_abs POP_TOP
        Nr
   )r   r   r
   r
   r   
p_except26  s    zPython26Parser.p_except26c             C   s   dS )a	  
        dict ::= BUILD_MAP kvlist
        kvlist ::= kvlist kv3

        # Note: preserve positions 0 2 and 4 for semantic actions
        if_exp_not         ::= expr jmp_true  expr jf_cf_pop expr COME_FROM
        if_exp             ::= expr jmp_false expr jf_cf_pop expr come_from_opt
        if_exp             ::= expr jmp_false expr ja_cf_pop expr

        expr               ::= if_exp_not

        and                ::= expr JUMP_IF_FALSE POP_TOP expr JUMP_IF_FALSE POP_TOP

        # compare_chained is like x <= y <= z
        compare_chained    ::= expr compare_chained1 ROT_TWO COME_FROM POP_TOP _come_froms
        compare_chained1   ::= expr DUP_TOP ROT_THREE COMPARE_OP
                               jmp_false compare_chained1 _come_froms
        compare_chained1   ::= expr DUP_TOP ROT_THREE COMPARE_OP
                               jmp_false compare_chained2 _come_froms

        compare_chained1   ::= expr DUP_TOP ROT_THREE COMPARE_OP
                               jmp_false_then compare_chained1 _come_froms
        compare_chained1   ::= expr DUP_TOP ROT_THREE COMPARE_OP
                               jmp_false_then compare_chained2 _come_froms

        return_lambda      ::= RETURN_VALUE
        return_lambda      ::= RETURN_END_IF
        return_lambda      ::= RETURN_END_IF_LAMBDA
        return_lambda      ::= RETURN_VALUE_LAMBDA

        compare_chained2   ::= expr COMPARE_OP return_lambda

        return_if_lambda   ::= RETURN_END_IF_LAMBDA POP_TOP
        stmt               ::= if_exp_lambda
        stmt               ::= if_exp_not_lambda
        if_exp_lambda      ::= expr jmp_false_then expr return_if_lambda
                               return_stmt_lambda LAMBDA_MARKER
        if_exp_not_lambda ::=
                               expr jmp_true_then expr return_if_lambda
                               return_stmt_lambda LAMBDA_MARKER

        # if_exp_true are for conditions which always evaluate true
        # There is dead or non-optional remnants of the condition code though,
        # and we use that to match on to reconstruct the source more accurately
        expr               ::= if_exp_true
        if_exp_true        ::= expr jf_pop expr COME_FROM

        # This comes from
        #   0 or max(5, 3) if 0 else 3
        # where there seems to be an additional COME_FROM at the
        # end. Not sure if this is appropriately named or
        # is the best way to handle
        expr               ::= if_exp_false
        if_exp_false  ::= if_exp COME_FROM

        Nr
   )r   r   r
   r
   r   p_misc26  s    zPython26Parser.p_misc26c                sf   | j d tt| j|| d| jd< d| jd< d| jd< d| jd< d| jd< d| jd	< d| jd
< d S )Nz
        withasstmt ::= expr SETUP_WITH store suite_stmts_opt
                POP_BLOCK LOAD_CONST COME_FROM_WITH
                WITH_CLEANUP END_FINALLY
        ASTandassert_expr_andtokensifstmtZ
ifelsestmtlist_for
try_excepttryelsestmt)Zremove_rulesr   r   customize_grammar_rulesZcheck_reduce)r   r   Z	customize)r	   r
   r   r   R  s    





z&Python26Parser.customize_grammar_rulesc          
      s  t t| j|||||}|s$|d kr(|S |d+kr|d d kr@d	S | jd
kr^|d d dkr^dS |}x|| jdkr||d7 }qdW || jjdrd	S |d d }|j|j d }	|	|| jkp|| j|jk S |d-kr:x\t	|d |d d.D ]D}
||
 }|dkr$|j|t
|t|d  j kS |d/k rP  qW nJ|d1kr\|d j}|| j|kS |d dkr|t|kr|d8 }|| dkr||d  dkr|d8 }|| dkr||d  d kr||d  dkr||d  jtd2kp||d  dko||d  jdkS nj|d d"kr|d d#kr|d }|d dkrt|d j}|t|krp|d8 }|| dkrtrt|| jjd$d }||kS |t|kr|d8 }x2||d  dkr||d  dkr|d8 }qW || dkr||d  dkr|d8 }|| dkr||d  d kr||d  dkr||d  jtd3ko||d  dkp||d  jdkS d	S )4Nr   expr	jmp_false\e_come_from_optcome_from_optr   assert_expr   Fg@   r   Z
if_exp_notT	COME_FROMZJUMP_IF   r   testexpr_ifstmts_jump   JUMP_FORWARDPOP_TOPr   for_iterstore	list_iterJUMP_ABSOLUTE
come_fromsjb_popr   END_FINALLYRETURN_VALUEr   except_handler_r   r   r   r   r   r5   r   r   r   r    r   r7   r!   r   r   r   r9   )r6   r8   r:   r&   r'   )r   r;   )r*   r$   r   r+   r,   r-   r.   r/   r*   r0   )r   r=   )r)   r2   )r)   r2   )r   r   reduce_is_invalidversionkind
startswithoffsetattrZpattrrangeminlenZoff2int	frozensetint
isinstancesplit)r   Zruleastr   firstlastinvalidZ
test_indexr   Z
jmp_targetitZja_attrr3   Z
else_startZlast_offset)r	   r
   r   r>   a  s    

  

 
  
 (	& $z Python26Parser.reduce_is_invalid)__name__
__module____qualname__PARSER_DEFAULT_DEBUGr   r   r   r   r   r   r   r   r   r>   __classcell__r
   r
   )r	   r   r   
   s   2%d::r   c               @   s   e Zd ZdS )Python26ParserSingleN)rQ   rR   rS   r
   r
   r
   r   rV     s   rV   __main__)PYTHON_VERSIONIS_PYPYg@)get_scannerzJUMP_BACK CONTINUE RETURN_END_IF COME_FROM
               LOAD_GENEXPR LOAD_ASSERT LOAD_SETCOMP LOAD_DICTCOMP
               LAMBDA_MARKER RETURN_LAST
            Nc             C   s   g | ]}t jd d|qS )z_\d+$ )resub).0rP   r
   r
   r   
<listcomp>  s    r_   c             C   s   g | ]}t jd d|qS )z_CONT$r[   )r\   r]   )r^   rP   r
   r
   r   r_     s    )"__doc__Zuncompyle6.parserr   Zspark_parserr   rT   Zuncompyle6.parsers.parse2r   r   rV   rQ   pZcheck_grammar
uncompyle6rX   rY   Z
check_setslhsrhsr   Zright_recursiveZdup_rhsZuncompyle6.scannerrZ   ssetZopcopnameunionrJ   Z
opcode_setZremain_tokensr\   printr
   r
   r
   r   <module>   s0      S


