3
/*^<                 @   s.  d dl mZ d dlmZ d dlmZmZ d dlm	Z	 d dl
mZmZ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 )    )DEFAULT_DEBUG)next_offset)PythonParserSinglenop_func)Python2Parser)or_check
ifelsestmttryelsestmtc                   sX   e Zd Zef f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 )Python27Parserc                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/parse27.pyr      s    zPython27Parser.__init__c             C   s   dS )aL  
        list_for  ::= expr for_iter store list_iter JUMP_BACK
        list_comp ::= BUILD_LIST_0 list_iter
        lc_body   ::= expr LIST_APPEND
        for_iter  ::= GET_ITER COME_FROM FOR_ITER

        stmt ::= set_comp_func


        # Dictionary and set comprehensions were added in Python 2.7
        expr      ::= dict_comp
        dict_comp ::= LOAD_DICTCOMP MAKE_FUNCTION_0 expr GET_ITER CALL_FUNCTION_1

        stmt           ::= dict_comp_func
        dict_comp_func ::= BUILD_MAP_0 LOAD_FAST FOR_ITER store
                           comp_iter JUMP_BACK RETURN_VALUE RETURN_LAST

        set_comp_func ::= BUILD_SET_0 LOAD_FAST FOR_ITER store comp_iter
                          JUMP_BACK RETURN_VALUE RETURN_LAST

        comp_iter     ::= comp_if_not
        comp_if_not   ::= expr jmp_true comp_iter

        comp_body ::= dict_comp_body
        comp_body ::= set_comp_body
        comp_for ::= expr for_iter store comp_iter JUMP_BACK

        dict_comp_body ::= expr expr MAP_ADD
        set_comp_body ::= expr SET_ADD

        # See also common Python p_list_comprehension
        Nr   )r   argsr   r   r   p_comprehension27   s    z Python27Parser.p_comprehension27c             C   s   dS )a7  
        # If the last except is a "raise" we might not have a final COME_FROM
        # FIXME: need a check on this rule since this accepts try_except when
        # we shouldn't
        try_except      ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
                            except_handler

        tryfinallystmt ::= SETUP_FINALLY suite_stmts_opt
                           POP_BLOCK LOAD_CONST
                           COME_FROM_FINALLY suite_stmts_opt END_FINALLY

        tryelsestmt    ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
                           except_handler_else else_suite COME_FROM

        tryelsestmtl   ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
                           except_handler_else else_suitel JUMP_BACK COME_FROM

        tryelsestmtl   ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
                           except_handler_else else_suitel
        tryelsestmtc   ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
                           except_handler_else else_suitec COME_FROM

        except_stmt ::= except_cond2 except_suite

        except_cond1 ::= DUP_TOP expr COMPARE_OP
                         jmp_false POP_TOP POP_TOP POP_TOP

        except_cond2 ::= DUP_TOP expr COMPARE_OP
                         jmp_false POP_TOP store POP_TOP

        for_block    ::= l_stmts_opt JUMP_BACK

        Nr   )r   r   r   r   r   p_try277   s    zPython27Parser.p_try27c             C   s   dS )ab  
        iflaststmtl     ::= testexpr c_stmts

        _ifstmts_jump   ::= c_stmts_opt JUMP_FORWARD come_froms
        bp_come_from    ::= POP_BLOCK COME_FROM

        # FIXME: Common with 3.0+
        jmp_false ::= POP_JUMP_IF_FALSE
        jmp_true  ::= POP_JUMP_IF_TRUE

        ret_and    ::= expr JUMP_IF_FALSE_OR_POP ret_expr_or_cond COME_FROM
        ret_or     ::= expr JUMP_IF_TRUE_OR_POP ret_expr_or_cond COME_FROM
        if_exp_ret ::= expr POP_JUMP_IF_FALSE expr RETURN_END_IF COME_FROM ret_expr_or_cond

        expr_jitop ::= expr JUMP_IF_TRUE_OR_POP
        or         ::= expr_jitop expr COME_FROM
        and        ::= expr JUMP_IF_FALSE_OR_POP expr COME_FROM

        # compare_chained{1,2} is used exclusively in chained_compare
        compare_chained1 ::= expr DUP_TOP ROT_THREE COMPARE_OP JUMP_IF_FALSE_OR_POP
                             compare_chained1 COME_FROM
        compare_chained1 ::= expr DUP_TOP ROT_THREE COMPARE_OP JUMP_IF_FALSE_OR_POP
                             compare_chained2 COME_FROM

        return_lambda      ::= RETURN_VALUE
        return_lambda      ::= RETURN_VALUE_LAMBDA

        compare_chained2 ::= expr COMPARE_OP return_lambda
        compare_chained2 ::= expr COMPARE_OP return_lambda

        # 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.
        # FIXME: we should do analysis and reduce *only* if there is dead code?
        #        right now we check that expr is "or". Any other nodes types?

        expr             ::= if_exp_true
        if_exp_true      ::= expr JUMP_FORWARD expr COME_FROM

        if_exp           ::= expr jmp_false expr JUMP_FORWARD expr COME_FROM
        if_exp           ::= expr jmp_false expr JUMP_ABSOLUTE expr
        Nr   )r   r   r   r   r   p_jump27Z   s    zPython27Parser.p_jump27c             C   s   dS )a)  
        stmt ::= ifelsestmtr

        # assert condition
        assert        ::= assert_expr jmp_true LOAD_ASSERT RAISE_VARARGS_1

        # assert condition, expr
        assert2    ::= assert_expr jmp_true LOAD_ASSERT expr CALL_FUNCTION_1 RAISE_VARARGS_1

        continue   ::= JUMP_BACK JUMP_ABSOLUTE

        for_block  ::= returns _come_froms

        with       ::= expr SETUP_WITH POP_TOP suite_stmts_opt
                       POP_BLOCK LOAD_CONST COME_FROM_WITH
                       WITH_CLEANUP END_FINALLY

        withasstmt ::= expr SETUP_WITH store suite_stmts_opt
                POP_BLOCK LOAD_CONST COME_FROM_WITH
                WITH_CLEANUP END_FINALLY

        whilestmt         ::= SETUP_LOOP testexpr returns
                              _come_froms POP_BLOCK COME_FROM


        # 2.7.5 (and before to 2.7.0?)
        while1stmt        ::= SETUP_LOOP l_stmts_opt JUMP_BACK COME_FROM
        while1stmt        ::= SETUP_LOOP l_stmts_opt CONTINUE COME_FROM
        while1stmt        ::= SETUP_LOOP returns COME_FROM
        while1elsestmt    ::= SETUP_LOOP l_stmts JUMP_BACK
                              else_suitel COME_FROM

        while1stmt        ::= SETUP_LOOP returns bp_come_from
        while1stmt        ::= SETUP_LOOP l_stmts_opt JUMP_BACK POP_BLOCK COME_FROM

        whilestmt         ::= SETUP_LOOP testexpr l_stmts_opt JUMP_BACK POP_BLOCK _come_froms

        # Should this be JUMP_BACK+ ?
        # JUMP_BACK should all be to the same location
        whilestmt         ::= SETUP_LOOP testexpr l_stmts_opt JUMP_BACK JUMP_BACK POP_BLOCK _come_froms

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

        return_stmts      ::= _stmts return_stmt
        return_stmts      ::= return_stmt
        return_stmt       ::= return

        ifstmt            ::= testexpr return_stmts COME_FROM
        ifstmt            ::= testexpr return_if_stmts COME_FROM
        ifelsestmt        ::= testexpr c_stmts_opt JUMP_FORWARD else_suite come_froms
        ifelsestmtc       ::= testexpr c_stmts_opt JUMP_ABSOLUTE else_suitec
        ifelsestmtl       ::= testexpr c_stmts_opt JUMP_BACK else_suitel
        ifelsestmtl       ::= testexpr c_stmts_opt CONTINUE else_suitel

        # In the future when we have ifelsestmtl checking we should add something like:
        # ifelsestmtl       ::= testexpr c_stmts_opt JUMP_FORWARD else_suite come_froms
        # c_stmts           ::= ifelsestmtl

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

        # Common with 2.6
        return_if_lambda   ::= RETURN_END_IF_LAMBDA COME_FROM
        stmt               ::= if_exp_lambda
        stmt               ::= if_exp_not_lambda
        if_exp_lambda      ::= expr jmp_false expr return_if_lambda
                               return_stmt_lambda LAMBDA_MARKER
        if_exp_not_lambda  ::= expr jmp_true expr return_if_lambda
                               return_stmt_lambda LAMBDA_MARKER

        expr               ::= if_exp_not
        if_exp_not         ::= expr jmp_true expr _jump expr COME_FROM

        kv3 ::= expr expr STORE_MAP
        Nr   )r   r   r   r   r   p_stmt27   s    zPython27Parser.p_stmt27c                s   | j d d|kr| jdt tt| j|| tttd| _d| j	d< d| j	d< d| j	d	< d| j	d
< d| j	d< d| j	d< d| j	d< d| j	d< d| j	d< d| j	d< d| j	d< d| j	d< d| j	d< d S )Na   
        while1elsestmt ::= SETUP_LOOP l_stmts JUMP_BACK else_suite COME_FROM
        tryfinallystmt ::= SETUP_FINALLY suite_stmts_opt
                           POP_BLOCK LOAD_CONST COME_FROM suite_stmts_opt
                           END_FINALLY
        PyPyzf
                        return_if_stmt ::= ret_expr RETURN_END_IF come_froms
                        )orr	   ZtryelsestmtlASTandif_exptokensZexcept_handlerZexcept_handler_elser   raise_stmt1iflaststmtlr   list_if_notlist_ifcomp_ifif_exp_true	whilestmt)
Zremove_rulesZaddRuler   r   r
   customize_grammar_rulesr   r	   reduce_check_tableZcheck_reduce)r   r   Z	customize)r   r   r   r#      s.    













z&Python27Parser.customize_grammar_rulesc          	      s^  t t| j|||||}|d }t|}| jj|d }	|	rP|	| |||||||}t||d }|rf|S |d*kr|d }
|
d dkr|| j|
d j  k o|| jk S   S n|d |d dd fd,kr"|d }
|
d dkrZ|d j	 }|
d j|jkrdS |d j}||| jk S n8|d dkrN|d dkoL|d d dkS |d d-kr|d d }|j}|t|kp||| jkp|t
|d. j|d/ j|d0 jk S |d2krx\t|d |d d3D ]D}|| }|dkr|j|t|t|d  j kS |d4krP qW n>|d6kr|d }|d d7krZ|d }t|dkrZ|d jjdrZ|d d j}|t|kr|d8 }x*t|| jtr||k r|d7 }qW ||krdS x*||k rt|| jtr|d8 }qW || j |  k o|| j k S   S n>|d9krR|d d }|j}||jkoP||| jk S |d;kr|d d }|j}||jko||| jk S |d=kr|d d }|j|j d }||| jkp|| j|jk S |d d"kr2|d dd> d?kr2|d }x|| d&kr|d8 }qW || j||d  jkS |d d'krZ|dkoX||d  dkS d(S )@Nr      r    expr	jmp_false	comp_iterPOP_JUMP_IF_FALSE   r   JUMP_ABSOLUTE   T   r   r   assertassert2ifstmttestexpr_ifstmts_jumpJUMP_FORWARDPOP_TOP	COME_FROMr   c_stmts	testfalsetesttrueZjmp_r   jmp_true	list_iterr   \e_come_from_optr"      
SETUP_LOOPl_stmts_opt	JUMP_BACKr!   Fr&   r'   r(   )r    r@   r&   r'   r&   r+   r&   )r   rA   )r.   r/   rB   rB   r1   r2   )r0   rC   rB   )r4   r5   r1   r6   )r   rD   )r7   r8   r&   r9   r:   )r   rE   r&   r'   r:   )r   rF   r&   r9   r&   r;   )r   rG   )r=   r1   r>   r?   r?   )r   r
   reduce_is_invalidlenr$   getminoffsetattrZfirst_childr   opopcrangeZoff2intkind
startswith
isinstancestrZpattr)r   Zruleastr   firstlastinvalidlhsnfnr'   Z
else_instrZ
end_offsetZ	jump_instZjump_targetitr1   testZ
jmp_targetZjump_offsetr9   )r   r   r   rI     s    

* 
$

 

 
*


 z Python27Parser.reduce_is_invalid)__name__
__module____qualname__PARSER_DEFAULT_DEBUGr   r   r   r   r   r#   rI   __classcell__r   r   )r   r   r
      s   "#,P+r
   c               @   s   e Zd ZdS )Python27ParserSingleN)r`   ra   rb   r   r   r   r   re   a  s   re   __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).0r^   r   r   r   
<listcomp>t  s   rn   c             C   s   g | ]}t jd d|qS )z_CONT$rj   )rk   rl   )rm   r^   r   r   r   rn   v  s   )(Zspark_parserr   rc   Zxdisr   Zuncompyle6.parserr   r   Zuncompyle6.parsers.parse2r   Zuncompyle6.parsers.reducecheckr   r   r	   r
   re   r`   pZcheck_grammar
uncompyle6rg   rh   Z
check_setsrZ   rhsr   Zright_recursiveZdup_rhsZuncompyle6.scannerri   ssetrP   opnameunionsplitZ
opcode_setZremain_tokensrk   printr   r   r   r   <module>   s4     T




