U
    Zf8                     @   s~   d dl mZmZmZmZ d dlZd dlZd dlmZ dZ	e	rDd dl
Z
G dd deZe ZG dd deZdd	 Zd
d ZdS )    )absolute_importdivisionprint_functionunicode_literalsNFc                   @   s   e Zd ZdZdd ZdS )
MultiTokenzdObject used to monkeypatch ply.lex so that we can return multiple
    tokens from one lex operation.c                 C   s   |d j | _ || _d S )Nr   )typetokens)selfr    r
   8/tmp/pip-unpacked-wheel-vqb3mfeu/stone/frontend/lexer.py__init__   s    zMultiToken.__init__N)__name__
__module____qualname____doc__r   r
   r
   r
   r   r      s   r   c                   @   sx  e Zd ZdZdZdd Zdd Zdd Zd	d
 ZdZ	e	d7 Z	e	d7 Z	e	d7 Z	e	d7 Z	e	d7 Z	e	d7 Z	e	d7 Z	dZ
dZdZdZdZdZdZdZdZdZdddd d!d"d#d$d%d&d'd(d)d*d+d,d-gZd.d/d0d1d2d3d4d5d6d7d8d9d:Ze	ee 7 Z	d;d< Zd=d> Zd?d@ ZdAdB ZdCdD ZdEdF ZdGdH ZdIdJ ZdKdL Z dMdN Z!dOdP Z"dQdR Z#dSdT Z$dUdV Z%dWdX Z&dYdZ Z'd[Z(d\d] Z)d^S )_Lexerz'
    Lexer. Tokenizes stone files.
    ))WSIGNOREZ	inclusivec                 C   s.   d | _ d | _d | _td| _d | _g | _d S )Nzstone.stone.lexer)lextokens_queue
cur_indentlogging	getLogger_logger
last_tokenerrors)r	   r
   r
   r   r   "   s    zLexer.__init__c                 K   s6   t j f d| i|| _ g | _d| _| j |d  dS )z
        Required by ply.yacc for this to quack (duck typing) like a ply lexer.

        :param str file_data: Contents of the file to lex.
        moduler   
N)r   r   r   input)r	   Z	file_datakwargsr
   r
   r   r   ,   s    zLexer.inputc                 C   s   | j r| j d| _n| j }t|trH| j |j | j d| _n|dkr| j	dkr| jr| jj
dkrtdd| jj| jj}| j | | j	}tdd| jj| jj}| j |g|  d| _	| j d| _n|| _| jS )zf
        Returns the next LexToken. Returns None when all tokens have been
        exhausted.
        r   N)NEWLINEZLINEr   r   DEDENT	)r   popr   r   token
isinstancer   extendr   r   r   _create_tokenlinenolexposappend)r	   rnewline_tokenZdedent_countZdedent_tokenr
   r
   r   r#   9   s:    


      zLexer.tokenc                 C   s,   |  | |  }|sq(| jd| q
dS )z;Logs all tokens for human inspection. Useful for debugging.zToken %rN)r   r#   r   debug)r	   datar#   r
   r
   r   testX   s
    
z
Lexer.test)ZIDKEYWORDPATHDOT)r    INDENTr   )COMMAZEQLPARRPAR)ZBOOLEANFLOATZINTEGERZNULLSTRING)LBRACKETRBRACKET)LBRACERBRACECOLON)Q)ATz\.z\[z\]=,z\?z\{z\}z\:@alias
annotationannotation_typeattrsby
deprecateddocZexampleerrorextendsimport	namespacepatchroutestructunionunion_closedZ
ANNOTATIONZANNOTATION_TYPEATTRSZ
DEPRECATEDZBYZEXTENDSZIMPORTPATCHZROUTEZSTRUCTZUNIONZUNION_CLOSED)rC   rD   rE   rG   rF   rJ   rK   rM   rN   rO   rP   rQ   c                 C   s   |j d |S )z\(r   )lexerZ
push_stater	   r#   r
   r
   r   t_LPAR   s    zLexer.t_LPARc                 C   s   |j   |S )z\))rT   Z	pop_staterU   r
   r
   r   t_RPAR   s    
zLexer.t_RPARc                 C   s   |j dk|_ |S )z\btrue\b|\bfalse\btrue)valuerU   r
   r
   r   t_ANY_BOOLEAN   s    zLexer.t_ANY_BOOLEANc                 C   s
   t |_|S )z\bnull\b)	NullTokenrY   rU   r
   r
   r   
t_ANY_NULL   s    zLexer.t_ANY_NULLc                 C   s>   |j | jkr6|j dkr | jr |S | j|j d|_|S |S dS )z[a-zA-Z_][a-zA-Z0-9_-]*rD   r/   N)rY   KEYWORDSr   RESERVEDgetr   rU   r
   r
   r   t_ANY_ID   s    	zLexer.t_ANY_IDc                 C   s   |S )z\/[/a-zA-Z0-9_-]*r
   rU   r
   r
   r   
t_ANY_PATH   s    zLexer.t_ANY_PATHc                 C   s   t |j|_|S )z-?\d+(\.\d*(e-?\d+)?|e-?\d+))floatrY   rU   r
   r
   r   t_ANY_FLOAT   s    zLexer.t_ANY_FLOATc                 C   s   t |j|_|S )z-?\d+)intrY   rU   r
   r
   r   t_ANY_INTEGER   s    zLexer.t_ANY_INTEGERc                    s   d}|j  j|jd7  _|jdd }d}tdt|D ]N}|| }|rt|dkrZd}n|dkrfd}||7 }d}q<|d	krd}q<||7 }q<d
t| j   fdd| D }d	||_|S )z\"([^\\"]|(\\.))*\"r   r       ntr!   \ c                    s   g | ]}|  d dqS )rh   rf   )replace).0lineZindentation_strr
   r   
<listcomp>  s   z&Lexer.t_ANY_STRING.<locals>.<listcomp>)
rT   r'   rY   countrangelen_indent_level_to_spaces_countr   
splitlinesjoin)r	   rj   escapedsZnew_stricZlines_without_indentationr
   rp   r   t_ANY_STRING  s,    

zLexer.t_ANY_STRINGc                 C   s   |j  j|jd7  _|jd }|dkr|j j| dk}| oN|j j| dk}|sX|rtdd|j|jt|j d }|j |_ | |}|r|S |r|r|j	
d| |S |S |d8 }q"dS )[#][^\n]*\n+r   rf   r   rl   r   N)rT   r'   rY   rr   r(   lexdatar&   rt   !_create_tokens_for_next_line_dentr   insert)r	   r#   rz   Zis_full_line_commentZis_partial_line_commentr+   dent_tokensr
   r
   r   t_INITIAL_comment%  s0    
 zLexer.t_INITIAL_commentc                 C   sN   |j  j|jd7  _tdd|j|jt|j d }|j |_ | | dS )r}   r   r   rf   N)rT   r'   rY   rr   r&   r(   rt   _check_for_indent)r	   r#   r+   r
   r
   r   t_WSIGNORE_commentC  s     zLexer.t_WSIGNORE_commentc                 C   s@   |j  j|jd7  _| |}|r8|jd| |S |S dS )\n+r   r   N)rT   r'   rY   rr   r   r   r   )r	   r+   r   r
   r
   r   t_INITIAL_NEWLINEL  s    
zLexer.t_INITIAL_NEWLINEc                 C   s&   |j  j|jd7  _| | dS )r   r   N)rT   r'   rY   rr   r   )r	   r+   r
   r
   r   t_WSIGNORE_NEWLINEV  s    zLexer.t_WSIGNORE_NEWLINEc                 C   sr   |  |}|dks|dkrdS |dkr*dnd}t|d|jd |jt|j }|gt| }|  j|7  _t|S )z
        Starting from a newline token that isn't followed by another newline
        token, returns any indent or dedent tokens that immediately follow.
        If indentation doesn't change, returns None.
        Nr   r2   r    r!   rf   )	_get_next_line_indent_deltar&   r'   r(   rt   rY   absr   r   )r	   r+   indent_deltaZ	dent_typeZ
dent_tokenr   r
   r
   r   r   [  s    
  z'Lexer._create_tokens_for_next_line_dentc                 C   s6   |  |}|dks|dkrdS | jd|jjf dS )zw
        Checks that the line following a newline is indented, otherwise a
        parsing error is generated.
        Nrf   z-Line continuation must increment indent by 1.)r   r   r)   rT   r'   )r	   r+   r   r
   r
   r   r   p  s    
zLexer._check_for_indentc                 C   s   |j dkstd|jt|j }|t|jjkr6dS |jj|d tj	dd }|s\dS |
 }t|}|dkrxdS |d dkrdS t|| }|d dkr| jd|jjf dS |t| j }|d S )	aX  
        Returns the change in indentation. The return units are in
        indentations rather than spaces/tabs.

        If the next line's indent isn't relevant (e.g. it's a comment),
        returns None. Since the return value might be 0, the caller should
        explicitly check the return type, rather than rely on truthiness.
        r   z3Can only search for a dent starting from a newline.Nrf   r   #   zIndent is not divisible by 4.)r   AssertionErrorr(   rt   rY   rT   r~   splitoslineseplstripr   r)   r'   ru   r   )r	   r+   Znext_line_posro   Zlstripped_lineZlstripped_line_lengthindentr   r
   r
   r   r     s.    	
z!Lexer._get_next_line_indent_deltaz 	c                 C   sR   | j d|jd |jj | jdt|jd d |jjf |j	d d S )NzIllegal character %r at line %dr   zIllegal character %s.urf   )
r   r,   rY   rT   r'   r   r)   reprr   skiprU   r
   r
   r   t_ANY_error  s     zLexer.t_ANY_errorN)*r   r   r   r   Zstatesr   r   r#   r.   r   Zt_DOTZ
t_LBRACKETZ
t_RBRACKETZt_EQZt_COMMAZt_QZt_LBRACEZt_RBRACEZt_COLONZt_ATr]   r^   tuplevaluesrV   rW   rZ   r\   r`   ra   rc   re   r|   r   r   r   r   r   r   r   Zt_ignorer   r
   r
   r
   r   r      s   

	$	
&r   c                 C   s$   t  }| |_||_||_||_|S )z
    Helper for creating ply.lex.LexToken objects. Unfortunately, LexToken
    does not have a constructor defined to make settings these values easy.
    )r   ZLexTokenr   rY   r'   r(   )
token_typerY   r'   r(   r#   r
   r
   r   r&     s    r&   c                 C   s   | d S )Nr   r
   )r   r
   r
   r   ru     s    ru   )
__future__r   r   r   r   r   r   Zply.lexr   Z_MYPYtypingobjectr   r[   r   r&   ru   r
   r
   r
   r   <module>   s   	   