ó
    ‰*£hð:  ã                   óN   • S r SSKr " S S\5      r " S S5      r " S S5      rg)	zÇ
This module contains a tokenizer for Excel formulae.

The tokenizer is based on the Javascript tokenizer found at
http://ewbi.blogs.com/develops/2004/12/excel_formula_p.html written by Eric
Bachtal
é    Nc                   ó   • \ rS rSrSrSrg)ÚTokenizerErroré   z$Base class for all Tokenizer errors.© N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú__static_attributes__r   ó    ÚW/home/mande/repo/quber/.venv/lib/python3.13/site-packages/openpyxl/formula/tokenizer.pyr   r      s   † Ü.r   r   c                   ó
  • \ rS rSrSr\R                  " S5      r\R                  " S5      r\R                  " S5      \R                  " S5      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S jrS rS rSrg)Ú	Tokenizeré   aB  
A tokenizer for Excel worksheet formulae.

Converts a str string representing an Excel formula (in A1 notation)
into a sequence of `Token` objects.

`formula`: The str string to tokenize

Tokenizer defines a method `._parse()` to parse the formula into tokens,
which can then be accessed through the `.items` attribute.

z^[1-9](\.[0-9]+)?[Ee]$z[ \n]+z"(?:[^"]*"")*[^"]*"(?!")z'(?:[^']*'')*[^']*'(?!')©Ú"Ú')z#NULL!z#DIV/0!z#VALUE!z#REF!z#NAME?z#NUM!z#N/Az#GETTING_DATAz,;}) +-*/^&=><%c                 óh   • Xl         / U l        / U l        SU l        / U l        U R                  5         g )Nr   )ÚformulaÚitemsÚtoken_stackÚoffsetÚtokenÚ_parse)Úselfr   s     r   Ú__init__ÚTokenizer.__init__.   s-   € ØŒØˆŒ
ØˆÔàˆŒØˆŒ
Ø�‰�r   c           
      ó\  • U R                   (       a  gU R                  (       d  gU R                  S   S:X  a  U =R                   S-  sl         O>U R                  R                  [	        U R                  [        R
                  5      5        gSU R                  4SU R                  4SU R                  4SU R                  4S	U R                  4S
U R                  4SU R                  4SU R                  4SU R                  44	n0 nU H)  u  p4UR                  [        R!                  X45      5        M+     U R                   [#        U R                  5      :  aÆ  U R%                  5       (       a  M:  U R                  U R                      nXPR&                  ;   a  U R)                  5         XR;   a  U =R                   X%   " 5       -  sl         O0U R*                  R                  U5        U =R                   S-  sl         U R                   [#        U R                  5      :  a  MÆ  U R)                  5         g)z5Populate self.items with the tokens from the formula.Nr   Ú=é   z"'Ú[Ú#Ú Ú
z
+-*/^&=><%z{(ú)}z;,)r   r   r   ÚappendÚTokenÚLITERALÚ_parse_stringÚ_parse_bracketsÚ_parse_errorÚ_parse_whitespaceÚ_parse_operatorÚ_parse_openerÚ_parse_closerÚ_parse_separatorÚupdateÚdictÚfromkeysÚlenÚcheck_scientific_notationÚTOKEN_ENDERSÚ
save_tokenr   )r   Ú	consumersÚ
dispatcherÚcharsÚconsumerÚ	curr_chars         r   r   ÚTokenizer._parse7   sµ  € à�;�;ØØ�|�|ØØ�\‰\˜!‰_ Ó#Ø�KŠK˜1ÑŽKà�J‰J×Ñœe D§L¡L´%·-±-Ó@ÔAØà�D×&Ñ&Ð'Ø�$×&Ñ&Ð'Ø�$×#Ñ#Ð$Ø�$×(Ñ(Ð)Ø�4×)Ñ)Ð*Ø˜4×/Ñ/Ð0Ø�4×%Ñ%Ð&Ø�4×%Ñ%Ð&Ø�4×(Ñ(Ð)ð

ˆ	ð ˆ
Û(‰OˆEØ×ÑœdŸm™m¨EÓ<Ö=ñ  )à�k‰kœC §¡Ó-Ó-Ø×-Ñ-×/Ñ/ÙØŸ™ T§[¡[Ñ1ˆIØ×-Ñ-Ó-Ø—‘Ô!ØÓ&Ø—’˜zÒ4Ó6Ñ6–ð —
‘
×!Ñ! )Ô,Ø—’˜qÑ •ð �k‰kœC §¡Ó-Õ-ð 	�‰Õr   c                 óø  • U R                  SS9  U R                  U R                     nUS;   d   eU R                  U   nUR	                  U R                  U R                  S 5      nUc%  US:X  a  SOSn[        SU S	U R                   35      eUR                  S
5      nUS:X  a/  U R                  R                  [        R                  U5      5        OU R                  R                  U5        [        U5      $ )ay  
Parse a "-delimited string or '-delimited link.

The offset must be pointing to either a single quote ("'") or double
quote ('"') character. The strings are parsed according to Excel
rules where to escape the delimiter you just double it up. E.g.,
"abc""def" in Excel is parsed as 'abc"def' in Python.

Returns the number of characters matched. (Does not update
self.offset)

Ú:©Ú
can_followr   Nr   ÚstringÚlinkz%Reached end of formula while parsing z in r   )Úassert_empty_tokenr   r   ÚSTRING_REGEXESÚmatchr   Úgroupr   r'   r(   Úmake_operandr   r5   )r   ÚdelimÚregexrG   Úsubtypes        r   r*   ÚTokenizer._parse_string_   sã   € ð 	×Ñ¨3ÐÑ/Ø—‘˜TŸ[™[Ñ)ˆØ˜
Ó"Ð"Ð"Ø×#Ñ# EÑ*ˆØ—‘˜DŸL™L¨¯©¨Ð6Ó7ˆØ‰=Ø"'¨3£,‘h°FˆGÜ Ð#HÈÈ	ÐQUÐVZ×VbÑVbÐUcÐ!dÓeÐeØ—‘˜A“ˆØ�C‹<Ø�J‰J×Ñœe×0Ñ0°Ó7Õ8à�J‰J×Ñ˜eÔ$Ü�5‹zÐr   c                 óŒ  • U R                   U R                     S:X  d   e[        R                  " SU R                   U R                  S 5       Vs/ s H  oR	                  5       S4PM     nn[        R                  " SU R                   U R                  S 5       Vs/ s H  oR	                  5       S4PM     nnSn[        X#-   5       HW  u  pVXF-  nUS:X  d  M  US-   nU R                  R                  U R                   U R                  U R                  U-    5        Us  $    [        SU R                    35      es  snf s  snf )	z|
Consume all the text between square brackets [].

Returns the number of characters matched. (Does not update
self.offset)

r"   z\[Nr!   z\]éÿÿÿÿr   zEncountered unmatched '[' in )	r   r   ÚreÚfinditerÚstartÚsortedr   r'   r   )r   ÚtÚleftsÚrightsÚ
open_countÚidxÚ
open_closeÚouter_rights           r   r+   ÚTokenizer._parse_brackets{   s4  € ð �|‰|˜DŸK™KÑ(¨CÓ/Ð/Ð/ä—’˜U D§L¡L°·±°Ð$>Ô?óAÚ?ð %&—'‘'“)˜Q“Ù?ð 	ð Aô —+’+˜e T§\¡\°$·+±+°,Ð%?Ô@óBÚ@ð '(—7‘7“9˜b“/Ù@ð 	ð Bð ˆ
Ü% e¡nÖ5‰OˆCØÑ$ˆJØ˜Q�Ø! A™g�Ø—
‘
×!Ñ!Ø—L‘L §¡¨T¯[©[¸;Ñ-FÐGôIà"Ò"ñ  6ô Ð<¸T¿\¹\¸NÐKÓLÐLùòAùòBs   ÁD<ÂEc                 óú  • U R                  SS9  U R                  U R                     S:X  d   eU R                  U R                  S nU R                   H  nUR	                  U5      (       d  M  U R
                  R                  [        R                  SR                  U R                  5      U-   5      5        U R                  SS2	 [        U5      s  $    [        SU R                   SU R                   S35      e)	z£
Consume the text following a '#' as an error.

Looks for a match in self.ERROR_CODES and returns the number of
characters matched. (Does not update self.offset)

Ú!rA   r#   NÚ zInvalid error code at position ú in 'r   )rE   r   r   ÚERROR_CODESÚ
startswithr   r'   r(   rI   Újoinr   r5   r   )r   Ú
subformulaÚerrs      r   r,   ÚTokenizer._parse_error”   sÒ   € ð 	×Ñ¨3ÐÑ/Ø�|‰|˜DŸK™KÑ(¨CÓ/Ð/Ð/Ø—\‘\ $§+¡+ ,Ð/ˆ
Ø×#Ô#ˆCØ×$Ñ$ S×)Ó)Ø—
‘
×!Ñ!¤%×"4Ñ"4°R·W±W¸T¿Z¹ZÓ5HÈ3Ñ5NÓ"OÔPØ—J‘Jšq�MÜ˜3“x’ñ	 $ô
 Ð>¸t¿{¹{¸mÈ5ÐQU×Q]ÑQ]ÐP^Ð^_Ð`ÓaÐar   c                 óT  • U R                   U R                     S;   d   eU R                  R                  [	        U R                   U R                     [        R
                  5      5        U R                  R                  U R                   U R                  S 5      R                  5       $ )zn
Consume a string of consecutive spaces.

Returns the number of spaces found. (Does not update self.offset).

)r$   r%   N)	r   r   r   r'   r(   ÚWSPACEÚ	WSPACE_RErG   Úend©r   s    r   r-   ÚTokenizer._parse_whitespace¦   sv   € ð �|‰|˜DŸK™KÑ(¨KÓ7Ð7Ð7Ø�
‰
×Ñœ% §¡¨T¯[©[Ñ 9¼5¿<¹<ÓHÔIØ�~‰~×#Ñ# D§L¡L°·±°Ð$>Ó?×CÑCÓEÐEr   c                 óþ  • U R                   U R                  U R                  S-    S;   aX  U R                  R                  [	        U R                   U R                  U R                  S-    [        R
                  5      5        gU R                   U R                     nUS;   d   eUS:X  a  [	        S[        R                  5      nGOUS;   a  [	        U[        R
                  5      nOüU R                  (       d  [	        U[        R                  5      nOÐ[        S [        U R                  5       5       S5      nU=(       ae    UR                  [        R                  :H  =(       dA    UR                  [        R                  :H  =(       d    UR                  [        R                  :H  nU(       a  [	        U[        R
                  5      nO[	        U[        R                  5      nU R                  R                  U5        g)	z}
Consume the characters constituting an operator.

Returns the number of characters consumed. (Does not update
self.offset)

é   )z>=z<=z<>z
%*/^&=><+-Ú%z*/^&=><c              3   óf   #   • U  H'  nUR                   [        R                  :w  d  M#  Uv •  M)     g 7f©N)Útyper(   rg   )Ú.0Úis     r   Ú	<genexpr>Ú,Tokenizer._parse_operator.<locals>.<genexpr>É   s)   é € ð 4Ò$8˜qØŸF™F¤e§l¡lÑ2÷ ™Ò$8ùs   ‚"1¨	1Nr!   )r   r   r   r'   r(   ÚOP_INÚOP_POSTÚOP_PREÚnextÚreversedrL   ÚCLOSErq   ÚOPERAND)r   r=   r   ÚprevÚis_infixs        r   r.   ÚTokenizer._parse_operator±   sm  € ð �<‰<˜Ÿ™ D§K¡K°!¡OÐ4Ð8JÓJØ�J‰J×ÑœeØ—‘˜TŸ[™[¨¯©°q©Ð9Ü—‘óô ð Ø—L‘L §¡Ñ-ˆ	Ø˜LÓ(Ð(Ð(Ø˜ÓÜ˜#œuŸ}™}Ó-ŠEØ˜)Ó#Ü˜)¤U§[¡[Ó1‰Eà——Ü˜)¤U§\¡\Ó2‰Eäñ 4¤H¨T¯Z©ZÔ$8ó 4Ø59ó;ˆDà÷ Ø—‘¤§¡Ñ+÷ .Ø—9‘9¤§¡Ñ-÷.à—9‘9¤§¡Ñ-ð ö
 Ü˜i¬¯©Ó5‘ä˜i¬¯©Ó6�Ø�
‰
×Ñ˜%Ô Ør   c                 ó  • U R                   U R                     S;   d   eU R                   U R                     S:X  a&  U R                  5         [        R	                  S5      nOiU R
                  (       aC  SR                  U R
                  5      S-   nU R
                  SS2	 [        R	                  U5      nO[        R	                  S5      nU R                  R                  U5        U R                  R                  U5        g)zi
Consumes a ( or { character.

Returns the number of characters consumed. (Does not update
self.offset)

)Ú(Ú{r‚   r^   r�   Nr!   )
r   r   rE   r(   Úmake_subexpr   rb   r   r'   r   )r   r   Útoken_values      r   r/   ÚTokenizer._parse_opener×   sÂ   € ð �|‰|˜DŸK™KÑ(¨JÓ6Ð6Ð6Ø�<‰<˜Ÿ™Ñ$¨Ó+Ø×#Ñ#Ô%Ü×%Ñ% cÓ*‰EØ�Z�ZØŸ'™' $§*¡*Ó-°Ñ3ˆKØ—
‘
š1�Ü×%Ñ% kÓ2‰Eä×%Ñ% cÓ*ˆEØ�
‰
×Ñ˜%Ô Ø×Ñ×Ñ Ô&Ør   c                 óF  • U R                   U R                     S;   d   eU R                  R                  5       R	                  5       nUR
                  U R                   U R                     :w  a  [        SU R                   -  5      eU R                  R                  U5        g)zi
Consumes a } or ) character.

Returns the number of characters consumed. (Does not update
self.offset)

)Ú)Ú}zMismatched ( and { pair in '%s'r!   )	r   r   r   ÚpopÚ
get_closerÚvaluer   r   r'   )r   r   s     r   r0   ÚTokenizer._parse_closerí   s…   € ð �|‰|˜DŸK™KÑ(¨JÓ6Ð6Ð6Ø× Ñ ×$Ñ$Ó&×1Ñ1Ó3ˆØ�;‰;˜$Ÿ,™, t§{¡{Ñ3Ó3Ü Ø1°D·L±LÑ@óBð Bà�
‰
×Ñ˜%Ô Ør   c                 óÆ  • U R                   U R                     nUS;   d   eUS:X  a  [        R                  S5      nO_ U R                  S   R
                  nU[        R                  :X  a  [        S[        R                  5      nO[        R                  S5      n U R                  R                  U5        g! [         a    [        S[        R                  5      n NBf = f)zi
Consumes a ; or , character.

Returns the number of characters consumed. (Does not update
self.offset)

)Ú;Ú,rŽ   rO   r�   r!   )r   r   r(   Úmake_separatorr   rq   ÚPARENrv   Ú
IndexErrorr   r'   )r   r=   r   Útop_types       r   r1   ÚTokenizer._parse_separatorý   s»   € ð —L‘L §¡Ñ-ˆ	Ø˜JÓ&Ð&Ð&Ø˜ÓÜ×(Ñ(¨Ó-‰Eð6Ø×+Ñ+¨BÑ/×4Ñ4�ð œuŸ{™{Ó*Ü! #¤u§{¡{Ó3‘Eä!×0Ñ0°Ó5‘EØ�
‰
×Ñ˜%Ô Øøô ó 0Ü˜c¤5§;¡;Ó/’ð0ús   ¿B9 Â9$C ÃC c                 óH  • U R                   U R                     nUS;   aƒ  [        U R                  5      S:¼  aj  U R                  R                  SR                  U R                  5      5      (       a1  U R                  R                  U5        U =R                  S-  sl        gg)zž
Consumes a + or - character if part of a number in sci. notation.

Returns True if the character was consumed and self.offset was
updated, False otherwise.

z+-r!   r^   TF)r   r   r5   r   ÚSN_RErG   rb   r'   )r   r=   s     r   r6   Ú#Tokenizer.check_scientific_notation  sv   € ð —L‘L §¡Ñ-ˆ	Ø˜ÓÜ˜Ÿ
™
“O qÓ(Ø—J‘J×$Ñ$ R§W¡W¨T¯Z©ZÓ%8×9Ñ9Ø�J‰J×Ñ˜iÔ(Ø�KŠK˜1Ñ�KØØr   c                 óš   • U R                   (       a:  U R                   S   U;  a&  [        SU R                   SU R                   S35      egg)a
  
Ensure that there's no token currently being parsed.

Or if there is a token being parsed, it must end with a character in
can_follow.

If there are unconsumed token contents, it means we hit an unexpected
token transition. In this case, we raise a TokenizerError

rO   z!Unexpected character at position r_   r   N)r   r   r   r   )r   rB   s     r   rE   ÚTokenizer.assert_empty_token'  sJ   € ð �:�:˜$Ÿ*™* R™.°
Ó:Ü Ð#DÀTÇ[Á[ÀMÐQVÐW[×WcÑWcÐVdÐdeÐ!fÓgÐgð ;ˆ:r   c                 óÔ   • U R                   (       aW  U R                  R                  [        R	                  SR                  U R                   5      5      5        U R                   SS2	 gg)z9If there's a token being parsed, add it to the item list.r^   N)r   r   r'   r(   rI   rb   rj   s    r   r8   ÚTokenizer.save_token5  sC   € à�:�:Ø�J‰J×Ñœe×0Ñ0°·±¸¿¹Ó1DÓEÔFØ—
‘
š1‘ð r   c                 óø   • U R                   (       d  gU R                   S   R                  [        R                  :X  a  U R                   S   R                  $ SSR                  S U R                    5       5      -   $ )z+Convert the parsed tokens back to a string.r^   r   r    c              3   ó8   #   • U  H  oR                   v •  M     g 7frp   )r‹   )rr   r   s     r   rt   Ú#Tokenizer.render.<locals>.<genexpr>A  s   é € ÐA²j¨UŸ[ž[²jùs   ‚)r   rq   r(   r)   r‹   rb   rj   s    r   ÚrenderÚTokenizer.render;  sX   € à�z�zØØ�Z‰Z˜‰]×Ñ¤5§=¡=Ó0Ø—:‘:˜a‘=×&Ñ&Ð&Ø�R—W‘WÑA°d·j²jÓAÓAÑAÐAr   )r   r   r   r   r   N)r   )r   r   r	   r
   r   rP   Úcompiler–   rh   rF   r`   r7   r   r   r*   r+   r,   r-   r.   r/   r0   r1   r6   rE   r8   rŸ   r   r   r   r   r   r      s¢   † ñð �JŠJÐ0Ó1€EØ—
’
˜9Ó%€Ið �ZŠZÐ2Ó3Ø�ZŠZÐ2Ó3ñ€Nð5€Kà$€Lòò&òPò8Mò2bò$	Fò$òLò,ò ò2ô"hòõBr   r   c                   ó¶   • \ rS rSrSr/ SQrSrSrSrSr	Sr
S	rS
rSrSrSrSS jrSrSrSrSrSrS r\S 5       rSrSr\S S j5       rS rSrSr\S 5       rSr g)!r(   iD  a  
A token in an Excel formula.

Tokens have three attributes:

* `value`: The string value parsed that led to this token
* `type`: A string identifying the type of token
* `subtype`: A string identifying subtype of the token (optional, and
             defaults to "")

©r‹   rq   rL   r)   r|   ÚFUNCÚARRAYr‘   ÚSEPzOPERATOR-PREFIXzOPERATOR-INFIXzOPERATOR-POSTFIXzWHITE-SPACEc                 ó(   • Xl         X l        X0l        g rp   r£   )r   r‹   Útype_rL   s       r   r   ÚToken.__init___  s   € ØŒ
ØŒ	Ø�r   ÚTEXTÚNUMBERÚLOGICALÚERRORÚRANGEc                 ód   • SR                  U R                  U R                  U R                  5      $ )Nz{0} {1} {2}:)Úformatrq   rL   r‹   rj   s    r   Ú__repr__ÚToken.__repr__q  s#   € Ø×%Ñ% d§i¡i°·±¸t¿z¹zÓJÐJr   c                 óB  • UR                  S5      (       a  U R                  nONUR                  S5      (       a  U R                  nO+US;   a  U R                  nO [	        U5        U R
                  nU " XR                  U5      $ ! [         a    U R                  n N+f = f)zCreate an operand token.r   r#   )ÚTRUEÚFALSE)	ra   rª   r­   r¬   Úfloatr«   Ú
ValueErrorr®   r|   ©Úclsr‹   rL   s      r   rI   ÚToken.make_operandt  sŒ   € ð ×Ñ˜C× Ñ Ø—h‘h‰GØ×Ñ˜c×"Ñ"Ø—i‘i‰GØÐ'Ó'Ø—k‘k‰Gð$Ü�e”ØŸ*™*�ñ �5Ÿ+™+ wÓ/Ð/øô ó $ØŸ)™)’ð$ús   ÁB ÂBÂBÚOPENr{   c                 óN  • US   S;   d   eU(       a/  [         R                  " SU5      (       d   e[        R                  nO>US;   a  [        R                  nO'US;   a  [        R
                  nO[        R                  nUS;   a  U R                  OU R                  nU " XU5      $ )zu
Create a subexpression token.

`value`: The value of the token
`func`: If True, force the token to be of type FUNC

rO   )r‚   rˆ   r�   r‡   z.+\(|\)z{}z()r&   )rP   rG   r(   r¤   r¥   r‘   r{   r»   )r¹   r‹   Úfuncr¨   rL   s        r   rƒ   ÚToken.make_subexp‘  s…   € ð �R‰yÐ0Ó0Ð0Ð0ÞÜ—8’8˜K¨×/Ñ/Ð/Ð/Ü—J‘J‰EØ�d‹]Ü—K‘K‰EØ�d‹]Ü—K‘K‰Eä—J‘JˆEØ$¨›}�#—)’)°#·(±(ˆÙ�5 Ó)Ð)r   c                 ó(  • U R                   U R                  U R                  U R                  4;   d   eU R                  U R
                  :X  d   eU R                   U R                  :X  a  SOSnU R                  XR                   U R                  :H  S9$ )z6Return a closing token that matches this token's type.rˆ   r‡   )r½   )rq   r¤   r¥   r‘   rL   r»   rƒ   )r   r‹   s     r   rŠ   ÚToken.get_closer§  st   € à�y‰y˜TŸY™Y¨¯
©
°D·J±JÐ?Ó?Ð?Ð?Ø�|‰|˜tŸy™yÓ(Ð(Ð(Ø—y‘y D§J¡JÓ.‘°CˆØ×Ñ ¯I©I¸¿¹Ñ,BÐÐCÐCr   ÚARGÚROWc                 ót   • US;   d   eUS:X  a  U R                   OU R                  nU " XR                  U5      $ )zCreate a separator token)r�   rŽ   r�   )rÁ   rÂ   r¦   r¸   s      r   r�   ÚToken.make_separator¹  s8   € ð ˜
Ó"Ð"Ð"Ø" c›\�#—'’'¨s¯w©wˆÙ�5Ÿ'™' 7Ó+Ð+r   )rL   rq   r‹   N)r^   )F)!r   r   r	   r
   r   Ú	__slots__r)   r|   r¤   r¥   r‘   r¦   rx   rv   rw   rg   r   rª   r«   r¬   r­   r®   r±   ÚclassmethodrI   r»   r{   rƒ   rŠ   rÁ   rÂ   r�   r   r   r   r   r(   r(   D  s¼   † ñ
ò -€Ià€GØ€GØ€DØ€EØ€EØ
€CØ€FØ€EØ €GØ€Fôð €DØ€FØ€GØ€EØ€EòKð ñ0ó ð0ð2 €DØ€Eàó*ó ð*ò*Dð €CØ
€Càñ,ó ó,r   r(   )r   rP   Ú	Exceptionr   r   r(   r   r   r   Ú<module>rÈ      s6   ðñó 
ô/�Yô /÷qBñ qB÷h	z,ò z,r   