3
/*^n                 @   s   d Z ddlmZ ddlmZmZmZ ddlmZm	Z	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re Zej  dS )ae  
Base grammar for Python 2.x.

However instead of terminal symbols being the usual ASCII text,
e.g. 5, myvariable, "for", etc.  they are CPython Bytecode tokens,
e.g. "LOAD_CONST 5", "STORE NAME myvariable", "SETUP_LOOP", etc.

If we succeed in creating a parse tree, then we have a Python program
that a later phase can turn into a sequence of ASCII text.
    )print_function)except_handler_else
ifelsestmttryelsestmt)PythonParserPythonParserSinglenop_func)
SyntaxTree)DEFAULT_DEBUGc                   sh   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dd Zdd Z  ZS )Python2Parserc                s"   t t| jtd|d t | _d S )NZstmts)debug)superr   __init__r	   setZ	new_rules)selfZdebug_parser)	__class__ V/home/psgendb/BIRCHDEV/python/lib/python3.6/site-packages/uncompyle6/parsers/parse2.pyr   %   s    zPython2Parser.__init__c             C   s   dS )a  
        stmt ::= print_items_stmt
        stmt ::= print_nl
        stmt ::= print_items_nl_stmt

        print_items_stmt ::= expr PRINT_ITEM print_items_opt
        print_items_nl_stmt ::= expr PRINT_ITEM print_items_opt PRINT_NEWLINE_CONT
        print_items_opt ::= print_items?
        print_items     ::= print_item+
        print_item      ::= expr PRINT_ITEM_CONT
        print_nl        ::= PRINT_NEWLINE
        Nr   )r   argsr   r   r   p_print2)   s    zPython2Parser.p_print2c             C   s   dS )a  
        stmt ::= print_to
        stmt ::= print_to_nl
        stmt ::= print_nl_to
        print_to ::= expr print_to_items POP_TOP
        print_to_nl ::= expr print_to_items PRINT_NEWLINE_TO
        print_nl_to ::= expr PRINT_NEWLINE_TO
        print_to_items ::= print_to_items print_to_item
        print_to_items ::= print_to_item
        print_to_item ::= DUP_TOP expr ROT_TWO PRINT_ITEM_TO
        Nr   )r   r   r   r   r   
p_print_to7   s    zPython2Parser.p_print_toc             C   s   dS )a  
        sstmt ::= stmt
        sstmt ::= return RETURN_LAST

        return_if_stmts ::= return_if_stmt
        return_if_stmts ::= _stmts return_if_stmt
        return_if_stmt ::= ret_expr RETURN_END_IF

        return_stmt_lambda ::= ret_expr RETURN_VALUE_LAMBDA

        stmt      ::= break
        break     ::= BREAK_LOOP

        stmt      ::= continue
        continue  ::= CONTINUE
        continues ::= _stmts lastl_stmt continue
        continues ::= lastl_stmt continue
        continues ::= continue

        stmt ::= assert2
        stmt ::= raise_stmt0
        stmt ::= raise_stmt1
        stmt ::= raise_stmt2
        stmt ::= raise_stmt3

        raise_stmt0 ::= RAISE_VARARGS_0
        raise_stmt1 ::= expr RAISE_VARARGS_1
        raise_stmt2 ::= expr expr RAISE_VARARGS_2
        raise_stmt3 ::= expr expr expr RAISE_VARARGS_3

        for         ::= SETUP_LOOP expr for_iter store
                        for_block POP_BLOCK _come_froms

        del_stmt         ::= delete_subscript
        delete_subscript ::= expr expr DELETE_SUBSCR
        del_stmt         ::= expr DELETE_ATTR

        _mklambda ::= load_closure mklambda
        kwarg     ::= LOAD_CONST expr

        kv3 ::= expr expr STORE_MAP

        classdef ::= buildclass store

        buildclass ::= LOAD_CONST expr mkfunc
                     CALL_FUNCTION_0 BUILD_CLASS

        # Class decorators starting in 2.6
        stmt ::= classdefdeco
        classdefdeco ::= classdefdeco1 store
        classdefdeco1 ::= expr classdefdeco1 CALL_FUNCTION_1
        classdefdeco1 ::= expr classdefdeco2 CALL_FUNCTION_1
        classdefdeco2 ::= LOAD_CONST expr mkfunc CALL_FUNCTION_0 BUILD_CLASS

        assert_expr ::= expr
        assert_expr ::= assert_expr_or
        assert_expr ::= assert_expr_and
        assert_expr_or ::= assert_expr jmp_true expr
        assert_expr_and ::= assert_expr jmp_false expr

        ifstmt ::= testexpr _ifstmts_jump

        testexpr ::= testfalse
        testexpr ::= testtrue
        testfalse ::= expr jmp_false
        testtrue ::= expr jmp_true

        _ifstmts_jump ::= return_if_stmts

        iflaststmt  ::= testexpr c_stmts_opt JUMP_ABSOLUTE
        iflaststmtl ::= testexpr c_stmts_opt JUMP_BACK

        # this is nested inside a try_except
        tryfinallystmt  ::= SETUP_FINALLY suite_stmts_opt
                            POP_BLOCK LOAD_CONST
                            COME_FROM suite_stmts_opt END_FINALLY

        lastc_stmt ::= tryelsestmtc

        # Move to 2.7? 2.6 may use come_froms
        tryelsestmtc    ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
                            except_handler_else else_suitec COME_FROM

        tryelsestmtl    ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
                            except_handler_else else_suitel COME_FROM

        try_except      ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
                            except_handler COME_FROM

        # Note: except_stmts may have many jumps after END_FINALLY
        except_handler  ::= JUMP_FORWARD COME_FROM except_stmts
                            END_FINALLY come_froms

        except_handler  ::= jmp_abs COME_FROM except_stmts
                             END_FINALLY

        except_handler_else  ::= except_handler

        except_stmts ::= except_stmt+

        except_stmt ::= except_cond1 except_suite
        except_stmt ::= except

        except_suite ::= c_stmts_opt JUMP_FORWARD
        except_suite ::= c_stmts_opt jmp_abs
        except_suite ::= returns

        except  ::=  POP_TOP POP_TOP POP_TOP c_stmts_opt _jump
        except  ::=  POP_TOP POP_TOP POP_TOP returns

        jmp_abs ::= JUMP_ABSOLUTE
        jmp_abs ::= JUMP_BACK
        jmp_abs ::= CONTINUE
        Nr   )r   r   r   r   r   	p_grammarD   s    zPython2Parser.p_grammarc             C   s   dS )z^
        generator_exp ::= LOAD_GENEXPR MAKE_FUNCTION_0 expr GET_ITER CALL_FUNCTION_1
        Nr   )r   r   r   r   r   p_generator_exp2   s    zPython2Parser.p_generator_exp2c             C   s   dS )a  
        expr ::= LOAD_LOCALS
        expr ::= LOAD_ASSERT
        expr ::= slice0
        expr ::= slice1
        expr ::= slice2
        expr ::= slice3
        expr ::= unary_convert

        expr_jt  ::= expr jmp_true
        or       ::= expr_jt  expr come_from_opt
        and      ::= expr jmp_false expr come_from_opt

        unary_convert ::= expr UNARY_CONVERT

        # In Python 3, DUP_TOPX_2 is DUP_TOP_TWO
        subscript2 ::= expr expr DUP_TOPX_2 BINARY_SUBSCR
        Nr   )r   r   r   r   r   p_expr2   s    zPython2Parser.p_expr2c             C   s   dS )a  
        store ::= expr STORE_SLICE+0
        store ::= expr expr STORE_SLICE+1
        store ::= expr expr STORE_SLICE+2
        store ::= expr expr expr STORE_SLICE+3

        aug_assign1 ::= expr expr inplace_op ROT_FOUR  STORE_SLICE+3
        aug_assign1 ::= expr expr inplace_op ROT_THREE STORE_SLICE+1
        aug_assign1 ::= expr expr inplace_op ROT_THREE STORE_SLICE+2
        aug_assign1 ::= expr expr inplace_op ROT_TWO   STORE_SLICE+0

        slice0 ::= expr SLICE+0
        slice0 ::= expr DUP_TOP SLICE+0
        slice1 ::= expr expr SLICE+1
        slice1 ::= expr expr DUP_TOPX_2 SLICE+1
        slice2 ::= expr expr SLICE+2
        slice2 ::= expr expr DUP_TOPX_2 SLICE+2
        slice3 ::= expr expr expr SLICE+3
        slice3 ::= expr expr expr DUP_TOPX_3 SLICE+3
        Nr   )r   r   r   r   r   p_slice2   s    zPython2Parser.p_slice2c             C   s   dS )zZ
        inplace_op ::= INPLACE_DIVIDE
        binary_operator  ::= BINARY_DIVIDE
        Nr   )r   r   r   r   r   p_op2   s    zPython2Parser.p_op2c             C   s  d|kr| j dt td~}t }xpt|D ]b\}}|j}|d|jd |ks.||kr^q.|d|jd }|dkr4|j}	|	d }
|	d d }|dkrddd  }| j	|||	| |
dkr| j	ddd  ||	| ||jdd d j
 }d| d|
  d |  d!|	d   | }| jd"| |g| q.nR|d#kr|d$krx| jd%d&d'g| | jd(kr| j	d)d*d| q.d+|j }d,||f }| j |t q.n|d-kr|j}|d.kr| jd/d0g| q.|d1kstd2| | jd3d4g| q.n|dkrH| j|\}}t|td5 d1 }d9d!|  d:|  d!|  | }n>|d;kr| j|\}}t|td; d1 }d9d!|  d:|  d!|  | }n|d<kr| j d=t |j| q.n|d>kr| j d?t |j| q.n|jd@r| j dAt |j| dB| jdC< q.np|dDkr<| j dEt |j| q.nJ|dFkrl| j dGt dB| jdH< |j| q.n|dIkr| j dJt |j| q.n|dkrq.n|dMkr| j dNt q.n|dOkr| j dPt q.n|dQkr | j dRt |j| q.n|dSkr&| j dTt |j| q.n`|dUkrP| jdVdWg| |j| q.n6|dXkrv| j dYt |j| q.n|dZkr|dkr||d  d[kr| j d\d]|j |f t d^d!|j |f }n|d_kr|dkr||d  d[kr| j d`d!|j |f t |dkrH||d  }|dakrH| jdbd!|j |f g| | jdcd!|j |f g| | jd(kr.|dkr.||d  }|ddkr| jded!|j |f g| q.|dUkr.| jdVdfd!|j |f g| q.n|dgkrd|kr| jdhdidjg| |j| q.n~|dkkr6d|kr(| j dlt |j| q.nP|dkr^|j| do| dp|j  }n(|dqkr.|j| dr| dp|j  }nq.| j |t q.W ttttds| _dB| jdt< du| jdv< du| jdw< dB| jdx< dB| jdy< dB| jdz< dB| jd{< dB| jd|< du| jd}< dS )a  The base grammar we start out for a Python version even with the
        subclassing is, well, is pretty base.  And we want it that way: lean and
        mean so that parsing will go faster.

        Here, we add additional grammar rules based on specific instructions
        that are in the instruction/token stream. In classes that
        inherit from from here and other versions, grammar rules may
        also be removed.

        For example if we see a pretty rare JUMP_IF_NOT_DEBUG
        instruction we'll add the grammar for that.

        More importantly, here we add grammar rules for instructions
        that may access a variable number of stack items. CALL_FUNCTION,
        BUILD_LIST and so on are like this.

        Without custom rules, there can be an super-exponential number of
        derivations. See the deparsing paper for an elaboration of
        this.
        PyPya  
                        stmt ::= assign3_pypy
                        stmt ::= assign2_pypy
                        assign3_pypy ::= expr expr expr store store store
                        assign2_pypy ::= expr expr store store
                        list_comp    ::= expr  BUILD_LIST_FROM_ARG for_iter store list_iter
                                         JUMP_BACK
                        BUILDCALLCONTINUEDELETEDUPEXECGETJUMPLOADLOOKUPMAKESETUPRAISEUNPACKN_
BUILD_LIST	BUILD_SETBUILD_TUPLEi       r   zexpr32 ::=%sz exprzexpr1024 ::=%sz expr32   z%s ::= z	expr1024 zexpr32 zexpr zexpr ::= %s	BUILD_MAPZBUILD_MAP_nzkvlist_n ::=  kvlist_n kv3zkvlist_n ::=zdict ::= BUILD_MAP_n kvlist_ng@zddict_comp_func ::= BUILD_MAP_n LOAD_FAST FOR_ITER store comp_iter JUMP_BACK RETURN_VALUE RETURN_LASTZdict_comp_funcz kv3zdict ::= %s%sBUILD_SLICE   zexpr ::= build_slice2z(build_slice2 ::= expr expr BUILD_SLICE_2   z'BUILD_SLICE value must be 2 or 3; is %szexpr ::= build_slice3z-build_slice3 ::= expr expr expr BUILD_SLICE_3CALL_FUNCTIONCALL_FUNCTION_VARCALL_FUNCTION_VAR_KWCALL_FUNCTION_KWzcall ::= expr zkwarg ZCALL_METHODCONTINUE_LOOPzcontinue ::= CONTINUE_LOOPDELETE_ATTRzdel_stmt ::= expr DELETE_ATTRZDELETE_SLICEa+  
                del_expr ::= expr
                del_stmt ::= del_expr DELETE_SLICE+0
                del_stmt ::= del_expr del_expr DELETE_SLICE+1
                del_stmt ::= del_expr del_expr DELETE_SLICE+2
                del_stmt ::= del_expr del_expr del_expr DELETE_SLICE+3
                ASTdel_exprDELETE_DEREFz|
                   stmt           ::= del_deref_stmt
                   del_deref_stmt ::= DELETE_DEREF
                   DELETE_SUBSCRz
                    del_stmt ::= delete_subscript
                    delete_subscript ::= expr expr DELETE_SUBSCR
                   delete_subscriptGET_ITERzp
                    expr      ::= get_iter
                    attribute ::= expr GET_ITER
                    DUP_TOPXRAISE_VARARGSZ	EXEC_STMTz
                    stmt      ::= exec_stmt
                    exec_stmt ::= expr exprlist DUP_TOP EXEC_STMT
                    exec_stmt ::= expr exprlist EXEC_STMT
                    exprlist  ::= expr+
                    ZJUMP_IF_NOT_DEBUGaN  
                    jmp_true_false ::= POP_JUMP_IF_TRUE
                    jmp_true_false ::= POP_JUMP_IF_FALSE
                    stmt ::= assert_pypy
                    stmt ::= assert2_pypy
                    assert_pypy  ::= JUMP_IF_NOT_DEBUG assert_expr jmp_true_false
                                     LOAD_ASSERT RAISE_VARARGS_1 COME_FROM
                    assert2_pypy ::= JUMP_IF_NOT_DEBUG assert_expr jmp_true_false
                                     LOAD_ASSERT expr CALL_FUNCTION_1
                                     RAISE_VARARGS_1 COME_FROM
                     	LOAD_ATTRzl
                  expr      ::= attribute
                  attribute ::= expr LOAD_ATTR
                  ZLOAD_LISTCOMPzexpr ::= listcompZLOAD_SETCOMPzexpr ::= set_compzGset_comp ::= LOAD_SETCOMP MAKE_FUNCTION_0 expr GET_ITER CALL_FUNCTION_1ZLOOKUP_METHODz
                             expr      ::= attribute
                             attribute ::= expr LOOKUP_METHOD
                             MAKE_FUNCTIONZLOAD_LAMBDAzmklambda ::= %s LOAD_LAMBDA %szpos_arg zmkfunc ::= %s LOAD_CODE %sZMAKE_CLOSUREz+mklambda ::= %s load_closure LOAD_LAMBDA %sZLOAD_GENEXPRzOgenerator_exp ::= %s load_closure LOAD_GENEXPR %s expr GET_ITER CALL_FUNCTION_1z'mkfunc ::= %s load_closure LOAD_CODE %sZLOAD_DICTCOMPzLdict_comp ::= %s load_closure LOAD_DICTCOMP %s expr GET_ITER CALL_FUNCTION_1zJset_comp ::= %s load_closure LOAD_SETCOMP %s expr GET_ITER CALL_FUNCTION_1SETUP_EXCEPTzstmt ::= try_except_pypyzDtry_except_pypy ::= SETUP_EXCEPT suite_stmts_opt except_handler_pypyzDexcept_handler_pypy ::= COME_FROM except_stmts END_FINALLY COME_FROMSETUP_FINALLYz
                        stmt ::= tryfinallystmt_pypy
                        tryfinallystmt_pypy ::= SETUP_FINALLY suite_stmts_opt COME_FROM_FINALLY
                                                suite_stmts_opt END_FINALLYUNPACK_TUPLEUNPACK_SEQUENCEzunpack ::= z storeZUNPACK_LISTzunpack_list ::= )r   r   r   tryelsestmtlandtokensr   raise_stmt1assert_expr_andr   rI   aug_assign2orZifstmt)r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   )r,   r-   r.   )r5   r6   r7   r8   )rA   rB   )rG   rH   )ZaddRuler   	frozensetr   	enumeratekindfindrfindattrZadd_unique_rulelowerZadd_unique_rulesversionAssertionErrorZ
get_pos_kwlenadd
startswithZcheck_reducer   r   r   reduce_check_table)r   rK   Z	customizeZcustomize_instruction_basenamesZcustom_seen_opsitokenopnameZopname_baseZbuild_countZ	thousandsZ	thirty32sruleZ
collectionZkvlist_nZ	slice_numZargs_posZargs_kwZnakZprev_tokr   r   r   customize_grammar_rules   s                	

(





   $
$
















































z%Python2Parser.customize_grammar_rulesc          	   C   s  |d krdS |d }t |}| jj|d }|rH|| |||||||rHdS |dkr|| dkr`dS |d	 }	|	d d
krx$||k rt|| jtr|d	8 }qvW |	d j|| jk rdS |d	 d }	|	j|	j d }
|
|| jkp|| j|	jk S |dkr|d r|d d dkrdS |dkrD|d	 }	|	d j}||| j kS |dkrh|| dkof|t |kS |dkr|d }|dko|d dkS |dkr|d d }|j	dkS dS )NFr   TrJ   expr	jmp_false\e_come_from_optYIELD_VALUEr0   POP_JUMP_IF_FALSEr4   aug_assign1rN   rO   rM   rL   ZLOAD_ASSERTjmp_truer3   r?   r<   rb   rc   rb   rd   )rJ   ri   )rg   rN   )rJ   rO   )rL   rb   rh   rb   rd   )rO   rj   )r?   r<   )rJ   rO   )
rY   r\   get
isinstanceoffsetstrrU   ZpattrZoff2intrR   )r   r`   astrK   firstlastlhsnfnrc   Z
jmp_targetZjump_targetZexpr2opr   r   r   reduce_is_invalid  sL    







zPython2Parser.reduce_is_invalid)__name__
__module____qualname__PARSER_DEFAULT_DEBUGr   r   r   r   r   r   r   r   ra   rv   __classcell__r   r   )r   r   r   $   s   t   1r   c               @   s   e Zd ZdS )Python2ParserSingleN)rw   rx   ry   r   r   r   r   r|     s   r|   __main__N)__doc__
__future__r   Zuncompyle6.parsers.reducecheckr   r   r   Zuncompyle6.parserr   r   r   Zuncompyle6.parsers.treenoder	   Zspark_parserr
   rz   r   r|   rw   pZcheck_grammarr   r   r   r   <module>   s        9