o
    /hk                     @   s   d Z g dZddlZddlZddlZddlZddlZddlmZ G dd de	Z
G dd	 d	e
ZG d
d de
ZG dd de
ZG dd de
ZG dd dZG dd dZG dd dZej Zg ZG dd dZG dd dZdS )a  Productions parser used by css and stylesheets classes to parse
test into a cssutils.util.Seq and at the same time retrieving
additional specific cssutils.util.Item objects for later use.

TODO:
    - ProdsParser
        - handle EOF or STOP?
        - handle unknown @rules
        - handle S: maybe save to Seq? parameterized?
        - store['_raw']: always?

    - Sequence:
        - opt first(), naive impl for now

)
ProdParserSequenceChoiceProdPreDef    N   	pushtokenc                   @      e Zd ZdZdS )
ParseErrorz6Base Exception class for ProdParser (used internally).N__name__
__module____qualname____doc__ r   r   G/var/www/html/myenv/lib/python3.10/site-packages/cssutils/prodparser.pyr          r   c                   @   r
   )Donez@Raised if Sequence or Choice is finished and no more Prods left.Nr   r   r   r   r   r   #   r   r   c                   @   r
   )	Exhaustedz<Raised if Sequence or Choice is finished but token is given.Nr   r   r   r   r   r   )   r   r   c                   @   r
   )MissingzIRaised if Sequence or Choice is not finished but no matching token given.Nr   r   r   r   r   r   /   r   r   c                   @   r
   )NoMatchz3Raised if nothing in Sequence or Choice does match.Nr   r   r   r   r   r   5   r   r   c                   @   s@   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )r   z2A Choice of productions (Sequence or single Prod).c                 O   sV   || _ z|d | _W n ty$   | j D ]
}|jrd| _ nqd| _Y nw |   dS )zi
        *prods
            Prod or Sequence objects
        options:
            optional=False
        optionalTFN)_prodsr   KeyErrorreset)selfprodsoptionspr   r   r   __init__>   s   
zChoice.__init__c                 C   s
   d| _ dS )zStart Choice from zeroFN)
_exhaustedr   r   r   r   r   S   s   
zChoice.resetc                 C   s    | j D ]
}||r dS qdS )zCheck if token matchesTF)r   matchesr   tokenprodr   r   r   r#   W   s
   

zChoice.matchesc                 C   sl   | j s.d}| jD ]}||rd| _ |  |  S |jrd}q|s,td| d|  dS |r4tddS )a?  
        Return:

        - next matching Prod or Sequence
        - ``None`` if any Prod or Sequence is optional and no token matched
        - raise ParseError if nothing matches and all are mandatory
        - raise Exhausted if choice already done

        ``token`` may be None but this occurs when no tokens left.FTNo match for  in Extra tokenN)r!   r   r#   r   r   r   r   )r   r%   r   r   r   r   r   nextProd^   s    

zChoice.nextProdc              	   C   .   d| j j d|  d| jdt| dd	S N<cssutils.prodsparser.z object sequence=z
 optional= at 0xx>	__class__r   __str__r   idr"   r   r   r   __repr__{      .zChoice.__repr__c                 C      dd dd | jD  S )Nz
Choice(%s), c                 S      g | ]}t |qS r   str.0r/   r   r   r   
<listcomp>       z"Choice.__str__.<locals>.<listcomp>joinr   r"   r   r   r   r3   ~      zChoice.__str__N)
r   r   r   r   r    r   r#   r*   r5   r3   r   r   r   r   r   ;   s    r   c                   @   sT   e Zd ZdZdd Zdd Zdd Zdd	 Zed
d Z	dd Z
dd Zdd ZdS )r   z2A Sequence of productions (Choice or single Prod).c                 O   s   || _ z|d }W n ty   dd }Y nw | \| _| _| jdu r7ztj| _W n ty6   tj| _Y nw t| j | _| 	  dS )z
        *prods
            Prod or Choice or Sequence objects
        **options:
            minmax = lambda: (1, 1)
                callback returning number of times this sequence may run
        minmaxc                   S   s   dS )N)r   r   r   r   r   r   r   <lambda>   s    z#Sequence.__init__.<locals>.<lambda>N)
r   r   _min_maxsysmaxsizeAttributeErrorlen
_prodcountr   )r   r   r   rC   r   r   r   r       s   
zSequence.__init__c              	   C   sD   | j D ]}||r dS z	|jsW  dS W q ty   Y qw dS )z4Called by Choice to try to find if Sequence matches.TF)r   r#   r   rI   r$   r   r   r   r#      s   

zSequence.matchesc                 C   s   d| _ d| _d| _dS )z$Reset this Sequence if it is nested.Fr   N)_roundstarted_i_roundr"   r   r   r   r      s   
zSequence.resetc                 C   s,   | j | jd D ]}|jst|  S qdS )z0Return current element of Sequence, used by nameNr   )r   rM   r   r;   )r   r&   r   r   r   _currentName   s
   zSequence._currentNamec                 C   s
   | j dkS )Nr   )rE   r"   r   r   r   rD      s   
 zSequence.<lambda>c                 C   s   | j | jk rg| j}| j }| j| }|dkrd| _|  jd7  _| j| jkr/|  j d7  _ d| _||r=d| _|  |S |jrAq || j	k sI| jrOt
d| |s]| jrZt
d| t td| d|  |rmtdd	S )
zReturn

        - next matching Prod or Choice
        - raises ParseError if nothing matches
        - raises Exhausted if sequence already done
        r   Fr   TzMissing token for production %sr'   r(   r)   N)rN   rF   rM   r   rL   rK   r#   r   r   rE   r   r   r   r   )r   r%   iroundr   r   r   r   r*      s4   

zSequence.nextProdc              	   C   r+   r,   r1   r"   r   r   r   r5      r6   zSequence.__repr__c                 C   r7   )NzSequence(%s)r8   c                 S   r9   r   r:   r<   r   r   r   r>      r?   z$Sequence.__str__.<locals>.<listcomp>r@   r"   r   r   r   r3      rB   zSequence.__str__N)r   r   r   r   r    r#   r   rO   propertyr   r*   r5   r3   r   r   r   r   r      s    	1r   c                   @   sN   e Zd ZdZ										dddZdd Zdd	 Zd
d Zdd ZdS )r   z"Single Prod in Sequence or Choice.FNc                 C   s   || _ || _|| _|| _|| _|| _|	| _|
| _|| _|| _	dd }|s(|du r,|| _
ndd | _
t|r:|| _dS |rC||| _dS d| _dS )a  
        name
            name used for error reporting
        match callback
            function called with parameters tokentype and tokenvalue
            returning True, False or raising ParseError
        toSeq callback (optional) or False
            calling toSeq(token, tokens) returns (type_, val) == (token[0], token[1])
            to be appended to seq else simply unaltered (type_, val)

            if False nothing is added

        toStore (optional)
            key to save util.Item to store or callback(store, util.Item)
        optional = False
            whether Prod is optional or not
        stop = False
            if True stop parsing of tokens here
        stopAndKeep
            if True stop parsing of tokens here but return stopping
            token in unused tokens
        stopIfNoMoreMatch = False
            stop even if more tokens available, similar to stop and keep but with
            condition no more matches
        nextSor=False
            next is S or other like , or / (CSSValue)
        mayEnd = False
            no token must follow even defined by Sequence.
            Used for operator ',/ ' currently only

        storeToken = None
            if True toStore saves simple token tuple and not and Item object
            to store. Old style processing, TODO: resolve

        exception = None
            exception to be raised in case of error, normaly SyntaxErr
        c                    s    fdd}|S )z"Return a function used by toStore.c                    sB    | v r|   }t |ts|g|  < |   | dS ||  < dS )zSet or append store item.N)
isinstancelistappend)storeitem_vkeyr   r   toStore:  s   

z3Prod.__init__.<locals>.makeToStore.<locals>.toStorer   )rZ   r[   r   rY   r   makeToStore7  s   
z"Prod.__init__.<locals>.makeToStoreFc                 S   s   | d | d fS Nr   r   r   ttokensr   r   r   rD   J      zProd.__init__.<locals>.<lambda>N)_namematchr   stopstopAndKeepstopIfNoMoreMatchnextSormayEnd
storeToken	exceptiontoSeqcallabler[   )r   namerc   r   rk   r[   rd   re   rf   rg   rh   ri   rj   r\   r   r   r   r       s&   4


zProd.__init__c                 C   s    |sdS |\}}}}|  ||S )zReturn if token matches.F)rc   )r   r%   type_vallinecolr   r   r   r#   T  s   zProd.matchesc                 C   s   d S Nr   r"   r   r   r   r   [  s   z
Prod.resetc                 C   s   | j S rr   )rb   r"   r   r   r   r3   ^  s   zProd.__str__c                 C   s$   d| j j d| jdt| ddS )Nr-   z object name=r.   r/   r0   )r2   r   rb   r4   r"   r   r   r   r5   a  s   $zProd.__repr__)
FNNFFFFFNN)	r   r   r   r   r    r#   r   r3   r5   r   r   r   r   r      s"    
\r   c                   @   s@   e Zd ZdZdddZdd Zddd	Z	
	
		
	
dddZdS )r   zProductions parser.Tc                 C   s&   t jj| _t j| _|rt  d S d S rr   )cssutilscssproductionsCSSProductionstypeslog_log	tokenizerclear)r   rz   r   r   r   r    o  s
   
zProdParser.__init__c                 C   sd   t |trt| S t |tjr|S t |tr't|dkr"t	 t
|gS t |tr0t
|S |S )zhBuild a generator which is the only thing that is parsed!
        old classes may use lists etc
           )rS   r;   ry   tokenizestriprv   GeneratorTypetuplerJ   NotImplementedErroriterrT   )r   textr   r   r   _texttotokensu  s   



zProdParser._texttotokens,/c              	   c   s    |D ]I}|d | j jkr=zt|}W n ty   |V  Y qw |d |v r*|V  q|d | j jkr6|V  q|V  |V  q|d | j jkrI|V  q|V   |D ]}|V  qOdS )zpNew tokens generator which has S tokens removed,
        if followed by anything in ``until``, normally a ``,``.r   r   N)rv   SnextStopIterationCOMMENT)r   r`   untilr%   next_r   r   r   
_SorTokens  s*   
zProdParser._SorTokensFNc	                 C   s  |  |}	|	s| jd dg ddfS tjjdd}
|si }|g}d}d}d}d}d}d}	 zt }W n tyO   zt	|	}W n t
yL   Y Y nHw Y nw |\}}}}|| jjkrl|
tj|tjj|| n'|r|| jjkr|s|rz|s{q-|
|||| n|| jjkrd}| jd| n|dkrd}nd}z8	 z	|d |}W n ttfy   d}Y nw t|trn|r|| nt|d	kr|  ntd
qW nZ ty } z |rt| d}nd}| j| d| d| W Y d}~nd}~w ty2 } z!|rt| d}nd}| j| d| d| W Y d}~nfd}~ww |jp8|}|jrm|jsm|||	\}}|durm|
|||| |jrm|jsg|||
d  n||| |j rrn"|jrt| t!"||	}	d}n|j#r| $|	d}	d}nd}q.|}|sI	 z
|d jdd}W nX t%y   d}Y n_ t&y } zd}t'|dr|j(sd}| j| d|  W Y d}~n8d}~w ty } zd}d}| j| d|  W Y d}~nd}~ww |d j)rd}n	|r|j)rq|r&|j)s&d}| j| dt*| nt|d	kr2|  nnq|sIt|
sI| jd dg ddfS |
+  ||
||	fS )a  
        text (or token generator)
            to parse, will be tokenized if not a generator yet

            may be:
            - a string to be tokenized
            - a single token, a tuple
            - a tuple of (token, tokensGenerator)
            - already tokenized so a tokens generator

        name
            used for logging
        productions
            used to parse tokens
        keepS
            if WS should be added to Seq or just be ignored
        store  UPDATED
            If a Prod defines ``toStore`` the key defined there
            is a key in store to be set or if store[key] is a list
            the next Item is appended here.

            TODO: NEEDED? :
            Key ``raw`` is always added and holds all unprocessed
            values found
        emptyOk
            if True text may be empty, hard to test before as may be generator

        returns
            :wellformed: True or False
            :seq: a filled cssutils.util.Seq object which is NOT readonly yet
            :store: filled keys defined by Prod.toStore
            :unusedtokens: token generator containing tokens not used yet
        zNo content to parse.FN)readonlyTzInvalid token: EOFr   zNo matchz: r   )r%   rh   z: Missing token for production ),r   rx   errorrs   utilSeqsavedTokenspop
IndexErrorr   r   rv   r   rU   css
CSSCommentr   INVALIDr*   r   r   rS   r   rJ   r   ry   pushrf   rk   re   r[   ri   rd   	itertoolschainrg   r   r   r   hasattrrh   r   r;   rstrip)r   r   rm   productionskeepScheckSrV   emptyOkdebugr`   seqr   
wellformedstartedstopallr&   defaultSrf   r%   rn   ro   rp   rq   elastprodr   r   r   parse  s  
,






  	"
'zProdParser.parse)T)r   )FFNFF)r   r   r   r   r    r   r   r   r   r   r   r   r   l  s    

#r   c                   @   s0  e Zd ZdZejjZe	dZ
ed-ddZe									d.d	d
Zed/ddZed0ddZed1ddZed2ddZed1ddZed1ddZed3ddZed3ddZed3ddZed1ddZed4d d!Zed3d"d#Zed1d$d%Zed1d&d'Zed5d(d)Zed6d+d,ZdS )7r   z_Predefined Prod definition for use in productions definition
    for ProdParser instances.
    z1^\#(?:[0-9abcdefABCDEF]{3}|[0-9abcdefABCDEF]{6})$NFc                 C      t ddd | |dS )Ncalcfunctionc                 S      dt j|kS )Nzcalc(rs   helper	normalizer_   vr   r   r   rD     ra   zPreDef.calc.<locals>.<lambda>)rm   rc   rk   rg   r   )rk   rg   r   r   r   calc  s   zPreDef.calcchar,c	           	         s"   t |  fdd|||||||d	S )zany CHARc                    s   | kS rr   r   r   r   r   r   rD         zPreDef.char.<locals>.<lambda>)	rm   rc   rk   rd   re   rh   rf   r   rg   r   )	rm   r   rk   rd   re   rh   rf   r   rg   r   r   r   r     s   
zPreDef.charc                 C   s   t jdd| |dS )Ncommar   r   rk   r   r   r   r   r   r   r     s   zPreDef.commac                    s   t ddd  fddddS )Ncommentc                 S      | dkS )Nr   r   r   r   r   r   rD     r   z PreDef.comment.<locals>.<lambda>c                    s   | d t jjdg dfS )Nr   r   )
parentRule)rs   r   r   r^   parentr   r   rD     s   T)rm   rc   rk   r   r   r   r   r   r   r     s   
zPreDef.commentc                 C   s   t ddd dd || dS )N	dimensionc                 S      | t jjkS rr   )r   rv   	DIMENSIONr   r   r   r   rD         z"PreDef.dimension.<locals>.<lambda>c                 S      | d t j| d fS r]   r   r^   r   r   r   rD         rm   rc   rk   rd   rg   r   )rg   rd   r   r   r   r     s   zPreDef.dimensionc                 C   s   t ddd || |dS )Nfunctionc                 S   r   rr   )r   rv   FUNCTIONr   r   r   r   rD     r   z!PreDef.function.<locals>.<lambda>)rm   rc   r[   rk   rg   r   )rk   rg   r[   r   r   r   r        zPreDef.functionc                 C   s   t jdd | |dS ))zend FUNC ")"rd   rh   r   r   r   r   r   funcEnd  s   zPreDef.funcEndc                 C   r   )z#123 or #123456z	HEX colorc                 S   s   | t jjkot j|S rr   )r   rv   HASH
reHexcolorrc   r   r   r   r   rD     r   z!PreDef.hexcolor.<locals>.<lambda>)rm   rc   rd   rg   r   rd   rg   r   r   r   hexcolor  s   zPreDef.hexcolorc                 C      t ddd | ||dS )Nidentc                 S   r   rr   )r   rv   IDENTr   r   r   r   rD     r   zPreDef.ident.<locals>.<lambda>)rm   rc   rd   r[   rg   r   )rd   r[   rg   r   r   r   r     r   zPreDef.identc                 C   r   )Nnumberc                 S   r   rr   )r   rv   NUMBERr   r   r   r   rD     r   zPreDef.number.<locals>.<lambda>rm   rc   rd   rk   rg   r   rd   rk   rg   r   r   r   r     r   zPreDef.numberc                 C   r   )N
percentagec                 S   r   rr   )r   rv   
PERCENTAGEr   r   r   r   rD   #  r   z#PreDef.percentage.<locals>.<lambda>r   r   r   r   r   r   r     r   zPreDef.percentagec                 C      t ddd dd | |dS )z(string delimiters are removed by defaultstringc                 S   r   rr   )r   rv   STRINGr   r   r   r   rD   .  r   zPreDef.string.<locals>.<lambda>c                 S   r   r]   )rs   r   stringvaluer^   r   r   r   rD   /  r   r   r   r   r   r   r   r   )     zPreDef.string
whitespacec                 C   s   t | dd ||ddS )Nc                 S   r   rr   )r   rv   r   r   r   r   r   rD   8  r   zPreDef.S.<locals>.<lambda>T)rm   rc   rk   r   rh   r   )rm   rk   r   r   r   r   r   4  r   zPreDef.Sc                 C   s   t ddd d| ||dS )z+ or -zunary +-c                 S   s   |dv S )N)+-r   r   r   r   r   rD   C  r   zPreDef.unary.<locals>.<lambda>T)rm   rc   r   rd   rk   rg   r   r   r   r   r   unary>  s   zPreDef.unaryc                 C   r   )z.'url(' and ')' are removed and URI is strippedURIc                 S   r   rr   )r   rv   r   r   r   r   r   rD   O  r   zPreDef.uri.<locals>.<lambda>c                 S   r   r]   )rs   r   urivaluer^   r   r   r   rD   P  r   r   r   r   r   r   r   uriJ  r   z
PreDef.uric                 C   r   )z$u+123456-abc normalized to lower `u`zunicode-rangec                 S   r   rr   )r   rv   UNICODE_RANGEr   r   r   r   rD   Z  r   z&PreDef.unicode_range.<locals>.<lambda>c                 S   s   | d | d   fS r]   )lowerr^   r   r   r   rD   [  r?   r   r   r   r   r   r   unicode_rangeU  r   zPreDef.unicode_rangec                 C   s   t ddd | |||dS )Nvariablec                 S   r   )Nzvar(r   r   r   r   r   rD   d  ra   z!PreDef.variable.<locals>.<lambda>)rm   rc   rk   r[   rd   rg   r   )rk   rd   rg   r[   r   r   r   r   `  s   zPreDef.variable@c                    s$   dd  t | dd  fdd|dS )z@rule dummy (matches ATKEYWORD to remove unknown rule tokens from
        stream::

            @x;
            @x {...}

        no nested yet!
        c                 S   sD   g }| D ]}| | |d dks|d dkrtj|  S qd S )Nr   };)rU   rs   r   CSSUnknownRule)r`   savedr_   r   r   r   rulew  s   
z PreDef.unknownrule.<locals>.rulec                 S   r   )N	ATKEYWORDr   r   r   r   r   rD     r   z$PreDef.unknownrule.<locals>.<lambda>c                    s   d t | |fS )Nr   r   r^   r   r   r   rD     s    )rm   rc   rk   r[   r   )rm   r[   r   r   r   unknownrulel  s   
zPreDef.unknownrule)NF)	r   r   NFFFFFF)FNrr   )FF)NFN)FNF)r   NF)NFFN)r   N)r   r   r   r   rs   rt   ru   rv   recompiler   staticmethodr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r     sb    
						
	

r   )r   __all__r   r   rG   rv   rs   r   r	   	Exceptionr   r   r   r   r   r   r   r   	tokenize2	Tokenizerry   r   r   r   r   r   r   r   <module>   s,    Gs
q  D