
    'ivO                     ,   d Z ddlmZ ddlmZ ddlmZmZ ddlm	Z	m
Z
mZmZmZmZmZmZmZmZmZmZmZ ddlmZ ddlmZ  G d d	e      Z G d
 de      Z G d de      ZdZ G d de      Z G d de      Z  G d de       Z! ee      Z" ee      Z"y)zA convenience which constructs expression trees from an easy-to-read syntax

Use this unless you have a compelling reason not to; it performs some
optimizations that would be tedious to do when constructing an expression tree
by hand.

    )OrderedDict)dedent)
BadGrammarUndefinedLabel)LiteralRegexSequenceOneOf	Lookahead
QuantifierOptional
ZeroOrMore	OneOrMoreNotTokenMatcher
expressionis_callable)NodeVisitor)evaluate_stringc                   \     e Zd ZdZd fd	Zd Z fdZd ZddZddZ	d Z
d	 Zd
 Z xZS )GrammaraE  A collection of rules that describe a language

    You can start parsing from the default rule by calling ``parse()``
    directly on the ``Grammar`` object::

        g = Grammar('''
                    polite_greeting = greeting ", my good " title
                    greeting        = "Hi" / "Hello"
                    title           = "madam" / "sir"
                    ''')
        g.parse('Hello, my good sir')

    Or start parsing from any of the other rules; you can pull them out of the
    grammar as if it were a dictionary::

        g['title'].parse('sir')

    You could also just construct a bunch of ``Expression`` objects yourself
    and stitch them together into a language, but using a ``Grammar`` has some
    important advantages:

    * Languages are much easier to define in the nice syntax it provides.
    * Circular references aren't a pain.
    * It does all kinds of whizzy space- and time-saving optimizations, like
      factoring up repeated subexpressions into a single object, which should
      increase cache hit ratio. [Is this implemented yet?]

    c           
          |j                         D ci c]   \  }}|t        |      rt        |||       n|" }}}| j                  ||      \  }}t        |   |j                                || _        yc c}}w )ay  Construct a grammar.

        :arg rules: A string of production rules, one per line.
        :arg default_rule: The name of the rule invoked when you call
            :meth:`parse()` or :meth:`match()` on the grammar. Defaults to the
            first rule. Falls back to None if there are no string-based rules
            in this grammar.
        :arg more_rules: Additional kwargs whose names are rule names and
            values are Expressions or custom-coded callables which accomplish
            things the built-in rule syntax cannot. These take precedence over
            ``rules`` in case of naming conflicts.

        N)itemsr   r   _expressions_from_rulessuper__init__default_rule)	selfrules
more_ruleskvdecorated_custom_rulesexprsfirst	__class__s	           E/var/www/br/venv/lib/python3.12/site-packages/parsimonious/grammar.pyr   zGrammar.__init__/   s    " #((*",1 +a.
1a&a?", ", 33E;QRu'!",s   %A7c                 :    | j                         }||   |_        |S )zAReturn a new Grammar whose :term:`default rule` is ``rule_name``.)_copyr   )r   	rule_namenews      r'   defaultzGrammar.defaultF   s    jjly>
    c                     t         j                  t               }t        t         |  | j	                                | j
                  |_        |S )zReturn a shallow copy of myself.

        Deep is unnecessary, since Expression trees are immutable. Subgrammars
        recreate all the Expressions from scratch, and AbstractGrammars have
        no Expressions.

        )r   __new__r   r   r   r   )r   r+   r&   s     r'   r)   zGrammar._copyL   s;     oog&gs$TZZ\2,,
r-   c                 `    t         j                  |      }t        |      j                  |      S )a  Return a 2-tuple: a dict of rule names pointing to their
        expressions, and then the first rule.

        It's a web of expressions, all referencing each other. Typically,
        there's a single root to the web of references, and that root is the
        starting symbol for parsing, but there's nothing saying you can't have
        multiple roots.

        :arg custom_rules: A map of rule names to custom-coded rules:
            Expressions

        )rule_grammarparseRuleVisitorvisitr   r   custom_rulestrees       r'   r   zGrammar._expressions_from_rulesY   s*     !!%(<(..t44r-   c                 \    | j                          | j                  j                  ||      S )zoParse some text with the :term:`default rule`.

        :arg pos: The index at which to start parsing

        pos)_check_default_ruler   r2   r   textr:   s      r'   r2   zGrammar.parsei   s,     	  "  &&t&55r-   c                 \    | j                          | j                  j                  ||      S )zParse some text with the :term:`default rule` but not necessarily
        all the way to the end.

        :arg pos: The index at which to start parsing

        r9   )r;   r   matchr<   s      r'   r?   zGrammar.matchr   s,     	  "  &&t&55r-   c                 2    | j                   st        d      y)z7Raise RuntimeError if there is no default rule defined.zCan't call parse() on a Grammar that has no default rule. Choose a specific rule instead, like some_grammar['some_rule'].parse(...).N)r   RuntimeErrorr   s    r'   r;   zGrammar._check_default_rule|   s%        L M M !r-   c                       j                   r j                   gng }|j                   fd j                         D               dj                  d |D              S )zbReturn a rule string that, when passed to the constructor, would
        reconstitute the grammar.c              3   >   K   | ]  }|j                   ur|  y wN)r   ).0exprr   s     r'   	<genexpr>z"Grammar.__str__.<locals>.<genexpr>   s&      4d!2!22  4s   
c              3   <   K   | ]  }|j                           y wrE   )as_rulerF   rG   s     r'   rH   z"Grammar.__str__.<locals>.<genexpr>   s     :D:s   )r   extendvaluesjoin)r   r$   s   ` r'   __str__zGrammar.__str__   sP     (,'8'8""#b 4dkkm 4 	4yy:E:::r-   c                 6    dj                  t        |             S )z8Return an expression that will reconstitute the grammar.zGrammar({!r}))formatstrrB   s    r'   __repr__zGrammar.__repr__   s    %%c$i00r-   ) )r   )__name__
__module____qualname____doc__r   r,   r)   r   r2   r?   r;   rP   rT   __classcell__)r&   s   @r'   r   r      s6    8".5 66M;1r-   r   c                       e Zd ZdZd Zy)TokenGrammarzA Grammar which takes a list of pre-lexed tokens instead of text

    This is useful if you want to do the lexing yourself, as a separate pass:
    for example, to implement indentation-based languages.

    c                 `    t         j                  |      }t        |      j                  |      S rE   )r1   r2   TokenRuleVisitorr4   r5   s       r'   r   z$TokenGrammar._expressions_from_rules   s(    !!%(-33D99r-   NrV   rW   rX   rY   r    r-   r'   r\   r\      s    :r-   r\   c                       e Zd ZdZd Zy)BootstrappingGrammara  The grammar used to recognize the textual rules that describe other
    grammars

    This grammar gets its start from some hard-coded Expressions and claws its
    way from there to an expression tree that describes how to parse the
    grammar description syntax.

    c                    t        dd      }t        t        d      |d      }t        |d      }t        t	        d      |d      }t        t        d	      |d
      }t        |t        |      d      }t        t        d      |d      }	t        dddd      }
t        |
|d      }t        t	        d      |t        dd      |d      }t        |||d      }t        ||	d      }t        ||d      }t        t	        d      ||d      }|f|j                  z   |_        t        |t        |      d      }t        t	        d      ||d      }t        |t        |      d      }t        |||d       }t        |||d!      }t        |t        |      d"      }|j                  |      }t               j                  |      S )#zReturn the rules for parsing the grammar definition syntax.

        Return a 2-tuple: a dict of rule names pointing to their expressions,
        and then the top-level expression for the first rule.

        z	#[^\r\n]*commentnamez\s+meaninglessness_=equalsz[a-zA-Z_][a-zA-Z_0-9]*label	referencez[*+?]
quantifierzu?r?"[^"\\]*(?:\\.[^"\\]*)*"Tspaceless_literal)ignore_casedot_allrf   literal~z
[ilmsuxa]*)ro   regexatom
quantifiedterm!not_termsequence/or_termoredr   ruler   )r   r
   r   r	   r   r   membersr   r2   r3   r4   )r   rule_syntaxr6   rd   rg   rh   rj   rk   rl   rm   rn   rq   rs   rt   ru   rv   rx   ry   r{   r|   r   r}   r   	rule_trees                           r'   r   z,BootstrappingGrammar._expressions_from_rules   s    95fw=NOS1'#,98917KUCKkB	eHoq|D
!"A.2*.':< ,ai@ |>%	'
 YV<dJ\B
ZF3GCL$
C {T\\1D)D/
C73<DyAi0v>44lC
vz?IdO': KK,	 }""9--r-   Nr_   r`   r-   r'   rb   rb      s    1.r-   rb   a+  
    # Ignored things (represented by _) are typically hung off the end of the
    # leafmost kinds of nodes. Literals like "/" count as leaves.

    rules = _ rule*
    rule = label equals expression
    equals = "=" _
    literal = spaceless_literal _

    # So you can't spell a regex like `~"..." ilm`:
    spaceless_literal = ~"u?r?b?\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\""is /
                        ~"u?r?b?'[^'\\\\]*(?:\\\\.[^'\\\\]*)*'"is

    expression = ored / sequence / term
    or_term = "/" _ term
    ored = term or_term+
    sequence = term term+
    not_term = "!" term _
    lookahead_term = "&" term _
    term = not_term / lookahead_term / quantified / atom
    quantified = atom quantifier
    atom = reference / literal / regex / parenthesized
    regex = "~" spaceless_literal ~"[ilmsuxa]*"i _
    parenthesized = "(" _ expression ")" _
    quantifier = ~r"[*+?]|\{\d*,\d+\}|\{\d+,\d*\}|\{\d+\}" _
    reference = label !equals

    # A subsequent equal sign is the only thing that distinguishes a label
    # (which begins a new rule) from a reference (which is just a pointer to a
    # rule defined somewhere else):
    label = ~"[a-zA-Z_][a-zA-Z_0-9]*(?![\"'])" _

    # _ = ~r"\s*(?:#[^\r\n]*)?\s*"
    _ = meaninglessness*
    meaninglessness = ~r"\s+" / comment
    comment = ~r"#[^\r\n]*"
    c                        e Zd ZdZdZd Zd Zy)LazyReferencezMA lazy reference to a rule, which we resolve after grokking all the
    rulesrU   c                     t               }| }	 ||v rt        d| j                   d|  d      |j                  |       	 |t	        |         }t        |t              s|S S# t
        $ r t        |      w xY w)a  
        Traverse the rule map following top-level lazy references,
        until we reach a cycle (raise an error) or a concrete expression.

        For example, the following is a circular reference:
            foo = bar
            baz = foo2
            foo2 = foo

        Note that every RHS of a grammar rule _must_ be either a
        LazyReference or a concrete expression, so the reference chain will
        eventually either terminate or find a cycle.
        zCircular Reference resolving ri   .)	setr   rf   addrS   KeyErrorr   
isinstancer   )r   rule_mapseencurs       r'   resolve_refszLazyReference.resolve_refs	  s     ud{ #@1TFRS!TUU*s3x( c=1
   *$S))*s    A! !A6c                     d| z  S )Nz<LazyReference to %s>r`   rB   s    r'   _as_rhszLazyReference._as_rhs&  s    &--r-   N)rV   rW   rX   rY   rf   r   r   r`   r-   r'   r   r     s     D:.r-   r   c                       e Zd ZdZeeedZej                  xZ
xZZddZd Zd Zd Zd Zd	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zy)r3   zTurns a parse tree of a grammar definition into a map of ``Expression``
    objects

    This is the magic piece that breathes life into a parsed bunch of parse
    rules, allowing them to go forth and parse other things.

    )?*+Nc                 (    |xs i | _         d| _        y)zConstruct.

        :arg custom_rules: A dict of {rule name: expression} holding custom
            rules which will take precedence over the others

        N)r6   _last_literal_node_and_type)r   r6   s     r'   r   zRuleVisitor.__init__6  s     ).B+/(r-   c                     |\  }}}}}|S )zTreat a parenthesized subexpression as just its contents.

        Its position in the tree suffices to maintain its grouping semantics.

        r`   )r   nodeparenthesized
left_parenrh   r   right_parens          r'   visit_parenthesizedzRuleVisitor.visit_parenthesized@  s     5B1
Az;r-   c                     |\  }}|S )z5Turn a quantifier into just its symbol-matching node.r`   )r   r   rm   symbolrh   s        r'   visit_quantifierzRuleVisitor.visit_quantifierI  s    	r-   c                 f   |\  }}	  | j                   |j                     |      S # t        $ r |j                  dd j                  d      }t	        |      dk(  rt        |d         x}}n3|d   rt        |d         nd}|d   rt        |d         n
t        d      }t        |||      cY S w xY w)N   ,r   inf)minmax)quantifier_classesr=   r   splitlenintfloatr   )r   r   ru   rt   rm   	min_match	max_matchs          r'   visit_quantifiedzRuleVisitor.visit_quantifiedN  s    %j
	B;4**:??;DAA 	B#2.44S9J:!#(+JqM(::	I2<Q-C
1.Q	2<Q-C
1.U5\	d	yAA	Bs   & BB0/B0c                 $    |\  }}}t        |      S rE   )r   )r   r   lookahead_term	ampersandrv   rh   s         r'   visit_lookahead_termz RuleVisitor.visit_lookahead_term\  s    +	4r-   c                 $    |\  }}}t        |      S rE   )r   )r   r   rx   exclamationrv   rh   s         r'   visit_not_termzRuleVisitor.visit_not_term`  s    'T14yr-   c                      |\  }}}||_         |S )z.Assign a name to the Expression and return it.re   )r   r   r}   rk   rj   r   s         r'   
visit_rulezRuleVisitor.visit_ruled  s    $(!vz
r-   c                 $    |\  }}t        |g| S )zfA parsed Sequence looks like [term node, OneOrMore node of
        ``another_term``s]. Flatten it out.)r	   )r   r   ry   rv   other_termss        r'   visit_sequencezRuleVisitor.visit_sequencej  s     %k+{++r-   c                 $    |\  }}t        |g| S rE   )r
   )r   r   r|   
first_termr   s        r'   
visit_oredzRuleVisitor.visit_oredp  s    "&
KZ.+..r-   c                     |\  }}}|S )zReturn just the term from an ``or_term``.

        We already know it's going to be ored, from the containing ``ored``.

        r`   )r   r   r{   slashrh   rv   s         r'   visit_or_termzRuleVisitor.visit_or_termt  s     !q$r-   c                 $    |\  }}|j                   S )z#Turn a label into a unicode string.)r=   )r   r   rk   rf   rh   s        r'   visit_labelzRuleVisitor.visit_label}  s    ayyr-   c                 "    |\  }}t        |      S )zjStick a :class:`LazyReference` in the tree as a placeholder.

        We resolve them all later.

        )r   )r   r   rl   rk   
not_equalss        r'   visit_referencezRuleVisitor.visit_reference  s     &zU##r-   c                     |\  }}}}|j                   j                         }|j                  }t        |d|v d|v d|v d|v d|v d|v d|v       S )	zReturn a ``Regex`` expression.ILMSUXA)ro   locale	multilinerp   unicodeverboseascii)r=   upperrq   r   )r   r   rs   tilderq   flagsrh   patterns           r'   visit_regexzRuleVisitor.visit_regex  sj    #( wq

  "//W#,%(E\(+u&)Ul&)Ul&)Ul$'5L2 	2r-   c                 4   t        |j                        }| j                  r[| j                  \  }}|t        |      k7  r>t	        t        d|j                   d| d|j                   dt        |       d	            |t        |      f| _        t        |      S )z<Turn a string literal into a ``Literal`` that recognizes it.z                    Found z (z) and zq) string literals.
                    All strings in a single grammar must be of the same type.
                )r   r=   r   typer   r   r   )r   rn   visited_childrenliteral_value	last_node	last_types         r'   visit_spaceless_literalz#RuleVisitor.visit_spaceless_literal  s    '(9(>(>?++#'#C#C IyD//  -$>>*"YKv>O>T>T=UUWX\]jXkWl m) "   ,=d=>Q+Q(}%%r-   c                     |\  }}|S )z6Pick just the literal out of a literal-and-junk combo.r`   )r   r   rq   rn   rh   s        r'   visit_literalzRuleVisitor.visit_literal  s    &1  r-   c                     |xs |S )a   Replace childbearing nodes with a list of their children; keep
        others untouched.

        For our case, if a node has children, only the children are important.
        Otherwise, keep the node around for (for example) the flags of the
        regex rule. Most of these kept-around nodes are subsequently thrown
        away by the other visitor methods.

        We can't simply hang the visited children off the original node; that
        would be disastrous if the node occurred in more than one place in the
        tree.

        r`   )r   r   r   s      r'   generic_visitzRuleVisitor.generic_visit  s      '4'r-   c                 <   |\  }}t        d |D              }|j                  | j                         t        |j	                               D ]&  \  }}t        |d      s|j                  |      ||<   ( |t        |t              r|r||d   j                     fS dfS )a  Collate all the rules into a map. Return (map, default rule).

        The default rule is the first one. Or, if you have more than one rule
        of that name, it's the last-occurring rule of that name. (This lets you
        override the default rule when you extend a grammar.) If there are no
        string-based rules, the default rule is None, because the custom rules,
        due to being kwarg-based, are unordered.

        c              3   8   K   | ]  }|j                   |f  y wrE   re   rL   s     r'   rH   z*RuleVisitor.visit_rules.<locals>.<genexpr>  s     CT		40Cs   r   r   N)	r   updater6   listr   hasattrr   r   rf   )r   r   
rules_listrh   r   r   rf   r}   s           r'   visit_ruleszRuleVisitor.visit_rules  s     5 CUCC
 	))* x~~/0 	=JD$t^, "&!2!28!<		= 't4 #58==1 J 	JDHJ 	Jr-   rE   )rV   rW   rX   rY   r   r   r   r   r   
lift_childvisit_expression
visit_term
visit_atomr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r`   r-   r'   r3   r3   *  s      (jyI1<1G1GGGzJ0
B,/
$2& !
( "Jr-   r3   c                       e Zd ZdZd Zd Zy)r^   znA visitor which builds expression trees meant to work on sequences of
    pre-lexed tokens rather than stringsc                 >    t        t        |j                              S )zrTurn a string literal into a ``TokenMatcher`` that matches
        ``Token`` objects by their ``type`` attributes.)r   r   r=   )r   rn   r   s      r'   r   z(TokenRuleVisitor.visit_spaceless_literal  s     O,=,B,BCDDr-   c                 &    |\  }}}}t        d      )NzsRegexes do not make sense in TokenGrammars, since TokenGrammars operate on pre-lexed tokens rather than characters.)r   )r   r   rs   r   rq   r   rh   s          r'   r   zTokenRuleVisitor.visit_regex  s"    #( wq , - 	-r-   N)rV   rW   rX   rY   r   r   r`   r-   r'   r^   r^     s    ,E
-r-   r^   N)#rY   collectionsr   textwrapr   parsimonious.exceptionsr   r   parsimonious.expressionsr   r   r	   r
   r   r   r   r   r   r   r   r   r   parsimonious.nodesr   parsimonious.utilsr   r   r\   rb   r   rS   r   r3   r^   r1   r`   r-   r'   <module>r      s    $  >    + .{1k {1|	:7 	::.7 :.@$N$.C $.NvJ+ vJr-{ -" $K0
 {#r-   