
    G@d&                     8    d Z dZd ZedfdZd Zd Zd Zd Zd	S )
z
LL(1) predictive parser for snippets CFG grammar.

Aho, Sethi, Ullman
Compilers: Principles, Techniques, and Tools, Addison-Wesley, 1986
a(  
START -> EXPRLIST
EXPRLIST -> EXPR MOREEXPR
MOREEXPR -> EXPR MOREEXPR | EPSILON

EXPR -> SNIPPET | ANY
TEXT_SNIPPETS -> MOREEXPR

TEXT -> ANY MOREANY
MOREANY -> ANY MOREANY | EPSILON

TEXT_NO_COL -> ANY_NO_COL MORE_ANY_NO_COL
MORE_ANY_NO_COL -> ANY_NO_COL MORE_ANY_NO_COL | EPSILON

TEXT_COL -> ANY_COL MORE_COL
MORE_COL -> ANY_COL MORE_COL | EPSILON

TEXT_REGEX -> ANY_REGEX MORE_REGEX
MORE_REGEX -> ANY_REGEX MORE_REGEX | EPSILON

TEXT_FORMAT -> ANY FOLLOW_ANY
FOLLOW_ANY -> ANY FOLLOW_ANY | EPSILON

ANY_REGEX -> ANY | dollar

ANY -> ANY_COL | ,
ANY_COL -> ANY_NO_COL | COLONS
ANY_NO_COL -> name | int | case | SYMBOLS | whitespace | left_curly_name
COLONS -> : | :+ | :- | :?
SYMBOLS ->  \: | \$ | text_pipe | { | \} | \ | \/ | \, | symbol

SNIPPET -> dollar SNIPPETBODY
SNIPPETBODY -> SNIPPETID | INTSNIPPET | VARSNIPPET

INTSNIPPET -> int | { int INTSNIPPETBODY }
INTSNIPPETBODY -> COLONBODY | PIPEBODY | EPSILON
COLONBODY -> : TEXT_SNIPPETS
PIPEBODY -> pipe TEXTSEQ pipe

TEXTSEQ -> TEXT_COL MORETEXT
MORETEXT -> , TEXT_COL MORETEXT | EPSILON

VARSNIPPET -> left_curly_name VARSNIPPETBODY } | name
VARSNIPPETBODY -> COLONBODY | REGEXBODY | EPSILON
REGEXBODY -> / REGEX / FORMATTEXT / OPTIONS

REGEX -> TEXT_REGEX | EPSILON
OPTIONS -> TEXT_REGEX | EPSILON

FORMATTEXT -> FORMAT MOREFORMAT
MOREFORMAT -> FORMAT MOREFORMAT | EPSILON
FORMAT -> FORMATEXPR | TEXT_FORMAT

FORMATTEXT_NO_COL -> FORMAT_NO_COL MOREFORMAT_NO_COL
MOREFORMAT_NO_COL -> FORMAT_NO_COL MOREFORMAT_NO_COL | EPSILON
FORMAT_NO_COL -> FORMATEXPR | TEXT_NO_COL

FORMATEXPR -> dollar FORMATBODY

FORMATBODY -> int | { int FORMATOPTIONS }
FORMATOPTIONS -> CASEOPTS | IFOPTS | IFELSEOPTS | ELSEOPTS | EPSILON

CASEOPTS -> : FORMATTEXT
IFOPTS -> :+ FORMATTEXT
IFELSEOPTS -> :? FORMATTEXT_NO_COL : FORMATTEXT
ELSEOPTS -> PROLOGFUNCT FORMATTEXT
PROLOGFUNCT -> : | :-
c                 `   |                                                                  }d |D             }i } |D ]v}|                    d          \  }}|                    d          }g }|D ]=}|                                                                 }|                    |           >|| |<   w| S )Nc                 B    g | ]}|d k    |                                 S ) )strip).0lines     <lib/python3.11/site-packages/spyder/utils/snippets/parser.py
<listcomp>z'_preprocess_grammar.<locals>.<listcomp>Y   s%    JJJdtrzzTZZ\\zzz    z -> z | )r   
splitlinessplitappend)grammargrammar_linesr   production_namerulesproductionsrule
rule_partss           r   _preprocess_grammarr   W   s    MMOO..00MJJmJJJMG / /!%F!3!3E"" 	+ 	+D++--Jz****#.  Nr
   STARTc                 ^   t          |           } t          |           }i }|D ]1}t          t          d ||         D                                 ||<   2t	          | ||          }i }|D ]>}i ||<   ||         D ].\  }}}	|dk    r|	||         |<   ||         D ]}
g ||         |
<   /?| |||fS )z/Create LL(1) parsing table for a given grammar.c                     g | ]
}|d          S )    )r   is     r   r	   z,create_LL1_parsing_table.<locals>.<listcomp>l   s    888!888r
   EPSILON)r   first_no_epsilonlistsetfollow)r   starting_rulefnefirstr   follow_rulesparse_table_sym
production
follow_syms              r   create_LL1_parsing_tabler*   f   s   !'**G
7
#
#CE ; ;388c$i88899::d'5-88LK 7 7D"%d) 	7 	7AsJi)3D!#&&".t"4 7 7J46K%j117		7 C{22r
   c                 6    i }| D ]}t          | ||          }|S )z)Compute FIRST sets for all grammar rules.)r#   )r   r"   r   s      r   r   r   z   s.    
C ( (GT3''Jr
   c                 d   g }||vr| |         D ]}d}|D ]z}|| vr|                     |||f           d} nY|d         }t          | ||          }d}||         D ]*\  }	}
}	|
dk    r|                     ||
|f           %|dz  }+|dk    rd} n{|r|                     |d|f           |||<   |S )a  
    Compute FIRST set for a given rule.

    The first set of a sequence of symbols u, written as First(u) is the set
    of terminals which start the sequences of symbols derivable from u.
    A bit more formally, consider all strings derivable from u. If u =>* v,
    where v begins with some terminal, that terminal is in First(u).
    If u =>* epsilon, then epsilon is in First(u).
    TF    r   r   )r   r#   )r   r   r"   	first_setr   epsilon_foundr(   first_productionnum_epsilonr&   r'   s              r   r#   r#      s,    I3"4= 	A 	AK M)  
W,,$$dJ%DEEE$)ME (31~$S99C"#K%()9%: - -	3)++%,,dC-EFFFF'1,KK"a''(- (  A  $	;!?@@@D	Jr
   c           	         i }i }dg||<   | D ]c}g }| D ]W}||k    r	t          | |                   D ]8\  }}	t          |	          D ]#\  }
}||k    r|                    |||
f           $9X|||<   d| D ]}t          | |||||          }|S )z*Compute FOLLOW sets for all grammar rules.z<eof>)	enumerater   _follow)r   r"   r!   r    positionrule1rule1_positionrule2r   r   jr(   r   s                r   r    r       s    FH$IF= 	) 	) 	= 	=E~~"+GEN";"; = =;%.{%;%; = =MAz!U**&--uam<<<== ) N N#tVX}MMMr
   c           	         g }||vs||k    r||k    r||         }||         D ]\  }}}	| |         |         }
|	t          |
          dz
  k     rf|
|	dz            }|| v rAd ||         D             }||z  }d||         v rt          | |||||          }|||         z  }z|                    |           t          | |||||          }|||         z  }t          t	          |                    ||<   |S )aD  
    Compute FOLLOW set for a grammar rule.

    The follow set of a nonterminal A is the set of terminal symbols that can
    appear immediately to the right of A in a valid sentence.
    A bit more formally, for every valid sentence S =>* uAv, where v begins
    with some terminal, and that terminal is in Follow(A).
    r   c                     g | ]
}|d k    |S )r   r   )r   xs     r   r	   z_follow.<locals>.<listcomp>   s(     ': ': ':Q*+y.. ()*8..r
   r   )lenr4   r   r   r   )r   r"   r   r    r5   r!   rule_followderived_ruler   r9   r(   	next_rulenext_rule_firsts                r   r4   r4      sV    K6T]22=   ,K"*4. 	4 	4L!Q .q1J3z??Q&&&&q1u-	''': ':#i. ': ': ':O?2K C	N22!(#|)/="J "J#vl';;&&y1111 #|!'=B Bvl33C,,--tMr
   N)__doc__GRAMMARr   r*   r   r#   r    r4   r   r
   r   <module>rD      s    CL   &-G 3 3 3 3(  $ $ $N  *! ! ! ! !r
   