U
    {h\                     @   sP   d Z ddlZddlmZ dZe ZG dd dZG dd	 d	ZG d
d dZdS )z=
Python Lexical Analyser

Classes for building NFAs and DFAs
    N   )TransitionMapic                   @   sH   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d Z
dS )Machinez1A collection of Nodes representing an NFA or DFA.c                 C   s   g | _ i | _d| _d S )Nr   )statesinitial_statesnext_state_numberself r
   8/tmp/pip-unpacked-wheel-fhl22ezh/Cython/Plex/Machines.py__init__   s    zMachine.__init__c                 C   s   | j D ]}|  qd S N)r   destroyr	   stater
   r
   r   __del__   s    
zMachine.__del__c                 C   s,   t  }| j}|d | _||_| j| |S )z-Add a new state to the machine and return it.r   )Noder   numberr   append)r	   snr
   r
   r   	new_state   s    
zMachine.new_statec                 C   s   |   }| || |S r   )r   make_initial_stater	   namer   r
   r
   r   new_initial_state#   s    zMachine.new_initial_statec                 C   s   || j |< d S r   r   r   r
   r
   r   r   (   s    zMachine.make_initial_statec                 C   s
   | j | S r   r   r	   r   r
   r
   r   get_initial_state+   s    zMachine.get_initial_statec                 C   sd   | d | jd k	rJ| d t| j D ]\}}| d||jf  q,| jD ]}|| qPd S )NzPlex.Machine:
   Initial states:
z      '%s': %d
)writer   sorteditemsr   r   dump)r	   filer   r   r   r
   r
   r   r#   .   s    



zMachine.dumpN)__name__
__module____qualname____doc__r   r   r   r   r   r   r#   r
   r
   r
   r   r      s   	r   c                   @   sp   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d Z
dd Zdd Zdd Zdd Zdd ZdS )r   zA state of an NFA or DFA.c                 C   s$   t  | _t| _d | _d| _d | _d S )Nr   )r   transitionsLOWEST_PRIORITYaction_priorityactionr   epsilon_closurer   r
   r
   r   r   ;   s
    zNode.__init__c                 C   s   d | _ d | _d | _d S r   )r)   r,   r-   r   r
   r
   r   r   D   s    zNode.destroyc                 C   s   | j || d S r   )r)   add)r	   eventr   r
   r
   r   add_transitionI   s    zNode.add_transitionc                 C   s   |  d| dS )z5Add an epsilon-move from this state to another state. N)r0   r   r
   r
   r   link_toL   s    zNode.link_toc                 C   s   || j kr|| _|| _ dS )zMake this an accepting state with the given action. If
        there is already an action, choose the action with highest
        priority.N)r+   r,   )r	   r,   priorityr
   r
   r   
set_actionP   s    
zNode.set_actionc                 C   s   | j S r   r,   r   r
   r
   r   
get_actionX   s    zNode.get_actionc                 C   s   | j S r   )r+   r   r
   r
   r   get_action_priority[   s    zNode.get_action_priorityc                 C   s
   | j d k	S r   r5   r   r
   r
   r   is_accepting^   s    zNode.is_acceptingc                 C   s
   d| j  S )NzState %dr   r   r
   r
   r   __str__a   s    zNode.__str__c                 C   sF   | d| j  | j| | j}| j}|d k	rB| d||f  d S )N   State %d:
z      %s [priority %d]
)r    r   r)   r#   r,   r+   )r	   r$   r,   r3   r
   r
   r   r#   d   s    z	Node.dumpc                 C   s   | j |j k S r   r9   )r	   otherr
   r
   r   __lt__p   s    zNode.__lt__c                 C   s   t | t@ S r   )idmaxintr   r
   r
   r   __hash__s   s    zNode.__hash__N)r%   r&   r'   r(   r   r   r0   r2   r4   r6   r7   r8   r:   r#   r=   r@   r
   r
   r
   r   r   8   s   	r   c                   @   s   e Zd ZdZdd Zdd ZdddZd	d
 Zefe	e
jdddZdd Zdd Zdd Zdd ZeedddZedddZedddZdS ) FastMachinezd
    FastMachine is a deterministic machine represented in a way that
    allows fast scanning.
    c                 C   s(   i | _ g | _d| _d d d d d d| _d S )Nr   )r1   boleoleofelse)r   r   next_numbernew_state_templater   r
   r
   r   r   }   s        zFastMachine.__init__c                 C   s   | j D ]}|  qd S r   )r   clearr   r
   r
   r   r      s    
zFastMachine.__del__Nc                 C   s:   | j }|d | _ | j }||d< ||d< | j| |S )Nr   r   r,   )rF   rG   copyr   r   )r	   r,   r   resultr
   r
   r   r      s    

zFastMachine.new_statec                 C   s   || j |< d S r   r   r   r
   r
   r   r      s    zFastMachine.make_initial_state)r   r?   c                 C   sZ   t |tkrN|\}}|| kr(||d< qV||krVt||D ]}||t|< q:n|||< d S )NrE   )typetuplerangechr)r	   r   r/   r   r?   Zcode0code1coder
   r
   r   add_transitions   s    

zFastMachine.add_transitionsc                 C   s
   | j | S r   r   r   r
   r
   r   r      s    zFastMachine.get_initial_statec                 C   sb   | d | d t| j D ]"\}}| dt||d f  q"| jD ]}| || qLd S )NzPlex.FastMachine:
r   z      %s: %s
r   )r    r!   r   r"   reprr   
dump_state)r	   r$   r   r   r
   r
   r   r#      s    


zFastMachine.dumpc                 C   s@   | d|d   | || |d }|d k	r<| d|  d S )Nr;   r   r,   z	      %s
)r    dump_transitions)r	   r   r$   r,   r
   r
   r   rS      s
    zFastMachine.dump_statec                 C   s  i }i }|  D ]Z\}}t|dkrV|t|}|d krJg }||t|< || qt|dkr|||< qi }| jD ](}|t|}	|	rv| |	}
|||
< qvt|D ],}
| |
}||
 }|	d||d f  qdD ](}||}|r|	d||d f  qd S )Nr      z      %s --> State %d
r   )rB   rC   rD   rE   )
r"   lengetr>   r   r   chars_to_rangesr!   ranges_to_stringr    )r	   r   r$   Zchars_leading_to_stateZspecial_to_statecr   charsZranges_to_state	char_listrangeskeyr
   r
   r   rT      s2    





zFastMachine.dump_transitions)r\   returnc                 C   s   |   d}t|}g }||k r~t|| }|}|d7 }||k rft|| |d krf|d7 }|d7 }q8|t|t|f qt|S )Nr   r   )sortrV   ordr   rN   rL   )r	   r\   ir   rJ   c1c2r
   r
   r   rX      s    
zFastMachine.chars_to_ranges)r_   c                 C   s   d t| j|S )N,)joinmaprange_to_string)r	   Z
range_listr
   r
   r   rY      s    zFastMachine.ranges_to_string)range_tuplec                 C   s*   |\}}||krt |S |d|S d S )Nz..)rR   )r	   ri   rc   rd   r
   r
   r   rh      s    zFastMachine.range_to_string)N)r%   r&   r'   r(   r   r   r   r   r?   dictcythonintrQ   r   r#   rS   rT   listrL   rX   strrY   rh   r
   r
   r
   r   rA   x   s   
	
rA   )	r(   rk   ZTransitionsr   r?   r*   r   r   rA   r
   r
   r
   r   <module>   s   )@