U
    e                     @   s   d Z ddlmZ ddlZddlmZ dZejsPze W n e	k
rN   e
ZY nX e ZG dd deZG d	d
 d
eZG dd deZdS )z=
Python Lexical Analyser

Classes for building NFAs and DFAs
    )absolute_importN   )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-7k3cqui1/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   0   s    zMachine.make_initial_statec                 C   s
   | j | S r   r   r
   r   r   r   r   get_initial_state3   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$   6   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   C   s
    zNode.__init__c                 C   s   d | _ d | _d | _d S r   )r*   r-   r.   r	   r   r   r   r   L   s    zNode.destroyc                 C   s   | j || d S r   )r*   add)r
   eventr   r   r   r   add_transitionQ   s    zNode.add_transitionc                 C   s   |  d| dS )z5Add an epsilon-move from this state to another state. N)r1   r   r   r   r   link_toT   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_actionX   s    
zNode.set_actionc                 C   s   | j S r   r-   r	   r   r   r   
get_action`   s    zNode.get_actionc                 C   s   | j S r   )r,   r	   r   r   r   get_action_priorityc   s    zNode.get_action_priorityc                 C   s
   | j d k	S r   r6   r	   r   r   r   is_acceptingf   s    zNode.is_acceptingc                 C   s
   d| j  S )NzState %dr   r	   r   r   r   __str__i   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-   r4   r   r   r   r$   l   s    z	Node.dumpc                 C   s   | j |j k S r   r:   )r
   otherr   r   r   __lt__x   s    zNode.__lt__c                 C   s   t | t@ S r   )idmaxintr	   r   r   r   __hash__{   s    zNode.__hash__N)r&   r'   r(   r)   r   r   r1   r3   r5   r7   r8   r9   r;   r$   r>   rA   r   r   r   r   r   @   s   	r   c                   @   s   e Zd ZdZdd Zdd ZdddZd	d
 Zej	ej
ej
ej
edefddZdd Zdd Zdd Zdd Zej	eejejejejddd Zdd Z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   )r2   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-   )rG   rH   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)code0code1r@   r   c                 C   s\   t |tkrP|\}}|| kr(||d< qX||krX||k rX||t|< |d7 }q0n|||< d S )NrF   r   )typetupleunichr)r
   r   r0   r   r@   rL   rM   r   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 ]\\}}t|dkrX|t|d }|d krLg }||t|< || qt|dkr|||< qi }| jD ]*}|t|d }	|	rx| |	}
|||
< qxt|D ],}
| |
}||
 }|	d||d f  qdD ]*}||d }|r|	d||d f  qd S )Nr      z      %s --> State %d
r   )rC   rD   rE   rF   )
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\   ir   c1c2c                 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   chrrO   )r
   r\   r_   r   rK   r`   ra   r   r   r   rX      s    
zFastMachine.chars_to_rangesc                 C   s   d t| j|S )N,)joinmaprange_to_string)r
   Z
range_listr   r   r   rY      s    zFastMachine.ranges_to_stringc                 C   s0   |\}}||krt |S dt |t |f S d S )Nz%s..%s)rR   )r
   Zrange_tupler`   ra   r   r   r   rh      s    zFastMachine.range_to_string)N)r&   r'   r(   r)   r   r   r   r   cythonlocalsintdictr@   rQ   r   r$   rS   rT   listZ
Py_ssize_tlongrX   rY   rh   r   r   r   r   rB      s   
	

rB   )r)   
__future__r   ri   ZTransitionsr   r@   ZcompiledrP   	NameErrorrd   r+   objectr   r   rB   r   r   r   r   <module>   s   
)@