
    eiJ                     N   d 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 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dS )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                   \     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                       fd|                                 D             }                     ||          \  }}t          t                                         |                                            | _        dS )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.

        c                 \    i | ](\  }}|t          |          rt          ||          n|)S  )r   r   ).0kvselfs      k/var/www/html/volatility/venv/lib/python3.11/site-packages/ccxt/static_dependencies/parsimonious/grammar.py
<dictcomp>z$Grammar.__init__.<locals>.<dictcomp>=   sK     ", ", ",1 +a..?
1a&&&a", ", ",    N)items_expressions_from_rulessuperr   __init__default_rule)r   rules
more_rulesdecorated_custom_rulesexprsfirst	__class__s   `     r   r%   zGrammar.__init__.   s    ", ", ", ","((**", ", ", 33E;QRRugt%%ekkmm444!r!   c                 H    |                                  }||         |_        |S )zAReturn a new Grammar whose :term:`default rule` is ``rule_name``.)_copyr&   )r   	rule_namenews      r   defaultzGrammar.defaultE   s     jjlly>
r!   c                     t                               t                     }t          t           |                              |                                            | 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   r0   r,   s     r   r.   zGrammar._copyK   sL     oog&&gs$$TZZ\\222,
r!   c                 z    t                               |          }t          |                              |          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_rulesX   s3     !!%((<((..t444r!   r   c                 b    |                                   | j                            ||          S )zoParse some text with the :term:`default rule`.

        :arg pos: The index at which to start parsing

        pos)_check_default_ruler&   r6   r   textr>   s      r   r6   zGrammar.parseh   s2     	  """ &&t&555r!   c                 b    |                                   | 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

        r=   )r?   r&   matchr@   s      r   rC   zGrammar.matchq   s2     	  """ &&t&555r!   c                 2    | j         st          d          dS )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{   s5      	M  L M M M	M 	Mr!   c                       j         r j         gng }|                     fd                                 D                        d                    d |D                       S )zbReturn a rule string that, when passed to the constructor, would
        reconstitute the grammar.c              3   .   K   | ]}|j         u|V  d S N)r&   )r   exprr   s     r   	<genexpr>z"Grammar.__str__.<locals>.<genexpr>   s<       4 4d!222 22224 4r!   
c              3   >   K   | ]}|                                 V  d S rI   )as_ruler   rJ   s     r   rK   z"Grammar.__str__.<locals>.<genexpr>   s*      ::D::::::r!   )r&   extendvaluesjoin)r   r*   s   ` r   __str__zGrammar.__str__   s     (,'8@"##b 4 4 4 4dkkmm 4 4 4 	4 	4 	4yy::E::::::r!   c                 F    d                     t          |                     S )z8Return an expression that will reconstitute the grammar.zGrammar({!r}))formatstrrF   s    r   __repr__zGrammar.__repr__   s    %%c$ii000r!   )r   )r   )__name__
__module____qualname____doc__r%   r1   r.   r#   r6   rC   r?   rS   rW   __classcell__)r,   s   @r   r   r      s         8" " " " " ".      5 5 5 6 6 6 66 6 6 6M M M; ; ;1 1 1 1 1 1 1r!   r   c                       e Zd ZdZd ZdS )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                 z    t                               |          }t          |                              |          S rI   )r5   r6   TokenRuleVisitorr8   r9   s       r   r#   z$TokenGrammar._expressions_from_rules   s1    !!%((--33D999r!   NrX   rY   rZ   r[   r#   r   r!   r   r^   r^      s-         : : : : :r!   r^   c                       e Zd ZdZd ZdS )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"          }|                    |          }t                      
                    |          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_allrg   literal~z
[ilmsuxa]*)rp   regexatom
quantifiedterm!not_termsequence/or_termoredr   ruler'   )r   r
   r   r	   r   r   membersr   r6   r7   r8   )r   rule_syntaxr:   re   rh   ri   rk   rl   rm   rn   ro   rr   rt   ru   rv   rw   ry   rz   r|   r}   r   r~   r'   	rule_trees                           r   r#   z,BootstrappingGrammar._expressions_from_rules   sL    9555fw=NOOOS111'#,,99989917KKKUCKKkBBB	eHooq|DDD
!"A.2*.':< < < ,ai@@@ |>>>%	' ' '
 YV<<<dJ\BBB
ZF333GCLL$
CCC {T\1D)D//
CCC73<<DyAAAi00v>>>44lCCC
vz???IdOO'::: KK,,	 }}""9---r!   Nra   r   r!   r   rc   rc      s-         1. 1. 1. 1. 1.r!   rc   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                       e Zd ZdZdZd ZdS )LazyReferencezMA lazy reference to a rule, which we resolve after grokking all the
    rulesr   c                     d| z  S )Nz<LazyReference to %s>r   rF   s    r   _as_rhszLazyReference._as_rhs	  s    '$..r!   N)rX   rY   rZ   r[   rg   r   r   r!   r   r   r     s4          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d ZdS )r7   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                     |pi | _         dS )zConstruct.

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

        N)r:   )r   r:   s     r   r%   zRuleVisitor.__init__  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_parenri   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   rn   symbolri   s        r   visit_quantifierzRuleVisitor.visit_quantifier+  s    	r!   c                 B    |\  }} | j         |j                 |          S rI   )quantifier_classesrA   )r   r   rv   ru   rn   s        r   visit_quantifiedzRuleVisitor.visit_quantified0  s&    %j7t&z7===r!   c                 ,    |\  }}}t          |          S rI   )r   )r   r   lookahead_term	ampersandrw   ri   s         r   visit_lookahead_termz RuleVisitor.visit_lookahead_term4  s    +	4r!   c                 ,    |\  }}}t          |          S rI   )r   )r   r   ry   exclamationrw   ri   s         r   visit_not_termzRuleVisitor.visit_not_term8  s    'T14yyr!   c                      |\  }}}||_         |S )z.Assign a name to the Expression and return it.rf   )r   r   r~   rl   rk   r   s         r   
visit_rulezRuleVisitor.visit_rule<  s    $(!vz
r!   c                 &    |\  }}t          |g|R  S )zfA parsed Sequence looks like [term node, OneOrMore node of
        ``another_term``s]. Flatten it out.)r	   )r   r   rz   rw   other_termss        r   visit_sequencezRuleVisitor.visit_sequenceB  s$     %k+{++++r!   c                 &    |\  }}t          |g|R  S rI   )r
   )r   r   r}   
first_termr   s        r   
visit_oredzRuleVisitor.visit_oredH  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|   slashri   rw   s         r   visit_or_termzRuleVisitor.visit_or_termL  s     !q$r!   c                     |\  }}|j         S )z#Turn a label into a unicode string.)rA   )r   r   rl   rg   ri   s        r   visit_labelzRuleVisitor.visit_labelU  s    ayr!   c                 *    |\  }}t          |          S )zjStick a :class:`LazyReference` in the tree as a placeholder.

        We resolve them all later.

        )r   )r   r   rm   rl   
not_equalss        r   visit_referencezRuleVisitor.visit_referenceZ  s     &zU###r!   c                     |\  }}}}|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)rp   locale	multilinerq   unicodeverboseascii)rA   upperrr   r   )r   r   rt   tilderr   flagsri   patterns           r   visit_regexzRuleVisitor.visit_regexc  ss    #( wq
  ""/W#,%(E\(+u&)Ul&)Ul&)Ul$'5L2 2 2 	2r!   c                 D    t          t          |j                            S )z<Turn a string literal into a ``Literal`` that recognizes it.)r   r   rA   r   ro   visited_childrens      r   visit_spaceless_literalz#RuleVisitor.visit_spaceless_literalq  s    '8'=>>???r!   c                     |\  }}|S )z6Pick just the literal out of a literal-and-junk combo.r   )r   r   rr   ro   ri   s        r   visit_literalzRuleVisitor.visit_literalu  s    &1  r!   c                 
    |p|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_visitz  s      '4'r!   c                 r    t          |t                    rMt          |          }	 |         }n# t          $ r t	          |          w xY w                     |          S t          |dd          r@|vr<                    |           t           fd|j	        D                       |_	        |S )a  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   r   c              3   F   K   | ]}                     |          V  d S rI   )_resolve_refs)r   memberdonerule_mapr   s     r   rK   z,RuleVisitor._resolve_refs.<locals>.<genexpr>  sQ       %A %A)/ &*%7%7&$%O%O %A %A %A %A %A %Ar!   )

isinstancer   rV   KeyErrorr   r   getattraddtupler   )r   r   rJ   r   rl   reffed_exprs   `` `  r   r   zRuleVisitor._resolve_refs  s     dM** 	IIE+&uo + + +$T***+%%hTBBBtY++ AD0@0@ $ %A %A %A %A %A %A37<%A %A %A  A  AKs	   2 Ac                 N    |\  }}t          d |D                                            j                   t                      t           fd                                D                       t          |t                    r|r|d         j                 n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   (   K   | ]}|j         |fV  d S rI   rf   rO   s     r   rK   z*RuleVisitor.visit_rules.<locals>.<genexpr>  s)      CCT	40CCCCCCr!   c              3   T   K   | ]"}|j                             |          fV  #d S rI   )rg   r   )r   rJ   r   r   r   s     r   rK   z*RuleVisitor.visit_rules.<locals>.<genexpr>  sP       > >#' !%	4+=+=hd+S+ST > > > > > >r!   r   N)r   updater:   setrQ   r   listrg   )r   r   
rules_listri   r'   r   r   s   `    @@r   visit_ruleszRuleVisitor.visit_rules  s     5 CCUCCCCC
 	)*** uu > > > > > >+3??+<+<> > > > > 't44I9>I(58=11DHJ 	Jr!   rI   )rX   rY   rZ   r[   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!   r   r7   r7     s^          (jyII1<1GGGzJ/ / / /    
> > >      , , ,/ / /    
$ $ $2 2 2@ @ @! ! !
( ( (   : J  J  J  J  Jr!   r7   c                       e Zd ZdZd Zd ZdS )r`   znA visitor which builds expression trees meant to work on sequences of
    pre-lexed tokens rather than stringsc                 D    t          t          |j                            S )zrTurn a string literal into a ``TokenMatcher`` that matches
        ``Token`` objects by their ``type`` attributes.)r   r   rA   r   s      r   r   z(TokenRuleVisitor.visit_spaceless_literal  s     O,=,BCCD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   rt   r   rr   r   ri   s          r   r   zTokenRuleVisitor.visit_regex  s'    #( wq , - - 	-r!   N)rX   rY   rZ   r[   r   r   r   r!   r   r`   r`     s?        , ,E E E
- - - - -r!   r`   N) r[   collectionsr   
exceptionsr   r   expressionsr   r   r	   r
   r   r   r   r   r   r   r   r   nodesr   utilsr   r   r^   rc   r   rV   r   r7   r`   r5   r   r!   r   <module>r      s3    $ # # # # # 2 2 2 2 2 2 2 2                                  " " " " " "{1 {1 {1 {1 {1k {1 {1 {1|	: 	: 	: 	: 	:7 	: 	: 	::. :. :. :. :.7 :. :. :.@$N/ / / / /C / / /zJ zJ zJ zJ zJ+ zJ zJ zJz- - - - -{ - - -" $#K00
 w{##r!   