
    E#iJ                        S r SSKJr  SSKJrJr  SSKJrJrJ	r	J
r
JrJrJrJrJrJrJrJr  SSKJr  SSKJr   " S S	\5      r " S
 S\5      r " S S\5      rSr " S S\5      r " S S\5      r " S S\5      r\" \5      r\" \5      rg)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   )
BadGrammarUndefinedLabel)LiteralRegexSequenceOneOf	LookaheadOptional
ZeroOrMore	OneOrMoreNotTokenMatcher
expressionis_callable)NodeVisitor)evaluate_stringc                   n   ^  \ rS rSrSrSU 4S jjrS rU 4S jrS rSS jr	SS jr
S	 rS
 rS rSrU =r$ )Grammar   a  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           
        > UR                  5        VVs0 s H$  u  p4U[        U5      (       a  [        XCU 5      OU_M&     nnnU R                  X5      u  pg[        [
        U ]  UR                  5       5        Xpl        gs  snnf )a)  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superr   __init__default_rule)	selfrules
more_ruleskvdecorated_custom_rulesexprsfirst	__class__s	           g/home/james-whalen/.local/lib/python3.13/site-packages/ccxt/static_dependencies/parsimonious/grammar.pyr   Grammar.__init__.   sz    " #((*",* +a..
1&a?* 	 ", 33ERgt%ekkm4!",s   +A>c                 8    U R                  5       nX!   Ul        U$ )zAReturn a new Grammar whose :term:`default rule` is ``rule_name``.)_copyr   )r   	rule_namenews      r'   defaultGrammar.defaultE   s    jjl>
    c                    > [         R                  [         5      n[        [         U]  U R	                  5       5        U R
                  Ul        U$ )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*   Grammar._copyK   s;     oog&gs$TZZ\2,,
r/   c                 `    [         R                  U5      n[        U5      R                  U5      $ )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   Grammar._expressions_from_rulesX   s*     !!%(<(..t44r/   c                 T    U R                  5         U R                  R                  XS9$ )z_Parse some text with the :term:`default rule`.

:arg pos: The index at which to start parsing

pos)_check_default_ruler   r5   r   textr>   s      r'   r5   Grammar.parseh   s*     	  "  &&t&55r/   c                 T    U R                  5         U R                  R                  XS9$ )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

r=   )r?   r   matchr@   s      r'   rD   Grammar.matchq   s*     	  "  &&t&55r/   c                 <    U R                   (       d  [        S5      eg)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?   Grammar._check_default_rule{   s%        L M M !r/   c                    ^  T R                   (       a  T R                   /O/ nUR                  U 4S jT R                  5        5       5        SR                  S U 5       5      $ )zZReturn a rule string that, when passed to the constructor, would
reconstitute the grammar.c              3   J   >#    U  H  nUTR                   Ld  M  Uv   M     g 7fNr   ).0exprr   s     r'   	<genexpr>"Grammar.__str__.<locals>.<genexpr>   s&      4md!2!22 Tms   #	#
c              3   @   #    U  H  oR                  5       v   M     g 7frL   )as_rulerN   rO   s     r'   rP   rQ      s     :EDEs   )r   extendvaluesjoin)r   r$   s   ` r'   __str__Grammar.__str__   sP     (,'8'8""#b 4dkkm 4 	4yy:E:::r/   c                 6    SR                  [        U 5      5      $ )z8Return an expression that will reconstitute the grammar.zGrammar({!r}))formatstrrH   s    r'   __repr__Grammar.__repr__   s    %%c$i00r/   rM   ) )r   )__name__
__module____qualname____firstlineno____doc__r   r-   r*   r   r5   rD   r?   rY   r^   __static_attributes____classcell__)r&   s   @r'   r   r      s;    8".5 66M;1 1r/   r   c                       \ rS rSrSrS rSrg)TokenGrammar   zA 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                 `    [         R                  U5      n[        U5      R                  U5      $ rL   )r4   r5   TokenRuleVisitorr7   r8   s       r'   r   $TokenGrammar._expressions_from_rules   s(    !!%(-33D99r/    Nra   rb   rc   rd   re   r   rf   rn   r/   r'   ri   ri      s    :r/   ri   c                       \ rS rSrSrS rSrg)BootstrappingGrammar   zThe 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           	         [        SSS9n[        [        S5      USS9n[        USS9n[        [	        S5      USS9n[        [        S	5      US
S9n[        U[        U5      SS9n[        [        S5      USS9n	[        SSSSS9n
[        XSS9n[        [	        S5      U[        SSS9USS9n[        XUSS9n[        XSS9n[        XSS9n[        [	        S5      XSS9nU4UR                  -   Ul        [        U[        U5      SS9n[        [	        S5      X_SS9n[        U[        U5      SS9n[        UUUS S9n[        XvUS!S9n[        U[        U5      S"S9nUR                  U5      n[        5       R                  U5      $ )#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_allrv   literal~z
[ilmsuxa]*)r   regexatom
quantifiedterm!not_termsequence/or_termoredr   ruler   )r   r
   r   r	   r   r   membersr   r5   r6   r7   )r   rule_syntaxr9   rt   rw   rx   rz   r{   r|   r}   r~   r   r   r   r   r   r   r   r   r   r   r   r   	rule_trees                           r'   r   ,BootstrappingGrammar._expressions_from_rules   s    95fw=NOS1'#,98917KUCKkB	eHoq|D
!"A.2*.':< ,i@ |>%	'
 YV<d\B
ZF3GCL$
C {T\\1D)D/
C73<yAi0v>44lC
z?IdO': KK,	 }""9--r/   rn   Nro   rn   r/   r'   rq   rq      s    1.r/   rq   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?\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\""is /
                        ~"u?r?'[^'\\\\]*(?:\\\\.[^'\\\\]*)*'"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 = ~"[*+?]" _
    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                   "    \ rS rSrSrSrS rSrg)LazyReferencei  zIA lazy reference to a rule, which we resolve after grokking all the
rulesr`   c                     SU -  $ )Nz<LazyReference to %s>rn   rH   s    r'   _as_rhsLazyReference._as_rhs	  s    '$..r/   rn   N)ra   rb   rc   rd   re   rv   r   rf   rn   r/   r'   r   r     s     D/r/   r   c                       \ rS rSrSr\\\S.r\	R                  =r=rrSS jrS rS rS rS	 rS
 rS rS rS rS rS rS rS rS rS rS rS rS rSr g)r6   i  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                 $    U=(       d    0 U l         g)zConstruct.

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

Nr9   )r   r9   s     r'   r   RuleVisitor.__init__  s     ).Br/   c                     Uu  p4pVnU$ )zTreat a parenthesized subexpression as just its contents.

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

rn   )r   nodeparenthesized
left_parenrx   r   right_parens          r'   visit_parenthesizedRuleVisitor.visit_parenthesized"  s     5B1
zr/   c                     Uu  p4U$ )z5Turn a quantifier into just its symbol-matching node.rn   )r   r   r}   symbolrx   s        r'   visit_quantifierRuleVisitor.visit_quantifier+  s    	r/   c                 H    Uu  p4U R                   UR                     " U5      $ rL   )quantifier_classesrA   )r   r   r   r   r}   s        r'   visit_quantifiedRuleVisitor.visit_quantified0  s$    %&&z7==r/   c                 "    Uu  p4n[        U5      $ rL   )r   )r   r   lookahead_term	ampersandr   rx   s         r'   visit_lookahead_term RuleVisitor.visit_lookahead_term4  s    +	r/   c                 "    Uu  p4n[        U5      $ rL   )r   )r   r   r   exclamationr   rx   s         r'   visit_not_termRuleVisitor.visit_not_term8  s    '14yr/   c                     Uu  p4nX5l         U$ )z.Assign a name to the Expression and return it.ru   )r   r   r   r{   rz   r   s         r'   
visit_ruleRuleVisitor.visit_rule<  s    $(!zr/   c                 "    Uu  p4[        U/UQ76 $ )z^A parsed Sequence looks like [term node, OneOrMore node of
``another_term``s]. Flatten it out.)r	   )r   r   r   r   other_termss        r'   visit_sequenceRuleVisitor.visit_sequenceB  s     %+{++r/   c                 "    Uu  p4[        U/UQ76 $ rL   )r
   )r   r   r   
first_termr   s        r'   
visit_oredRuleVisitor.visit_oredH  s    "&
Z.+..r/   c                     Uu  p4nU$ )zqReturn just the term from an ``or_term``.

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

rn   )r   r   r   slashrx   r   s         r'   visit_or_termRuleVisitor.visit_or_termL  s     !$r/   c                 "    Uu  p4UR                   $ )z#Turn a label into a unicode string.)rA   )r   r   r{   rv   rx   s        r'   visit_labelRuleVisitor.visit_labelU  s    yyr/   c                      Uu  p4[        U5      $ )zZStick a :class:`LazyReference` in the tree as a placeholder.

We resolve them all later.

)r   )r   r   r|   r{   
not_equalss        r'   visit_referenceRuleVisitor.visit_referenceZ  s     &U##r/   c                     Uu  p4pVUR                   R                  5       nUR                  n[        USU;   SU;   SU;   SU;   SU;   SU;   SU;   S9$ )	zReturn a ``Regex`` expression.ILMSUXA)r   locale	multiliner   unicodeverboseascii)rA   upperr   r   )r   r   r   tilder   flagsrx   patterns           r'   visit_regexRuleVisitor.visit_regexc  sf    #( 

  "//W#,%(E\(+u&)Ul&)Ul&)Ul$'5L2 	2r/   c                 >    [        [        UR                  5      5      $ )z<Turn a string literal into a ``Literal`` that recognizes it.)r   r   rA   r   r~   visited_childrens      r'   visit_spaceless_literal#RuleVisitor.visit_spaceless_literalq  s    '8'='=>??r/   c                     Uu  p4U$ )z6Pick just the literal out of a literal-and-junk combo.rn   )r   r   r   r~   rx   s        r'   visit_literalRuleVisitor.visit_literalu  s    &  r/   c                     U=(       d    U$ )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.

rn   )r   r   r   s      r'   generic_visitRuleVisitor.generic_visitz  s      '4'r/   c                 N  ^ ^^ [        U[        5      (       a$  [        U5      n TU   nT R                  TUT5      $ [        USS5      (       a=  UT;  a7  TR                  U5        [        UUU 4S jUR                   5       5      Ul	        U$ ! [         a    [	        U5      ef = f)aT  Return an expression with all its lazy references recursively
resolved.

Resolve any lazy references in the expression ``expr``, recursing into
all subexpressions.

:arg done: The set of Expressions that have already been or are
    currently being resolved, to ward off redundant work and prevent
    infinite recursion for circular refs

r   rn   c              3   J   >#    U  H  nTR                  TUT5      v   M     g 7frL   )_resolve_refs)rN   memberdonerule_mapr   s     r'   rP   ,RuleVisitor._resolve_refs.<locals>.<genexpr>  s+      %A3? &*%7%7&$%O%O3?s    #)

isinstancer   r]   KeyErrorr   r   getattraddtupler   )r   r   rO   r   r{   reffed_exprs   `` `  r'   r   RuleVisitor._resolve_refs  s     dM**IE+&uo %%hTBBtY++D0@ $ %A37<<%A  AK  +$T**+s   B B$c                 .  ^ ^^ Uu  p4[        S U 5       5      mTR                  T R                  5        [        5       m[        UUU 4S jTR	                  5        5       5      mT[        U[        5      (       a  U(       a  TUS   R                     4$ S4$ )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   <   #    U  H  oR                   U4v   M     g 7frL   ru   rU   s     r'   rP   *RuleVisitor.visit_rules.<locals>.<genexpr>  s     CUT		40Us   c              3   b   >#    U  H$  nUR                   TR                  TUT5      4v   M&     g 7frL   )rv   r   )rN   rO   r   r   r   s     r'   rP   r     s0      >+<4 !%		4+=+=hd+ST+<s   ,/r   N)r   updater9   setrW   r   listrv   )r   r   
rules_listrx   r   r   r   s   `    @@r'   visit_rulesRuleVisitor.visit_rules  s      CUCC
 	))* u >+3??+<> > 't44 #58==1 J 	JDHJ 	Jr/   r   rL   )!ra   rb   rc   rd   re   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   rf   rn   r/   r'   r6   r6     s      (jyI1<1G1GGGzJ/
>,/
$2@!
( : Jr/   r6   c                   $    \ rS rSrSrS rS rSrg)rl   i  zjA visitor which builds expression trees meant to work on sequences of
pre-lexed tokens rather than stringsc                 >    [        [        UR                  5      5      $ )zjTurn a string literal into a ``TokenMatcher`` that matches
``Token`` objects by their ``type`` attributes.)r   r   rA   r   s      r'   r   (TokenRuleVisitor.visit_spaceless_literal  s     O,=,B,BCDDr/   c                 "    Uu  p4pV[        S5      e)NzsRegexes do not make sense in TokenGrammars, since TokenGrammars operate on pre-lexed tokens rather than characters.)r   )r   r   r   r   r   r   rx   s          r'   r   TokenRuleVisitor.visit_regex  s    #(  , - 	-r/   rn   N)ra   rb   rc   rd   re   r   r   rf   rn   r/   r'   rl   rl     s    ,E
-r/   rl   N) re   collectionsr   
exceptionsr   r   expressionsr   r   r	   r
   r   r   r   r   r   r   r   r   nodesr   utilsr   r   ri   rq   r   r]   r   r6   rl   r4   rn   r/   r'   <module>r     s    $ 2     "{1k {1|	:7 	::.7 :.@$N/C /zJ+ zJz-{ -" $K0
 {#r/   