a
    lc8                     @   s   d Z ddlmZ ddlmZmZmZmZmZm	Z	 ddl
mZmZ edZG dd dee ZG dd	 d	ZG d
d dee ZG dd dZdd Zdd Zdd Zdd ZeedddZdd Zdd Zdd ZdS ) a  
This module defines the data structures used to represent a grammar.

Specifying grammars in pgen is possible with this grammar::

    grammar: (NEWLINE | rule)* ENDMARKER
    rule: NAME ':' rhs NEWLINE
    rhs: items ('|' items)*
    items: item+
    item: '[' rhs ']' | atom ['+' | '*']
    atom: '(' rhs ')' | NAME | STRING

This grammar is self-referencing.

This parser generator (pgen2) was created by Guido Rossum and used for lib2to3.
Most of the code has been refactored to make it more Pythonic. Since this was a
"copy" of the CPython Parser parser "pgen", there was some work needed to make
it more readable. It should also be slightly faster than the original pgen2,
because we made some optimizations.
    )literal_eval)TypeVarGenericMappingSequenceSetUnion)GrammarParserNFAState_TokenTypeTc                   @   s6   e Zd ZdZeeeed f eedf dddZdS )Grammara  
    Once initialized, this class supplies the grammar tables for the
    parsing engine implemented by parse.py.  The parsing engine
    accesses the instance variables directly.

    The only important part in this parsers are dfas and transitions between
    dfas.
    zDFAState[_TokenTypeT]ReservedString)start_nonterminalrule_to_dfasreserved_syntax_stringsc                 C   s   || _ || _|| _d S N)nonterminal_to_dfasr   r   )selfr   r   r    r   Q/var/www/html/django/DPS/env/lib/python3.9/site-packages/parso/pgen2/generator.py__init__/   s    zGrammar.__init__N)__name__
__module____qualname____doc__strr   r   r   r   r   r   r   r   %   s
   

r   c                   @   s0   e Zd ZdZg fded dddZdd ZdS )	DFAPlanzj
    Plans are used for the parser to create stack nodes and do the proper
    DFA state transitions.
    DFAStatenext_dfa
dfa_pushesc                 C   s   || _ || _d S r   r   )r   r   r    r   r   r   r   =   s    zDFAPlan.__init__c                 C   s   d| j j| j| jf S )Nz
%s(%s, %s))	__class__r   r   r    r   r   r   r   __repr__A   s    zDFAPlan.__repr__N)r   r   r   r   r   r   r#   r   r   r   r   r   8   s   r   c                   @   sF   e Zd ZdZeee edddZdd Zdd Z	d	d
 Z
dd ZdS )r   aa  
    The DFAState object is the core class for pretty much anything. DFAState
    are the vertices of an ordered graph while arcs and transitions are the
    edges.

    Arcs are the initial edges, where most DFAStates are not connected and
    transitions are then calculated to connect the DFA state machines that have
    different nonterminals.
    )	from_rulenfa_setfinalc                 C   s^   t |tsJ t tt|ts$J t |ts2J || _|| _i | _i | _i | _	||v | _
d S r   )
isinstancesetnextiterr
   r$   r%   arcsnonterminal_arcstransitionsis_final)r   r$   r%   r&   r   r   r   r   O   s    zDFAState.__init__c                 C   s8   t |tsJ || jvsJ t |ts*J || j|< d S r   )r'   r   r+   r   )r   next_labelr   r   r   add_arc`   s    zDFAState.add_arcc                 C   s*   | j  D ]\}}||u r
|| j |< q
d S r   )r+   items)r   oldnewr0   r/   r   r   r   
unifystatef   s    zDFAState.unifystatec                 C   sd   t |tsJ | j|jkrdS t| jt|jkr6dS | j D ]\}}||j|ur@ dS q@dS )NFT)r'   r   r.   lenr+   r2   get)r   otherr0   r/   r   r   r   __eq__k   s    zDFAState.__eq__c                 C   s   d| j j| j| jf S )Nz<%s: %s is_final=%s>)r!   r   r$   r.   r"   r   r   r   r#   y   s    zDFAState.__repr__N)r   r   r   r   r   r   r
   r   r1   r5   r9   r#   r   r   r   r   r   E   s   	r   c                   @   s&   e Zd ZdZedddZdd ZdS )r   z
    Most grammars will have certain keywords and operators that are mentioned
    in the grammar as strings (e.g. "if") and not token types (e.g. NUMBER).
    This class basically is the former.
    valuec                 C   s
   || _ d S r   r:   )r   r;   r   r   r   r      s    zReservedString.__init__c                 C   s   d| j j| jf S )Nz%s(%s))r!   r   r;   r"   r   r   r   r#      s    zReservedString.__repr__N)r   r   r   r   r   r   r#   r   r   r   r   r      s   r   c                 C   sp   d}|rld}t | D ]T\}}t|d t| D ]8}| | }||kr.| |= | D ]}||| qLd} qq.qqdS )a  
    This is not theoretically optimal, but works well enough.
    Algorithm: repeatedly look for two states that have the same
    set of arcs (same labels pointing to the same nodes) and
    unify them, until things stop changing.

    dfas is a list of DFAState instances
    TF   N)	enumerateranger6   r5   )dfaschangesiZstate_ijZstate_jstater   r   r   _simplify_dfas   s    	rD   c                    s   t | tsJ t |tsJ  fdd t } | | t| j||g}|D ]}i }|jD ]6}|jD ]*}|jdurd||jt } |j	| qdqZ|
 D ]D\}	}|D ]}
|
j|kr qqt| j||}
||
 ||
|	 qqL|S )z
    Uses the powerset construction algorithm to create DFA states from sets of
    NFA states.

    Also does state reduction if some states are not needed.
    c                    sJ   t | tsJ | |v rd S ||  | jD ]}|jd u r* |j| q*d S r   )r'   r
   addr+   nonterminal_or_stringr)   )	nfa_statebase_nfa_setnfa_arc
addclosurer   r   rK      s    


z_make_dfas.<locals>.addclosureN)r'   r
   r(   r   r$   r%   r+   rF   
setdefaultr)   r2   appendr1   )startfinishrH   ZstatesrC   r+   rG   rI   r%   rF   Znested_stater   rJ   r   
_make_dfas   s*    
	





rP   c           	      C   s   t d| j | g}t|D ]\}}t d|||u r4dp6d |jD ]^}|j|j }}||v rf||}nt|}|| |d u rt d|  q@t d||f  q@qd S )NzDump of NFA for  State(final) z	    -> %d    %s -> %d)	printr$   r=   r+   rF   r)   indexr6   rM   )	rN   rO   todorA   rC   arcr0   r/   rB   r   r   r   	_dump_nfa   s    

rY   c                 C   sf   t d| d j t| D ]H\}}t d||jr0dp2d |j D ]\}}t d|| |f  q@qd S )NzDump of DFA forr   rQ   rR   rS   rT   )rU   r$   r=   r.   r+   r2   rV   )r?   rA   rC   nonterminalr/   r   r   r   
_dump_dfas   s
    r[   )bnf_grammarreturnc                 C   s   i }d}t |  D ]2\}}t||}t| |||j< |du r|j}qi }| D ]T\}}|D ]F}	|	j D ]6\}
}|
|v r||	j|
< qnt|||
}t	||	j
|< qnq`qTt| t|||S )a  
    ``bnf_text`` is a grammar in extended BNF (using * for repetition, + for
    at-least-once repetition, [] for optional parts, | for alternatives and ()
    for grouping).

    It's not EBNF according to ISO/IEC 14977. It's a dialect Python uses in its
    own parser.
    N)r	   parserP   rD   r$   r2   r+   r,   _make_transitionr   r-   _calculate_tree_traversalr   )r\   token_namespacer   r   Znfa_aZnfa_zr?   Zreserved_stringsrZ   	dfa_stateZterminal_or_nonterminalr   
transitionr   r   r   generate_grammar   s,    	

rd   c                 C   s   |d   rt| |S |d dv s*J ||ds>|drBJ t|}z
|| W S  tyz   t| }||< | Y S 0 dS )z
    Creates a reserved string ("if", "for", "*", ...) or returns the token type
    (NUMBER, STRING, ...) for a given grammar terminal.
    r   )"'z"""z'''N)isalphagetattr
startswithr   KeyErrorr   )ra   r   r0   r;   rr   r   r   r_     s    

r_   c              	   C   s   i }t |  }|  |D ]}||vrt| || q|  D ]}|D ]}|j}|j D ]\}}||  D ]r\}}	||v r|| }
t|
j	r|
j	d j
n|
jj
|	r|	d j
n|j
g}td|j
|ft|  t||	||< qnqZqFq>dS )z
    By this point we know how dfas can move around within a stack node, but we
    don't know how we can add a new stack node (nonterminal transitions).
    r   zZRule %s is ambiguous; given a %s token, we can't determine if we should evaluate %s or %s.N)listkeyssort_calculate_first_plansvaluesr-   r,   r2   sortedr    r$   r   
ValueErrortupler   )r   first_plansZnonterminalsrZ   r?   rb   r-   r   rc   pushesZ	prev_planchoicesr   r   r   r`   .  s>    
r`   c              	   C   s   | | }i }d||< |d }|j  D ]\}}|jg||< q&|j D ]h\}}z|| }	W n tyx   t| ||}	Y n0 |	du rtd| |	 D ]\}
}|g| ||
< qqF|||< |S )z
    Calculates the first plan in the first_plans dictionary for every given
    nonterminal. This is going to be used to know when to create stack nodes.
    Nr   zleft recursion for rule %r)r-   r2   r   r,   rj   ro   rr   )r   rt   rZ   r?   Znew_first_plansrC   rc   r/   Znonterminal2Zfirst_plans2tru   r   r   r   ro   `  s"    ro   N)r   astr   typingr   r   r   r   r   r   Zparso.pgen2.grammar_parserr	   r
   r   r   r   r   r   rD   rP   rY   r[   r   rd   r_   r`   ro   r   r   r   r   <module>   s     :2*2