U
    e                     @   s   d Z ddlmZ ddlZddlZddlZejd dkr<eZne	Ze
dj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d Zdd Zdd Zeeeeeed Zd!eiZd"d# Zd$d% Zd&d' Zd(d) ZdS )*z
A simple XPath-like language for tree traversal.

This works by creating a filter chain of generator functions.  Each
function selects a part of the expression, e.g. a child node, a
specific descendant or a node that holds an attribute.
    )absolute_importN   zD('[^']*'|\"[^\"]*\"|//?|\(\)|==?|[/.*\[\]()@])|([^/\[\]()@=\s]+)|\s+c                 C   s2   t | |}|d k	r*t|tkr"|S |gS ndS d S )N )getattrtypelist)node	attr_namechildr   r   </tmp/pip-unpacked-wheel-7k3cqui1/Cython/Compiler/TreePath.pyiterchildren   s    
r   c                 C   sR   z6z
| j }W n tk
r*   t |  Y W S X | W S W n tk
rL   Y d S X d S N)nextAttributeErrorStopIteration)it_nextr   r   r   _get_first_or_none*   s    
r   c                 C   s   | j jdd S )N.)	__class____name__split)r   r   r   r   	type_name5   s    r   c                 C   s8   |d }|  }|d dkr&t d| t| |}||fS )N   r   (z%Expected '(' after function name '%s')
ValueErrorhandle_predicate)r   tokenname	predicater   r   r   
parse_func8   s    
r!   c                    s   t | |\}  fdd}|S )z
    not(...)
    c                 3   s&   | D ]}t  |gd kr|V  qd S r   )r   )resultr   r    r   r   selectF   s    zhandle_func_not.<locals>.select)r!   r   r   r   r$   r   r#   r   handle_func_not@   s    r&   c                    s.   |d   t krt   | |S  fdd}|S )z)
    /NodeName/
    or
    func(...)
    r   c                 3   s<   | D ]2}|j D ]&}t||D ]}t| kr|V  qqqd S r   child_attrsr   r   )r"   r   r	   r
   r   r   r   r$   U   s
    
zhandle_name.<locals>.select)	functionsr   r   r$   r   r)   r   handle_nameL   s
    r,   c                 C   s   dd }|S )z
    /*/
    c                 s   s0   | D ]&}|j D ]}t||D ]
}|V  qqqd S r   r(   r   )r"   r   r   r
   r   r   r   r$   a   s    
zhandle_star.<locals>.selectr   r+   r   r   r   handle_star]   s    r.   c                 C   s   dd }|S )z
    /./
    c                 S   s   | S r   r   )r"   r   r   r   r$   l   s    zhandle_dot.<locals>.selectr   r+   r   r   r   
handle_doth   s    r/   c                    sX   |  }|d dkr  fdd n(|d s@|d  fdd nt d fdd	}|S )
z
    //...
    r   *c                 3   s:   | j D ].}t| |D ]}|V   |D ]
}|V  q&qqd S r   r-   r   r   r
   citer_recursiver   r   r4   v   s
    
z*handle_descendants.<locals>.iter_recursiver   c                 3   sF   | j D ]:}t| |D ]*}t|kr*|V   |D ]
}|V  q2qqd S r   r'   r1   r4   Z	node_namer   r   r4   ~   s    
zExpected node name after '//'c                 3   s"   | D ]} |D ]
}|V  qqd S r   r   )r"   r   r
   r3   r   r   r$      s    z"handle_descendants.<locals>.select)r   r+   r   r5   r   handle_descendantsp   s    r6   c                    s   |  }|d rt d|d }d z
|  }W n tk
r@   Y nX |d dkrVt| t| d krv fdd}n fdd}|S )Nr   zExpected attribute namer   =c              	   3   sB   | D ]8}z |}W n t k
r,   Y qY nX |d k	r|V  qd S r   )r   r"   r   
attr_value)readattrr   r   r$      s    
z handle_attribute.<locals>.selectc              	   3   sj   | D ]`}z |}W n t k
r,   Y qY nX |kr>|V  qt|trttr| kr|V  qd S r   )r   
isinstancebytes_unicodeencoder8   r:   valuer   r   r$      s    

)r   r   parse_path_valueoperator
attrgetterr%   r   r?   r   handle_attribute   s     

	rD   c                 C   s   |  }|d }|r`|d d dks2|d d dkr>|dd S z
t |W S  tk
r\   Y qX n<|d  rxt |d S |d  }|dkrdS |dkrd	S td
| d S )Nr   r   '"r   trueTfalseFz!Invalid attribute predicate: '%s')intr   isdigitlower)r   r   r@   r   r   r   r   rA      s"     
rA   c                    s   |  }g  |d dkr  t|d  | | z
|  }W n tk
rP   Y qY nX |d dkrd|  }|d s
|d dkr
t t| |S q
 fdd}|S )Nr   ]/r   andc                 3   s@   | D ]6}t |f} D ]}||}qt|}|d k	r|V  qd S r   iterr   )r"   r   	subresultr$   predicate_resultselectorr   r   r$      s    

z handle_predicate.<locals>.select)append
operationsr   logical_andr   r+   r   rS   r   r      s    

r   c                    s    fdd}|S )Nc                 3   sX   | D ]N}t |f} D ]}||}qt|}t |f}|d k	r|D ]
}|V  qFqd S r   rO   )r"   r   rQ   r$   rR   Zresult_nodelhs_selects
rhs_selectr   r   r$      s    


zlogical_and.<locals>.selectr   )rY   rZ   r$   r   rX   r   rW      s    
rW   )@ r0   r   z//[notc                    s   t dd t| D  z
 j}W n  tk
r@    fdd}Y nX | }g }z|t|d  || W n tk
r   tdY nX z| }|d dkr| }W qL tk
r   Y qY qLX qL|S )Nc                 S   s    g | ]\}}|s|r||fqS r   r   ).0specialtextr   r   r   
<listcomp>  s    z(_build_path_iterator.<locals>.<listcomp>c                      s   t  S r   )r   r   streamr   r   r   
  s    z#_build_path_iterator.<locals>._nextr   zinvalid pathrM   )rP   path_tokenizerr   r   rU   rV   r   r   )pathr   r   rT   r   rc   r   _build_path_iterator  s(    

rg   c                 C   s(   t |}t| f}|D ]}||}q|S r   )rg   rP   )r   rf   Zselector_chainr"   r$   r   r   r   iterfind  s
    

rh   c                 C   s   t t| |S r   )r   rh   r   rf   r   r   r   
find_first$  s    rj   c                 C   s   t t| |S r   )r   rh   ri   r   r   r   find_all'  s    rk   ) __doc__
__future__r   rerB   sysversion_infostrr=   unicodecompilefindallre   r   r   r   r!   r&   r,   r.   r/   r6   rD   rA   r   rW   rV   r*   rg   rh   rj   rk   r   r   r   r   <module>   sJ    (
 