3
L(c%A                 @   sL   d Z ddlZddlZddlmZmZmZ ddlmZ i Z	G dd de
ZdS )zGprovides the Lexer class for parsing template strings into parse trees.    N)	parsetree
exceptionscompat)adjust_whitespacec               @   s   e Zd Zd$ddZedd Zd%ddZd	d
 Zdd Zdd Z	e
j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d"d# ZdS )&LexerNFc             C   s   || _ || _tj| j| _d| _d| _d| _d| _g | _	g | _
g | _|| _|| _tjrd|rdtjd|d krtg | _nt|ds|g| _n|| _d S )N   r   z4Mako for Python 3 does not support disabling Unicode__iter__)textfilenamer   ZTemplateNodetemplatematched_linenomatched_charposlinenomatch_positiontagcontrol_lineternary_stackdisable_unicodeencodingr   Zpy3kr   ZUnsupportedErrorpreprocessorhasattr)selfr	   r
   r   Zinput_encodingr    r   ,/usr/lib/python3/dist-packages/mako/lexer.py__init__   s(    


zLexer.__init__c             C   s   | j | j| j| jdS )N)sourcer   posr
   )r	   r   r   r
   )r   r   r   r   exception_kwargs/   s    zLexer.exception_kwargsc             C   sX   yt ||f }W n< tk
rL   |r2tj||}n
tj|}|t ||f< Y nX | j|S )z>compile the given regexp, cache the reg, and call match_reg().)_regexp_cacheKeyErrorrecompile	match_reg)r   Zregexpflagsregr   r   r   match6   s    
zLexer.matchc             C   s   | j }|j| j| j }|r|j \}}||kr:|d | _ n|| _ | j| _tjd| j|| j  }|d }x,|dkr|| jk r| j| dkr|d8 }qjW || | _	|  jt
|7  _|S )zmatch the given regular expression object to the current text
        position.

        if a match occurs, update the current text and line position.

        r   z\nr   
)r   r%   r	   spanr   r   r    findall
textlengthr   len)r   r$   Zmpr%   startendlinescpr   r   r   r"   D   s    "
zLexer.match_regc       	      G   sT  | j }dj|}d}d}d}x0| jd}|r0q | jdtj}|rDq | jd| }|r|op|dkpp|dkpp|dk r| j|| j t|jd  |jdfS |s| jd| tj}|r2||jdjd7 }||jdjd	8 }||jdjd
7 }||jdjd8 }||jdjd7 }||jdjd8 }q t	j
ddj| f| jq W d S )N|r   z#.*\nz+(\"\"\"|\'\'\'|\"|\')[^\\]*?(\\.[^\\]*?)*\1z(%s)r   z(.*?)(?=\"|\'|#|%s){}()[]zExpected: %s,)r   joinr%   r    Sr	   r*   groupcountr   SyntaxExceptionr   )	r   Zwatch_nestingr	   startposZtext_reZbrace_levelZparen_levelZbracket_levelr%   r   r   r   parse_until_textb   sD    


zLexer.parse_until_textc             O   s  |j d| j |j d| j |j d| j | j|d< |||}t| jr\| jd jj| n| j	jj| | j
r| j
d }|jj| t|tjo|j|js| jr| jd	 r| jd
 d jj| t|tj rt| jr| jd |_| jj| nt|tjr|jr"| j
j  | jj  n|jrD| j
j| | jjg  nn| j
rr| j
d j|jrr| jd j| n@| j
r| j
d j|j rtjd|j| j
d jf f| jd S )Nr   r   r   r
   r   z1Keyword '%s' not a legal ternary for keyword '%s'r>   r>   r>   r>   r>   r>   r>   r>   r>   )
setdefaultr	   r   r   r
   r*   r   Znodesappendr   r   
isinstancer   ControlLineZ
is_ternarykeywordr   TagparentisendpopZ
is_primaryr   r;   r   )r   ZnodeclsargskwargsZnodeZcontrol_framer   r   r   append_node   sF    





zLexer.append_nodez #.*coding[:=]\s*([-\w.]+).*\r?\nc             C   s&  t |tjr6| jj|}|r&|jdp,|p,d}||fS |jtjr|t	tjd }d}| jj|j
dd}|dk	r|jddkrtjd|jd |j
dddd|n,| jj|j
dd}|r|jd}n|pd}|ry|j
|}W n4 tk
r   tjd| |j
dddd|Y nX ||fS )	zgiven string/unicode or bytes/string, determine encoding
           from magic encoding comment, return body as unicode
           or raw if decode_raw=False

        r   asciiNzutf-8ignorezHFound utf-8 BOM in file, with conflicting magic encoding comment of '%s'r   z0Unicode decode operation of encoding '%s' failed)rA   r   Z	text_type
_coding_rer%   r9   
startswithcodecsBOM_UTF8r*   decoder   CompileExceptionUnicodeDecodeError)r   r	   Z
decode_rawZknown_encodingr
   mr   Zparsed_encodingr   r   r   decode_raw_stream   s8    


zLexer.decode_raw_streamc             C   s<  | j | j| j | j| j\| _| _x| jD ]}|| j| _q*W | j| j t| j| _	xz| j
| j	krfP | j rpP | j rzqX| j rqX| j rqX| j rqX| j rqX| j rqX| j rqX| j
| j	krP tjdqXW t| jrtjd| jd j f| jt| jr6tjd| jd j | j| jd j| jd j| j| jS )	Nzassertion failedzUnclosed tag: <%%%s>r   z"Unterminated control keyword: '%s'r>   r>   r>   r>   )rU   r	   r   r   r
   r   r"   rM   r*   r)   r   	match_endmatch_expressionmatch_control_linematch_commentmatch_tag_startmatch_tag_endmatch_python_block
match_textr   rR   r   r;   rC   r   r   r   r   r   )r   Zpreprocr   r   r   parse   sV    

zLexer.parsec             C   s   d}| j |tjtjB tjB }|r|j \}}}|| _i }|rzx:tjd|D ]*}|\}}	}
|	p`|
}|jdd}|||< qLW | j	t
j|| |r| jj  nR|dkr| j dtj}|stjd| jd j f| j| j	t
j|jd | j S d	S d
S d S )Na  
            \<%     # opening tag

            ([\w\.\:]+)   # keyword

            ((?:\s+\w+|\s*=\s*|"[^"]*?"|'[^']*?'|\s*,\s*)*)  # attrname, = \
                                               #        sign, string expression
                                               # comma is for backwards compat
                                               # identified in #366

            \s*     # more whitespace

            (/)?>   # closing

        z)\s*(\w+)\s*=\s*(?:'([^']*)'|\"([^\"]*)\")z
r&   r	   z(.*?)(?=\</%text>)zUnclosed tag: <%%%s>r   TFr>   )r%   r    Ir8   XgroupsrC   r(   replacerJ   r   rD   r   rG   r   r;   r   Textr9   r[   )r   r$   r%   rC   attrrF   Z
attributesZattkeyZval1Zval2r	   r   r   r   rZ     s:    
zLexer.match_tag_startc             C   s   | j d}|r~t| js4tjd|jd f| jn<| jd j|jdkrptjd|jd| jd jf f| j| jj  dS dS d S )	Nz\</%[\t ]*(.+?)[\t ]*>z(Closing tag without opening tag: </%%%s>r   z.Closing tag </%%%s> does not match tag: <%%%s>TFr>   r>   )	r%   r*   r   r   r;   r9   r   rC   rG   )r   r%   r   r   r   r[   C  s    



zLexer.match_tag_endc             C   s0   | j dtj}|r(|j }|r"|S dS ndS d S )Nz\ZTF)r%   r    r8   r9   )r   r%   stringr   r   r   rV   U  s    zLexer.match_endc             C   s@   | j dtjtjB }|r8|jd}|r4| jtj| dS dS d S )Na  
                (.*?)         # anything, followed by:
                (
                 (?<=\n)(?=[ \t]*(?=%|\#\#)) # an eval or line-based
                                             # comment preceded by a
                                             # consumed newline and whitespace
                 |
                 (?=\${)      # an expression
                 |
                 (?=</?[%&])  # a substitution or block or call start or end
                              # - don't consume
                 |
                 (\\\r?\n)    # an escaped newline  - throw away
                 |
                 \Z           # end of string
                )r   TF)r%   r    r`   r8   r9   rJ   r   rc   )r   r%   r	   r   r   r   r]   `  s    
zLexer.match_textc             C   sd   | j d}|r\| j| j }}| jdd\}}t|d }| jtj||jddk||d dS dS d S )	Nz<%(!)?Fz%>r&   r   !)r   r   T)	r%   r   r   r=   r   rJ   r   ZCoder9   )r   r%   liner   r	   r,   r   r   r   r\   z  s    
zLexer.match_python_blockc             C   s~   | j d}|rv| j| j }}| jddd\}}|dkrH| jdd\}}nd}|jdd}| jtj||j ||d	 dS d
S d S )Nz\${Tz\|r1   r/    z
r&   )r   r   F)	r%   r   r   r=   rb   rJ   r   Z
Expressionstrip)r   r%   rh   r   r	   r,   Zescapesr   r   r   rW     s    

zLexer.match_expressionc             C   s   | j dtj}|r|jd}|jd}|dkrtj d|}|sRtjd| f| j|jdd\}}|d k	}|rt| jstjd||f f| jn0| jd j	|krtjd|| jd j	f f| j| j
tj||| n| j
tj| d	S d
S d S )NzB(?<=^)[\t ]*(%(?!%)|##)[\t ]*((?:(?:\\r?\n)|[^\r\n])*)(?:\r?\n|\Z)r      %z(end)?(\w+)\s*(.*)zInvalid control line: '%s'z!No starting keyword '%s' for '%s'z'Keyword '%s' doesn't match keyword '%s'TFr>   r>   )r%   r    Mr9   r   r;   r   r*   r   rC   rJ   r   rB   Comment)r   r%   operatorr	   m2rF   rC   r   r   r   rX     s<    




zLexer.match_control_linec             C   s2   | j dtj}|r*| jtj|jd dS dS dS )z*matches the multiline version of a commentz<%doc>(.*?)</%doc>r   TFN)r%   r    r8   rJ   r   rn   r9   )r   r%   r   r   r   rY     s
    zLexer.match_comment)NFNN)N)__name__
__module____qualname__r   propertyr   r%   r"   r=   rJ   r    r!   rM   rU   r^   rZ   r[   rV   r]   r\   rW   rX   rY   r   r   r   r   r      s&     

%*
(62#r   )__doc__r    rO   Zmakor   r   r   Z
mako.pygenr   r   objectr   r   r   r   r   <module>   s   