
    Pi/                   t   d Z ddlmZ ddlmZ ddlmZ  G d de          Z G d de          Z	ddZ
ddZdddddddddddddZddZddZdd Zdd!Zdd$Zdd'Zdd(Zd d*Zd!d-Zd"d/Z G d0 d1          Z G d2 d3          Z G d4 d5          Z G d6 d7          Z G d8 d9          Z G d: d;          Z G d< d=          Z G d> d?          Z G d@ dA          Z G dB dC          Z d#dEZ!d$dIZ" G dJ dK          Z# G dL dMe#          Z$ G dN dOe#          Z% G dP dQe#          Z& G dR dSe#          Z' G dT dUe#          Z( G dV dWe#          Z) G dX dYe#          Z* G dZ d[e#          Z+ G d\ d]e#          Z, G d^ d_e#          Z- G d` dae#          Z. G db dce#          Z/ G dd dee#          Z0 G df dge#          Z1 G dh die#          Z2 G dj dke#          Z3d%dlZ4 G dm dne#          Z5 G do dpe#          Z6 G dq dre#          Z7d&dtZ8d&duZ9d'dwZ:d(dyZ; G dz d{e#          Z< G d| d}e#          Z= G d~ de#          Z> G d de#          Z? G d de#          Z@ G d de#          ZA G d de#          ZB G d de#          ZC G d de#          ZD G d de#          ZE G d de#          ZF G d de#          ZG G d de#          ZH G d de#          ZI G d de#          ZJ G d de#          ZK G d de#          ZL G d de#          ZM G d de#          ZN G d de#          ZO G d de#          ZP G d de#          ZQ G d de#          ZR G d de#          ZS G d de#          ZT G d de#          ZU G d de#          ZV G d de#          ZW G d de#          ZX G d de#          ZY G d de#          ZZ G d de#          Z[ G d de#          Z\ G d de#          Z] G d de#          Z^ G d de#          Z_eeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSf         Z`eeZe[e\e]e^e_f         Za G d de#          Zb G dĄ de#          Zcd)dǄZdd*dȄZe	 	 	 	 d+d,d΄Zf	 d-d.dӄZgd/dԄZhd0dׄZid1d؄Zjd2dلZkd2dڄZld3dۄZmd1d܄Znd1d݄Zod1dބZpd1d߄Zqd4dZrd5dZsh dZth dZuh dZvh dZwh dZxddZyd%dZzd6dZ{d7dZ|ddZ}ddZ~ddZddZddZddZddZddZddZdZdZd8d9dZd8d:dZd8d;d Zd<dZddZddZddZddZddZd=d
Zd=dZddZddZddZddZddZddZd>dZd?dZdZdZdZ G d d          Zd@dAdZdS (B  z
Parable - A recursive descent parser for bash.

MIT License - https://github.com/ldayton/Parable

from parable import parse
ast = parse("ps aux | grep python | awk '{print $2}'")
    )annotations)Callable)Unionc                  .     e Zd ZdZdd fdZdd
Z xZS )
ParseErrorzRaised when parsing fails.r   messagestrposintlinec                    || _         || _        || _        t                                          |                                            d S N)r   r
   r   super__init___format_message)selfr   r
   r   	__class__s       5/root/projects/gits/Dippy/src/dippy/vendor/parable.pyr   zParseError.__init__   sB    	--//00000    returnc                    | j         dk    r%| j        dk    rd| j          d| j         d| j         S | j        dk    rd| j         d| j         S d| j         S )Nr   zParse error at line z, position z: zParse error at position zParse error: )r   r
   r   r   s    r   r   zParseError._format_message   sp    9>>dh!mmZ$)ZZZZDLZZZX]]HdhHH$,HHH-t|---r   r   r   )r   r	   r
   r   r   r   r   r	   )__name__
__module____qualname____doc__r   r   __classcell__)r   s   @r   r   r      s\        $$1 1 1 1 1 1 1. . . . . . . .r   r   c                      e Zd ZdZdS )MatchedPairErrorzRaised when a matched pair (like parentheses or braces) is unclosed at EOF.

    This is distinct from returning None/"" which signals "try alternative parsing".
    MatchedPairError means "this IS the construct, but it's unclosed at EOF".
    N)r   r   r   r    r   r   r!   r!   !   s          	Dr   r!   cr	   r   boolc                J    | dk    r| dk    p| dk    r| dk    p| dk    o| dk    S )N09afAFr"   r#   s    r   _is_hex_digitr-   +   s:    H!cXqCx'<AHX!s(BWqTWxXr   c                    | dk    o| dk    S )Nr&   7r"   r,   s    r   _is_octal_digitr0   /       8 S r               
      	      \   "   ?   )r(   beEr)   nrtv\"?r   c                8    t                               | d          S )zALook up simple ANSI-C escape byte value. Returns -1 if not found.)ANSI_C_ESCAPESgetr,   s    r   _get_ansi_escaperK   D   s    a$$$r   c                &    | dk    p| dk    p| dk    S )N 	
r"   r,   s    r   _is_whitespacerP   I   s    8-qDy-AI-r   s	bytearrayc                F    t          |                     d                    S )z*Convert a string to a list of UTF-8 bytes.utf-8)listencoderQ   s    r   _string_to_bytesrX   M   s    !!"""r   c                    | dk    p| dk    S )NrM   rN   r"   r,   s    r   _is_whitespace_no_newlinerZ   R       8 qDy r   startendc                    | ||         S )z0Extract substring from start to end (exclusive).r"   )rQ   r\   r]   s      r   
_substringr_   V   s    U3Y<r   r
   prefixc                .    |                      ||          S )z.Check if s starts with prefix at position pos.)
startswith)rQ   r
   r`   s      r   _starts_with_atrc   [   s    <<$$$r   c                    d}|dz
  }|dk    rg| |         dk    r[d}|dz
  }|dk    r(| |         dk    r|dz  }|dz  }|dk    r| |         dk    |dz  dk    rn|dz  }|dz  }|dk    r| |         dk    [|S )zCount consecutive '$' characters immediately before pos.

    Stops counting when hitting a '$' that is preceded by an unescaped backslash,
    since escaped dollars don't participate in dollar sequences like $$.
    r      $rD      r"   )rQ   r
   countkbs_countjs         r   !_count_consecutive_dollars_beforerl   `   s     EaA
q&&QqTS[[E1ff1MHFA 1ff1 a<1
	Q q&&QqTS[[ Lr   	delimiterc                V    t          | ||          sdS t          | |          dz  dk    S )zCheck if s[pos:] starts a real expansion (not after $$).

    Returns True if s starts with delimiter at pos AND the preceding
    context indicates this is a real expansion (not $$ followed by
    the delimiter's second character).
    Frg   r   )rc   rl   )rQ   r
   rm   s      r   _is_expansion_startro   w   s7     1c9-- u,Q44q8A==r   lst
list[Node]c                    | ||         S )z.Extract sublist from start to end (exclusive).r"   )rp   r\   r]   s      r   _sublistrs      s    uSy>r   r@   c                    g }d}||k     r |                     |            |dz  }||k      d                    |          S )zRepeat string s n times.r   re    appendjoin)rQ   r@   resultis       r   _repeat_strr{      sM    F	A
a%%a	Q a%% 776??r   c                      e 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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#Z%d$Z&d%Z'd&Z(d'Z)d(Z*d)Z+d*Z,d+Z-d,Z.d-Z/d.Z0d/Z1d0Z2d1Z3d2Z4d3Z5d4S )5	TokenTypez#Token type constants for the lexer.r   re   rg   r6   r9   r5   r7                            !   r;   #   $   %   &   '   (   )   *   +   ,   -   2   3   4   5   6   7   8   9   :   ;   <   =   >   r<   @   A   B   C   D   E   P   Q   N)6r   r   r   r   EOFWORDNEWLINESEMIPIPEAMPLPARENRPARENLBRACERBRACELESSGREATERAND_ANDOR_OR	SEMI_SEMISEMI_AMPSEMI_SEMI_AMP	LESS_LESSGREATER_GREATERLESS_AMPGREATER_AMPLESS_GREATERGREATER_PIPELESS_LESS_MINUSLESS_LESS_LESSAMP_GREATERAMP_GREATER_GREATERPIPE_AMPIFTHENELSEELIFFICASEESACFORWHILEUNTILDODONEINFUNCTIONSELECTCOPROCTIMEBANGLBRACKET_LBRACKETRBRACKET_RBRACKETASSIGNMENT_WORDNUMBERr"   r   r   r}   r}      s       --
CDG DD
CFFFFDG GEIHMIOHKLLONKH 
BDDD	BDD
CEE	BD	BHFFDD OFFFr   r}   c                  (    e Zd ZdZ	 	 dddZddZdS )TokenzA token produced by the lexer.

    For WORD tokens, `parts` contains expansion AST nodes (CommandSubstitution,
    ParameterExpansion, etc.) found within the word. The `word` field contains
    the fully parsed Word object.
    Ntype_r   valuer	   r
   partslist[Node] | NonewordWord | Nonec                T    || _         || _        || _        ||ng | _        || _        d S r   )typer   r
   r   r   )r   r   r   r
   r   r   s         r   r   zToken.__init__   s4     	
*/*;
			r   r   c           
         | j         r#d| j         d| j         d| j         d| j          d	S | j        r0d| j         d| j         d| j         dt          | j                   d	S d| j         d| j         d| j         dS )NzToken(z, z, word=)z, parts=)r   r   r   r
   r   lenr   s    r   __repr__zToken.__repr__   s    9 	UTDITTTTtxTT	TTTT: 	\[DI[[[[tx[[TZ[[[[>	>>TZ>>48>>>>r   NN)
r   r   r   r	   r
   r   r   r   r   r   r   )r   r   r   r   r   r   r"   r   r   r   r      sS          $(     ? ? ? ? ? ?r   r   c                  J    e 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 )ParserStateFlagsz;Parser state flags for context-sensitive parsing decisions.r   re   rg      r3   r   r   r         i   i   i   i   N)r   r   r   r   NONEPST_CASEPATPST_CMDSUBSTPST_CASESTMTPST_CONDEXPRPST_COMPASSIGN	PST_ARITHPST_HEREDOC
PST_REGEXP
PST_EXTPATPST_SUBSHELLPST_REDIRLISTPST_COMMENTPST_EOFTOKENr"   r   r   r   r      sZ        EEDKLLLNIKJJLMKLLLr   r   c                  *    e Zd ZdZdZdZdZdZdZdZ	dS )	DolbraceStatezStates for ${...} parameter expansion parsing.

    These states determine how single quotes are handled inside parameter expansions.
    Based on bash's DOLBRACE_* defines in parser.h.
    r   re   rg   r   r   r   N)
r   r   r   r   r   PARAMOPr   QUOTEQUOTE2r"   r   r   r   r     s8          DE	BDEFFFr   r   c                  :    e 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 )MatchedPairFlagszFlags for _parse_matched_pair() to control parsing behavior.

    Based on bash's P_* flags used in parse_matched_pair().
    These flags control how the function handles quotes, escapes, and nested constructs.
    r   re   rg   r   r3   r   r   r   r   r   N)r   r   r   r   r   DQUOTEDOLBRACECOMMANDARITHALLOWESCEXTGLOB
FIRSTCLOSEARRAYSUB	BACKQUOTEr"   r   r   r  r    sL          DFHGEHGJHIIIr   r  c                      e Zd ZdZ	 dddZdS )SavedParserStatezSaved parser state for nested parsing (e.g., command substitutions).

    Based on bash's sh_parser_state_t and save_parser_state/restore_parser_state.
    Used when parsing nested constructs to save and restore parser context.
    Nparser_stater   dolbrace_statepending_heredocsrq   	ctx_stacklist[ParseContext]	eof_token
str | Nonec                L    || _         || _        || _        || _        || _        d S r   r  r  r  r  r  )r   r  r  r  r  r  s         r   r   zSavedParserState.__init__,  s.     ), 0""r   r   )
r  r   r  r   r  rq   r  r  r  r  )r   r   r   r   r   r"   r   r   r  r  %  s<          !%# # # # # # #r   r  c                  @    e Zd ZdZd ZddZddZddZdd	Zdd
Z	dS )
QuoteStatezUnified quote state tracker for parsing.

    Tracks single and double quote state, with stack support for nested contexts
    like command substitutions inside parameter expansions.
    c                0    d| _         d| _        g | _        d S )NF)singledouble_stackr   s    r   r   zQuoteState.__init__B  s    /1r   r   Nonec                n    | j                             | j        | j        f           d| _        d| _        dS )z;Push current state onto stack and reset for nested context.FN)r  rw   r  r  r   s    r   pushzQuoteState.pushG  s3    DK5666r   c                d    | j         r(| j                                         \  | _        | _        dS dS )zRestore quote state from stack.N)r  popr  r  r   s    r   r!  zQuoteState.popM  s4    ; 	9'+{'8'8$DK	9 	9r   r$   c                    | j         p| j        S )z!Return True if inside any quotes.)r  r  r   s    r   	in_quoteszQuoteState.in_quotesR  s    {)dk)r   c                    t                      }| j        |_        | j        |_        t          | j                  |_        |S )z"Create a copy of this quote state.)r  r  r  rU   r  )r   qss     r   copyzQuoteState.copyV  s3    \\K	K	%%		r   c                    t          | j                  dk    rdS | j        t          | j                  dz
           d         S )z>Return True if the outer (parent) context is in double quotes.r   Fre   )r   r  r   s    r   outer_doublezQuoteState.outer_double^  s=    t{q  5{3t{++a/033r   Nr   r  r   r$   )r   r  )
r   r   r   r   r   r  r!  r#  r&  r(  r"   r   r   r  r  ;  s         2 2 2
   9 9 9 9
* * * *   4 4 4 4 4 4r   r  c                  8    e Zd ZdZdZdZdZdZdZddd	Z	ddZ
dS )ParseContexta  Context for parsing state within a specific scope.

    Tracks context type, nesting depths, and quote state for a single parsing scope.
    Used with ContextStack to manage nested contexts like command substitutions,
    arithmetic expressions, and case patterns.
    r   re   rg      r   kindr   c                    || _         d| _        d| _        d| _        d| _        d| _        d| _        t                      | _        d S )Nr   )	r.  paren_depthbrace_depthbracket_depth
case_deptharith_deptharith_paren_depthr  quoter   r.  s     r   r   zParseContext.__init__t  sG    	!"!+


r   r   c                    t          | j                  }| j        |_        | j        |_        | j        |_        | j        |_        | j        |_        | j        |_        | j        	                                |_        |S )z#Create a deep copy of this context.)
r,  r.  r0  r1  r2  r3  r4  r5  r6  r&  )r   ctxs     r   r&  zParseContext.copy~  sf    49%%** .* $ 6JOO%%	
r   Nr   )r.  r   r   r,  )r   r   r   r   NORMALCOMMAND_SUB
ARITHMETICCASE_PATTERNBRACE_EXPANSIONr   r&  r"   r   r   r,  r,  e  sf          FKJLO. . . . .
 
 
 
 
 
r   r,  c                  @    e Zd ZdZd ZddZdd	Zdd
ZddZddZ	dS )ContextStacka  Stack of parsing contexts for tracking nested scopes.

    Maintains a stack of ParseContext objects to handle nested structures like
    command substitutions inside arithmetic expressions inside case patterns.
    Always has at least one context (NORMAL) on the stack.
    c                .    t                      g| _        d S r   )r,  r  r   s    r   r   zContextStack.__init__  s    +7>>*:r   r   r,  c                F    | j         t          | j                   dz
           S )z%Return the current (topmost) context.re   )r  r   r   s    r   get_currentzContextStack.get_current  s    {3t{++a/00r   r.  r   r  c                T    | j                             t          |                     dS )z"Push a new context onto the stack.N)r  rw   r,  r7  s     r   r  zContextStack.push  s&    <--.....r   c                ~    t          | j                  dk    r| j                                        S | j        d         S )z<Pop and return the top context. Never pops the base context.re   r   )r   r  r!  r   s    r   r!  zContextStack.pop  s5    t{a;??$$${1~r   r  c                l    g }| j         D ])}|                    |                                           *|S )z9Return a deep copy of the context stack for state saving.)r  rw   r&  )r   ry   r9  s      r   
copy_stackzContextStack.copy_stack  s:    ; 	& 	&CMM#((**%%%%r   saved_stackc                p    g }|D ])}|                     |                                           *|| _        dS )z,Restore the context stack from a saved copy.N)rw   r&  r  )r   rJ  ry   r9  s       r   restore_fromzContextStack.restore_from  s>     	& 	&CMM#((**%%%%r   Nr;  )r.  r   r   r  )r   r  )rJ  r  r   r  )
r   r   r   r   r   rE  r  r!  rI  rL  r"   r   r   rB  rB    s         ; ; ;1 1 1 1/ / / /           r   rB  c                     e Zd ZU dZd\d]dZd^d
Zd^dZd_dZd`dZdadZ	dbdZ
dcdZd_dZdddZ	 dedfdZ	 dgdhd%Z	 	 didjd*Zej        dfdkd,Z	 	 	 dldmd1Zdbd2Zdnd4Zdnd5Zdod7Zdcd8Zdcd9Zdpd;Zdqd>Zd^d?ZdrdAZd^dBZd\dsdDZ d\dtdEZ!dudFZ"i dGe#j$        dHe#j%        dIe#j&        dJe#j'        dKe#j(        dLe#j)        dMe#j*        dNe#j+        dOe#j,        dPe#j-        dQe#j.        dRe#j/        dSe#j0        dTe#j1        dUe#j2        dVe#j3        dWe#j4        e#j5        e#j6        e#j7        e#j8        e#j9        dXZ:dYe;dZ<   d[S )vLexerz!Lexer for tokenizing shell input.Fsourcer	   extglobr$   c                   || _         d| _        t          |          | _        t	                      | _        d | _        t          j        | _	        t          j        | _        g | _        || _        d | _        d | _        d | _        t"          | _        d| _        d| _        d| _        d| _        t"          | _        d| _        d| _        d| _        d S )Nr   F)rO  r
   r   lengthr  r6  _token_cacher   r   _parser_stater   _dolbrace_state_pending_heredocs_extglob_parser
_eof_token_last_read_tokenWORD_CTX_NORMAL_word_context_at_command_start_in_array_literal_in_assign_builtin_post_read_pos_cached_word_context_cached_at_command_start_cached_in_array_literal_cached_in_assign_builtin)r   rO  rP  s      r   r   zLexer.__init__  s    v;;!+
*."2"7$1$6-/&*&*.2"1!&!&"'#$)8!.3%.3%/4&&&r   r   r  c                J    | j         | j        k    rdS | j        | j                  S z+Return current character without consuming.Nr
   rR  rO  r   s    r   peekz
Lexer.peek  s%    8t{""4{48$$r   c                n    | j         | j        k    rdS | j        | j                  }| xj         dz  c_         |S z%Consume and return current character.Nre   rg  r   r#   s     r   advancezLexer.advance  s8    8t{""4K!Ar   c                "    | j         | j        k    S )zReturn True if at end of input.r
   rR  r   s    r   at_endzLexer.at_end      x4;&&r   r@   r   c                H    t          | j        | j        | j        |z             S z+Return next n characters without consuming.r_   rO  r
   r   r@   s     r   	lookaheadzLexer.lookahead      $+txA>>>r   r#   c                
    |dv S )z*Return True if c is a shell metacharacter.z
|&;()<> 	
r"   rk  s     r   is_metacharzLexer.is_metachar  s    N""r   Token | Nonec                
   | j         }|                                 }|dS |                     d          }|                     d          }|dk    r+| xj         dz  c_         t          t          j        ||          S |dk    r+| xj         dz  c_         t          t          j        ||          S |dk    r+| xj         dz  c_         t          t          j        ||          S |dk    r+| xj         dz  c_         t          t          j        ||          S |dk    r+| xj         dz  c_         t          t          j	        ||          S |d	k    r+| xj         dz  c_         t          t          j
        ||          S |d
k    r+| xj         dz  c_         t          t          j        ||          S |dk    r+| xj         dz  c_         t          t          j        ||          S |dk    r+| xj         dz  c_         t          t          j        ||          S |dk    r+| xj         dz  c_         t          t          j        ||          S |dk    r+| xj         dz  c_         t          t          j        ||          S |dk    r+| xj         dz  c_         t          t          j        ||          S |dk    r+| xj         dz  c_         t          t          j        ||          S |dk    r+| xj         dz  c_         t          t          j        ||          S |dk    r+| xj         dz  c_         t          t          j        ||          S |dk    r+| xj         dz  c_         t          t          j        ||          S |dk    r+| xj         dz  c_         t          t          j        ||          S |dk    r+| xj         dz  c_         t          t          j        ||          S |dk    r+| xj         dz  c_         t          t          j        ||          S |dk    r=| j        t2          k    rdS | xj         dz  c_         t          t          j        ||          S |dk    r=| j        t2          k    rdS | xj         dz  c_         t          t          j        ||          S |dk    rY| j         dz   | j        k     r| j        | j         dz            dk    rdS | xj         dz  c_         t          t          j        ||          S |dk    rY| j         dz   | j        k     r| j        | j         dz            dk    rdS | xj         dz  c_         t          t          j        ||          S |dk    r+| xj         dz  c_         t          t          j         ||          S dS )z?Try to read an operator token. Returns None if not at operator.Nrg   r-  ;;&<<-<<<&>>&&||;;;&<<>><&>&<>>|&>z|&;re   |&(r   <>rO   )!r
   rh  ru  r   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r\  WORD_CTX_REGEXr   r   rR  rO  r   r   r   )r   r\   r#   twothrees        r   _read_operatorzLexer._read_operator  s   IIKK94nnQq!!E>>HHMHH0%???E>>HHMHH2E5AAAE>>HHMHH15%@@@E>>HHMHH6uEEE$;;HHMHH*C777$;;HHMHH#u555$;;HHMHH,c5999$;;HHMHH+S%888$;;HHMHH,c5999$;;HHMHH2C???$;;HHMHH+S%888$;;HHMHH.U;;;$;;HHMHH/e<<<$;;HHMHH/e<<<$;;HHMHH.U;;;$;;HHMHH+S%88888HHMHHE22288HHMHHE22288HHMHH511188!^33tHHMHH)1e44488!^33tHHMHH)1e44488x!|dk))dk$(Q,.G3.N.NtHHMHHE22288x!|dk))dk$(Q,.G3.N.NtHHMHH*Au55599HHMHH*Au555tr   r  c                    | j         | j        k     rB| j        | j                  }|dk    r|dk    rdS | xj         dz  c_         | j         | j        k     @dS dS )z$Skip spaces and tabs (not newlines).rM   rN   re   Nrg  rk  s     r   skip_blankszLexer.skip_blanksQ  sa    h$$DH%ACxxAIIHHMHH	 h$$$$$$r   c                   | j         | j        k    rdS | j        | j                  dk    rdS | j                                        rdS | j         dk    r| j        | j         dz
           }|dvrdS | j         | j        k     rL| j        | j                  dk    r6| xj         dz  c_         | j         | j        k     r| j        | j                  dk    6dS )zISkip comment if at # in comment-allowed context. Returns True if skipped.F#r   re   z
 	
;|&(){}rO   T)r
   rR  rO  r6  r#  )r   prevs     r   _skip_commentzLexer._skip_commentY  s    8t{""5;tx C''5:!! 	58a<<;tx!|,D>))uh$$TX)>$)F)FHHMHH h$$TX)>$)F)Ftr   r\   tuple[str, bool]c                &   dg}d}| j         | j        k     rl| j        | j                  }|dk    rd}|                    |           | xj         dz  c_         |dk    rd                    |          |fS | j         | j        k     lt          d|          )	zRead single-quoted string content for word parsing.

        Assumes opening quote already consumed.
        Returns (content_with_quotes, saw_newline).
        Raises ParseError if unterminated.
        'FrO   Tre   ru   zUnterminated single quoter
   )r
   rR  rO  rw   rx   r   )r   r\   charssaw_newliner#   s        r   _read_single_quotezLexer._read_single_quotek  s     h$$DH%ADyy"LLOOOHHMHHCxxwwu~~{22 h$$ 4%@@@@r   r   r9  chr2  r0  c                   |t           k    r|dk    r.| j        dz   | j        k     r| j        | j        dz            dk    rdS |dk    r.| j        dz   | j        k     r| j        | j        dz            dk    rdS |dk    r|dk    rdS t	          |          o|dk    S |t
          k    r|dk    r.| j        dz   | j        k     r| j        | j        dz            dk    rdS |dk    rdS |dk    rdS |dk    rdS |dk    rdS t          |          r.| j        dz   | j        k     r| j        | j        dz            d	k    sdS t	          |          S | j        t          j	        z  r| j
        || j
        k    r|dk    rdS t          |          r.| j        dz   | j        k     r| j        | j        dz            d	k    rdS t          |          o|dk    S )4Check if character terminates word in given context.]re   Tr  r   r   r  r  r  NF)r  r
   rR  rO  rP   WORD_CTX_COND_is_redirect_charrT  r   r   rY  _is_metacharr   r9  r  r2  r0  s        r   _is_word_terminatorzLexer._is_word_terminator~  s    .  SyyTX\DK77DKST<UY\<\<\tSyyTX\DK77DKST<UY\<\<\tSyy[A--t!"%%:+*::-SyyTX\DK77DKST<UY\<\<\tSyytSyytSyytSyyt $$ 1t{**t{48a</HC/O/Ot!"%%% "2"??	+do%%""4 b!!	1t{**DHqL)S005B6MQ$66r   r  	list[str]r   rq   	for_regexc                8   |r| j         dz   }|| j        k     r| j        |         dk    r|dz  }|| j        k     r| j        |         dk    r|dz  }d}|| j        k     rH| j        |         }|dk    r$|dz   | j        k     r| j        |dz            dk    rn|dk    r|dk    rn|dk    r#|dz   | j        k     r| j        |dz            dk    rn|dk    rd}n|d	k    r|dz   | j        k     r| j        |dz            d
k    r|dz  }|| j        k     rv| j        |         d
k    r"|dz   | j        k     r| j        |dz            dk    sC|dz  }|| j        k     r3| j        |         d
k    !|dz   | j        k     /| j        |dz            dk    C|| j        k     r|dz  }C|dz  }|| j        k     H|sdS nG| j         dz   | j        k    rdS | j        | j         dz            }t          |          s|dk    s|dk    rdS |                    |                                            |                                 s?|                                 dk    r'|                    |                                            |                                 s?|                                 dk    r'|                    |                                            |                                 sF|                                 }	|	dk    r)|                    |                                            n|	d	k    r| j         dz   | j        k     r| j        | j         dz            d
k    r|                    |                                            |                    |                                            |                                 s|                                 d
k    r,| j         dz   | j        k     r| j        | j         dz            dk    s|                    |                                            |                                 sD|                                 d
k    S| j         dz   | j        k     f| j        | j         dz            dk    |                                 sN|                    |                                            |                    |                                            n0|s|	d	k    r| j         dz   | j        k     r| j        | j         dz            dk    r|                    |                                            |                    |                                            |                                 s|                                 dk    r,| j         dz   | j        k     r| j        | j         dz            dk    s|                    |                                            |                                 sD|                                 dk    S| j         dz   | j        k     f| j        | j         dz            dk    |                                 sN|                    |                                            |                    |                                            no|s|	d	k    r| j         dz   | j        k     r| j        | j         dz            dk    r|                    |                                            |                    |                                            |                                 s|                                 dk    r,| j         dz   | j        k     r| j        | j         dz            dk    s|                    |                                            |                                 sD|                                 dk    S| j         dz   | j        k     f| j        | j         dz            dk    |                                 sN|                    |                                            |                    |                                            n|r|	dk    r|                                  | j	        
                    ||          s<|                                  |                    |                                            n<|                                  n'|                    |                                            |                                 FdS )zScan [...] bracket expression. Returns True if consumed, False if [ is literal.

        For regex mode, calls back to Parser._parse_dollar_expansion for $ expansions.
        re   ^r  Fr   r   r  T[:rg   r  =.rf   )r
   rR  rO  rZ   rw   rl  ro  rh  _sync_to_parserrX  _parse_dollar_expansion_sync_from_parser)
r   r  r   r  r0  scanbracket_will_closescnext_chr#   s
             r   _read_bracket_expressionzLexer._read_bracket_expression  sE     '	8a<Ddk!!dk$&73&>&>	dk!!dk$&73&>&>	!&$$[&99DK!7!7DKq<QUX<X<X99q99DK!7!7DKq<QUX<X<X99)-&99DK!7!7DKq<QUX<X<XAID,,D)S00 1Ht{22 Kq1S88	 ,,D)S00 1Ht{22 Kq1S88 dk))		- $$. & u x!|t{**uk$(Q,/G(11 W^^wRU~~uT\\^^$$${{}} 	)!3!3LL((({{}} 	)!3!3LL(((++-- <	-		ACxxT\\^^,,,CxxDHqL4;664;txRS|;TX[;[;[T\\^^,,,T\\^^,,,++-- 1IIKK3&&1t{22DHqL1S88LL000 ++-- 1IIKK3&&1t{22DHqL1S88 {{}} 1LL000LL000+-HHHqL4;..K1-44T\\^^,,,T\\^^,,,++-- 1IIKK3&&1t{22DHqL1S88LL000 ++-- 1IIKK3&&1t{22DHqL1S88 {{}} 1LL000LL000-HHHqL4;..K1-44T\\^^,,,T\\^^,,,++-- 1IIKK3&&1t{22DHqL1S88LL000 ++-- 1IIKK3&&1t{22DHqL1S88 {{}} 1LL000LL000 	-qCxx$$&&&|;;E5II -**,,,LL0000**,,,,T\\^^,,,y ++-- <	-z tr   	open_char
close_charflagsinitial_was_dollarc                   | j         }d}g }d}|}	d}
|dk    r5|                                 rt          d| d|          |                                 }|t          j        z  r*| j        t          j        k    r|dvrt          j	        | _        |r"d}|
                    |           |dk    }	|d	v }
|dk    rD||k    r|dz  }|dk    rn|d
k    r|t          j        z  rd}|
                    |           d}	d}
|d
k    rc|                                 s2|                                 dk    r|                                  d}	d}
7d}|
                    |           d}	d}
T||k    r*|dz  }|dk    rn|
                    |           d}	|d	v }
||k    r=||k    r7|t          j        z  r|dk    s|dz  }|
                    |           d}	|d	v }
|dv rM||k    rF|dk    ro|
                    |           |	r|t          j        z  n|}|                     dd|          }|
                    |           |
                    d           d}	d}
H|dk    ri|
                    |           |                     dd|t          j        z            }|
                    |           |
                    d           d}	d}
|dk    r\|
                    |           |                     dd|          }|
                    |           |
                    d           d}	d}
|dk    r|                                 s|t          j        z  s|                                 }|	r|
                    |           d}	d}
v|dk    r|t          j        z  rJ| j         dz   }|| j        k    st%          | j        |                   s|
                    |           d}	d}
| xj         dz  c_         |                                  t+          |t          j        z            }| j                            |          \  }}|                                  |r|
                    |           d}	d}
n+|
                    |                                            d}	d}
|dk    r| xj         dz  c_         |                                  | j         dz   | j        k     r| j        | j         dz            dk    r | j                                        \  }}|                                  |r|
                    |           d}	d}
nQ|                                  | j                                        \  }}|                                  |r|
                    |           d}	d}
n|
                    |                                            |
                    |                                            d}	d}
n| j                                        \  }}|                                  |r|
                    |           d}	d}
nR|
                    |                                            |
                    |                                            d}	d}
|dk    r| xj         dz  c_         |                                  | j                                        \  }}|                                  |r|
                    |           d}	d}
n+|
                    |                                            d}	d}
,|dk    r|
r|t          j        t          j        z  z  r|                                }| xj         dz  c_         |                                  | j                                        \  }}|                                  |r|
                    |           d}	d}
n@|
                    |           |
                    |                                            d}	d}
|
                    |           |dk    }	|d	v }
|dk    5d                    |          S )a  Parse a matched pair construct, handling quotes via recursion.

        This is the unified approach based on bash's parse_matched_pair().
        Quotes are handled by recursive calls where the quote is both open and close.

        Args:
            open_char: Opening delimiter (e.g., '(', '{', '[', '"', "'")
            close_char: Closing delimiter (e.g., ')', '}', ']', '"', "'")
            flags: MatchedPairFlags controlling behavior

        Returns:
            The content between delimiters (not including the delimiters themselves).

        Raises:
            MatchedPairError: If EOF is reached before finding the closing delimiter.
        re   Fr   z+unexpected EOF while looking for matching `r  r  #%^,~:-=?+/rf   r  rD   TrO   {z'"`rE   `r  rg   r  ru   ) r
   ro  r!   rl  r  r  rU  r   r   r   rw   r  rh  _parse_matched_pairr  r  r  rR  _is_funsub_charrO  r  r$   rX  _parse_param_expansionr  _parse_arithmetic_expansion_parse_command_substitution_parse_deprecated_arithmeticr
  r!  _parse_process_substitutionrx   )r   r  r  r  r  r\   rh   r  	pass_next
was_dollarwas_gtltr  quote_flagsnestedr  after_brace_pos	in_dquote
param_node
param_text
arith_node
arith_textcmd_nodecmd_text	directionprocsub_nodeprocsub_texts                             r   r  zLexer._parse_matched_pair$  s   . 	'
aii{{}} &O*OOO   
 B (11 >t7K}O_7_7_]**+8+=D(  !	R   3Y
: C##QJEzz::5+;+D#D: $IR   "
  Tzz{{}} )<)<LLNNN!&J$H 	R   "
  Z
A::R   "
:
 Y9
#:#: 0 99 i3>N>NQJER   "
: V||	Z 7 799 LL$$$GQ"\%*:*C"C"CW\K!55c3LLFLL(((LL%%%!&J$H3YYLL$$$!55c3HXH_@_``FLL(((LL%%%!&J$H3YYLL$$$!55c3FFFLL(((LL%%%!&J$H Syyy@P@X8Xy))++  LL$$$!&J$Hc>> /55 	%*.(Q,*dk99 K8B B9 "LL,,,)-J',H$HHMHH((*** $U-=-D%D E EI-1\-P-PQZ-[-[*J
**,,,! )Z000%*
#( T\\^^444%)
#(^^HHMHH((***x!|dk11dk$(Q,6OSV6V6V151Y1Y1[1[.
J..000% 1!LL444).J',HH !00222151Y1Y1[1[.Hh 22444' 	1 %X 6 6 6-2
+0 !&T\\^^ < < < %T\\^^ < < <-2
+0 .2\-U-U-W-W*(..000# 	-!LL222).J',HH "LL888!LL888).J',H^^HHMHH((***-1\-V-V-X-X*J
**,,,! )Z000%*
#( T\\^^444%)
#(
 c		 .7:J:SST 
 "IIKK	A$$&&&-1\-U-U-W-W*l&&((( 	%LL...!&J$HH LL+++LL000!&J$HLLsJTzHK aiiN wwu~~r   r  c                L    |                      dd|t          j        z  |          S )zCollect argument portion of ${...} until closing brace.

        Wraps _parse_matched_pair() with DOLBRACE flag for parameter expansion arguments.
        was_dollar should be True if the param name ended with $ (for $$ handling).
        r  })r  r  r  )r   r  r  s      r   _collect_param_argumentzLexer._collect_param_argument+  s(     ''S%:J:S2SU_```r   at_command_startin_array_literalin_assign_builtinr   c                "   | j         }g }g }d}d}	d}
d}|                                 s|                                 }|t          k    r[|dk    rU| j         dz   | j        k     rB| j        | j         dz            dk    r)|                                  |                                  |t          k    r|                     ||||          rn#|t          k    r|dk    r|dk    r-|dz  }|	                    |                                            |rz|rx|
svt          |          rg|t          |          dz
           }|                                s|dk    r5| j         }	|dz  }|	                    |                                            t|s9|
s7|r5| j         }	|dz  }|	                    |                                            |t          k    r:|d	k    r4|dk    r.|dz  }|	                    |                                            |t          k    r|d
k    r|dk    rd}
|t          k    r4|dk    r.|dz  }|	                    |                                            L|t          k    r<|dk    r6|dk    r.|dz  }|	                    |                                            nD|t          t          fv rU|dk    rO|t          k    }|                     ||||          r|	                    |                                            |t          k    r|dk    r| j        r|rt!          |t          |          dz
                     rt|	                    |                                            |                     ddt$          j                  }|	                    |           |	                    d           n*|t          k    r>t)          |          r/|dk    r)|	                    |                                            |dk    re|                                  |t          k    }|                     |          \  }}|	                    |           |r|r| j        d| j        _        a|dk    r|                                  |t          k    r|	                    d           d}|                                 s|s|                                 dk    r|                                 }|r0|	                    |                                            |dk    rd}v|dk    r| j         dz   | j        k     r| j        | j         dz            }|dk    r*|                                  |                                  n|	                    |                                            |	                    |                                            n]|dk    r|                                  | j                            ||d          s<|                                  |	                    |                                            n|                                  n|dk    r|                                  | j                                        }|                                  |d         r7|	                    |d                    |	                    |d                    nO|	                    |                                            n'|	                    |                                            |                                 s|h|                                 dk    |                                 rt9          d|          |	                    |                                            nP|t          k    }|                                  | j                            ||||           |                                  |dk    r| j         dz   | j        k     r| j        | j         dz            }|t          k    r/|dk    r)|                                  |                                  nN|	                    |                                            |	                    |                                            |t          k    r|dk    r| j         dz   | j        k     r| j        | j         dz            dk    r||                                 }|d         r7|	                    |d                    |	                    |d                    n'|	                    |                                            	`|t          k    r|dk    r| j         dz   | j        k     r| j        | j         dz            dk    r|                                 }|d         rR|	                    |d                    |                     |d                    |	                    |d                    n'|	                    |                                            
4|dk    r|                                  | j                            ||          s=|                                  |	                    |                                            n4|                                  | j        r|t          k    r|r	t          |t          |          dz
                     dk    r|t          |          dz
           d         dk    r|t          |          dz
           d         dv r|                                 s|                                 dk    rr|	                    |                                            |                     ddt$          j                  }|	                    |           |	                    d           |t          k    r|dk    r|                                  | j                                        }|                                  |d         r7|	                    |d                    |	                    |d                    n'|	                    |                                            |t          k    r<tC          |          r,| j         dz   | j        k     r| j        | j         dz            dk    r|                                  | j        "                                }|                                  |d         r7|	                    |d                    |	                    |d                    n}|d         r|	                    |d                    nY|	                    |                                            |t          k    r'|	                    |                                            |t          k    rF|dk    r?|r<|dk    r5d}t          |          dk    rP|t          |          dz
           dk    r4|t          |          dz
           d
k    rt          |dd                   }nF|t          |          dz
           d
k    r*t          |          dk    rt          |dd                   }|r|s|r|                                  | j        #                                }|                                  |d         r7|	                    |d                    |	                    |d                    nn1| j        r|t          k    rt!          |          r| j         dz   | j        k     r| j        | j         dz            dk    r|	                    |                                            |	                    |                                            |                     ddt$          j                  }|	                    |           |	                    d           |t          k    rV| j$        tJ          j&        z  rB| j'        ;|| j'        k    r0|dk    r*|s'|	                    |                                            n]|t          k    rtQ          |          r|dk    rn<|	                    |                                            |                                 |dk    r+|	dk    r%|                                 rtS          d|	          |sdS |r#tU          d+                    |          |          S tU          d+                    |          d          S )zUnified word parser with context-aware termination.

        Uses callbacks to Parser for methods that need parse_list or other parsing.
        r   rH   FrD   re   rO   r  _r  r  Tr  r   )r  r0  r  NrE   rf   r  r  Unterminated double quoter  rg   z?*@r-  +zunexpected EOF looking for `]'ru   ),r
   ro  rh  r  rR  rO  rl  r[  r  rw   _is_array_assignment_prefixr   isalnumr  r  rW  _is_extglob_prefixr  r  r  rP   r  rX  _saw_newline_in_single_quoter  r  r  _parse_backtick_substitutionr   _scan_double_quote_read_ansi_c_quote_read_locale_stringextendr  r  _parse_array_literalrT  r   r   rY  r  r!   Wordrx   )r   r9  r  r  r  r\   r  r   r2  bracket_start_posseen_equalsr0  r  	prev_charr  contenttrack_newliner  in_single_in_dquoter#   next_ccmdsub_resulthandle_line_continuationr  ansi_resultlocale_resultprocsub_resultis_array_assignarray_results                                r   _read_word_internalzLexer._read_word_internal5  sW    !#++-- a	)Bn$$::$(Q,"<"<TXXY\AZ^bAbAbLLNNNLLNNNo%%$*B*BR+ +% o%%")) 1$$!Q&MLL000!(! (! 4E::	! !&c%jj1n 5I ((** !i3.>.>,0H)%*T\\^^444  [ 5E (,%!Q&MLL000o%%"))8I8I"T\\^^,,,o%%"))8J8J"n$$sq T\\^^,,,n$$s??1$KLL000}n555"))>1	005I; 1    T\\^^,,,m##c		= U /A%E

UVBW/X/X LL000"66sCAQAYZZGLL)))LL%%% n$$););$aT\\^^,,,Syy # 6'+'>'>u'E'E$W%%%  E[ ET\5M@DDL=Syy/))LL%%%*/'"kkmm $91D $9		WZHZHZ IIKK. %!LL888 Cxx6; 3$99A)C)C%)[A%>F%~~ $ $ %T\\^^ < < < %T\\^^ < < < <#XX 00222#'<#G#G %u $H $ $ 9 !% 6 6 8 8 8 %T\\^^ < < < < $ 6 6 8 8 8 8#XX 00222,0L,U,U,W,WM 22444,Q/ = %]1-= > > > %]1-= > > > > %T\\^^ < < < <!LL888I #kkmm $91D $9		WZHZHZJ {{}} Q()D%PPPPLL0000 03m/C,((***L33E5%Iabbb**,,,TzzdhlT[88+dhl3.((W__LLNNNLLNNNNLL000LL000 ~%%#IIHqL4;..K1-44"5577q> 1LLQ000LLQ0000LL000 ~%%#IIHqL4;..K1-44 $ 8 8 : : # 1LLq!1222LLq!1222LLq!12222LL000Syy$$&&&|;;E5II ***,,,LL0000**,,, *?22! 3c%jj1n 566!;;!#e**q.1!4;;!#e**q.1!4== $ > IIKK3..T\\^^444"&":":3EUE]"^"^W---S)))n$$s$$&&& $ I I K K&&((( # 1LLq!1222LLq!12222LL000 ~%%%b)) &HqL4;..K1-44$$&&&!%!I!I!K!K&&(((!!$ 5LL!2333LL!23333#A& 5LL!23333LL000o--T\\^^444 o%%")))-STBTBT"' JJ!OOc%jj1n-44c%jj1n-44 'B%*&M&MOO3u::>*c11c%jjAoo&A%*&M&MO" 	(8 	<M 	((***#'<#D#D#F#FL**,,,#A \!_555\!_5555 ?**&r** +HqL4;..K1-44T\\^^,,,T\\^^,,,223=M=UVVW%%%S!!! &&'*:*GG 'O/$/))!Q&& 1LL000o%%,r*:*:%}PQ?Q?QLL(((C	 ++-- a	)F	 1!2b!8!8T[[]]!8"#CIZ[[[[ 	4 	/...BGGENND)))r   c                   | j         }| j         | j        k    rdS |                                 }|dS |dk    s|dk    o+| j         dz   | j        k     o| j        | j         dz            dk    }| j        t
          k    o|dk    p|dk    }|                     |          r|s|sdS |                     | j        | j        | j	        | j
                  }|dS t          t          j        |j        |d|          S )zARead a word token using _read_word_internal with current context.Nr  r  re   r  r   )r
   rR  rh  rO  r\  r  rx  r  r]  r^  r_  r   r}   r   r   )r   r\   r#   
is_procsubis_regex_parenr   s         r   
_read_wordzLexer._read_wordr  s   8t{""4IIKK94 #X!c 11t{*1DHqL)S0 	 +~=X18CWqTWxA 	z 	. 	4''""#	
 
 <4Y^TZdCCCr   r   c                t   | j         | j         }d| _         || _        |S |                                  |                                 r)t	          t
          j        d| j                  }|| _        |S | j        n| 	                                | j        k    rQ| j
        t          j        z  s=| j
        t          j        z  s)t	          t
          j        d| j                  }|| _        |S |                                 r|                                  |                                 r)t	          t
          j        d| j                  }|| _        |S | j        n| 	                                | j        k    rQ| j
        t          j        z  s=| j
        t          j        z  s)t	          t
          j        d| j                  }|| _        |S |                                 |                                 }|	|| _        |S |                                 }|	|| _        |S t	          t
          j        d| j                  }|| _        |S )z%Return the next token from the input.Nru   )rS  rZ  r  ro  r   r}   r   r
   rY  rh  rT  r   r   r   r  r  r  r   toks     r   
next_tokenzLexer.next_token  s   (#C $D$'D!J;;== 		r4844C$'D!J O'		t..'*:*FF /'*:*GG / 	r4844C$'D!J  "" 	{{}} IM2tx88(+%
 +IIKK4?22+.>.JJ 3+.>.KK 3 IM2tx88(+%
   "" 	  !!##?$'D!Joo?$'D!JIM2tx00 #
r   c                l    | j         '| j        }|                                 | _         || _        | j         S )z%Peek at next token without consuming.)rS  rZ  r  )r   
saved_lasts     r   
peek_tokenzLexer.peek_token  s6    $.J $ 1 1D$.D!  r   tuple[Node | None, str]c                   |                                  s|                                 dk    rdS | j        dz   | j        k    s| j        | j        dz            dk    rdS | j        }|                                  |                                  g }d}|                                  s|                                 }|dk    r|                                  d}n|dk    rc|                    |                                            |                                  s'|                    |                                            n'|                    |                                            |                                  |st          d|	          t          | j        || j                  }d
	                    |          }t          |          }||fS )zRead ANSI-C quoting $'...'.

        Returns (node, text) where node is the AST node and text is the raw text.
        Returns (None, "") if not a valid ANSI-C quote.
        rf   Nru   re   r  FTrD   z-unexpected EOF while looking for matching `''r  ru   )ro  rh  r
   rR  rO  rl  rw   r!   r_   rx   
AnsiCQuote)r   r\   content_charsfound_closer  textr  nodes           r   r  zLexer._read_ansi_c_quote  s    ;;== 	DIIKK3..88a<4;&&$+dhl*Cs*J*J8#%++-- 	5BSyy"t$$T\\^^444{{}} 9!((888$$T\\^^444 ++-- 	5  	_"#RX]^^^^$+udh77''-(('""Tzr   c                :    | j         | j        | j         _        dS dS )zESync Parser position to Lexer position before calling Parser methods.NrX  r
   r   s    r   r  zLexer._sync_to_parser  s$    <##xDL $#r   c                :    | j         | j         j        | _        dS dS )zFSync Lexer position from Parser position after calling Parser methods.Nr  r   s    r   r  zLexer._sync_from_parser  s"    <#|'DHHH $#r   #tuple[Node | None, str, list[Node]]c                
   |                                  s|                                 dk    rddg fS | j        dz   | j        k    s| j        | j        dz            dk    rddg fS | j        }|                                  |                                  g }g }d}|                                  sl|                                 }|dk    r|                                  d}n:|dk    r| j        dz   | j        k     r| j        | j        dz            }|d	k    r*|                                  |                                  n|                    |                                            |                    |                                            nw|dk    rU| j        d
z   | j        k     rA| j        | j        dz            dk    r'| j        | j        d
z            dk    r|                                  | j        	                                \  }}| 
                                 |r,|                    |           |                    |           n|                                  | j                                        \  }	}
| 
                                 |	r,|                    |	           |                    |
           nD|                    |                                            nt          | j        | j        d          r|                                  | j                                        \  }	}
| 
                                 |	r,|                    |	           |                    |
           n|                    |                                            ne|dk    r|                                  | j                                        \  }}| 
                                 |r+|                    |           |                    |           n|                    |                                            n|dk    r|                                  | j                                        \  }	}
| 
                                 |	r+|                    |	           |                    |
           nO|                    |                                            n'|                    |                                            |                                  l|s|| _        ddg fS d                    |          }d|z   dz   }t!          |          ||fS )a3  Read locale translation $"...".

        Returns (node, text, inner_parts) where:
        - node is the LocaleString AST node
        - text is the raw text including $"..."
        - inner_parts is a list of expansion nodes found inside
        Returns (None, "", []) if not a valid locale string.
        rf   Nru   re   rE   FTrD   rO   rg   r  $(r  $")ro  rh  r
   rR  rO  rl  rw   r  rX  r  r  r  ro   r  r  rx   LocaleString)r   r\   r  inner_partsr  r  r  r  r  cmdsub_nodecmdsub_textr  r  r  r  s                  r   r  zLexer._read_locale_string  s    ;;== 	 DIIKK3..R<8a<4;&&$+dhl*Cs*J*JR<#%"$++-- G	5BSyy"t1t{ : :+dhl3d??LLNNNLLNNNN!((888!((8888 c		HqL4;..K1-44K1-44 $$&&&)-)Q)Q)S)S&
J&&((( =&&z222!((4444 ((***/3|/W/W/Y/Y,K**,,," =#**;777%,,[9999%,,T\\^^<<<<$T[$(DAA 5$$&&&+/<+S+S+U+U([&&((( 9&&{333!((5555!((8888s$$&&&)-)L)L)N)N&
J&&((( 9&&z222!((4444!((8888s$$&&&+/<+T+T+V+V([&&((( 9&&{333!((5555!((8888$$T\\^^444O ++-- G	5P  	 DHR<''-((g~#G$$dK77r   op	has_paramc                \   | j         t          j        k    rdS |t          |          dk    rdS |d         }| j         t          j        k    r2|r0|dv rt          j        | _         dS |dk    rt          j        | _         dS | j         t          j        k    r|dv rt          j        | _         dS dS dS )z-Update dolbrace state based on operator seen.Nr   %#^,/r  rU  r   r   r   r   r   r   r   r   r  r  
first_chars       r   _update_dolbrace_for_opzLexer._update_dolbrace_for_op[  s    =#555F:RAFU
=#66696V##'4':$S  '4';$=#666]**'4'7$$$ 76**r   c                   |                                  rdS |                                 }|dk    rh|                                  |                                  rdS |                                 }t          |          r|                                  d|z   S dS t          |          r|                                  |S |dk    rX|                                  |                                  s.|                                 dk    r|                                  dS dS |dk    rX|                                  |                                  s.|                                 dk    r|                                  dS dS |dk    r|                                  |                                  sh|                                 }|dk    r|                                  dS |dk    r|                                  d	S |dk    r|                                  d
S dS |dk    rX|                                  |                                  s.|                                 dk    r|                                  dS dS |dk    rX|                                  |                                  s.|                                 dk    r|                                  dS dS |dk    r|                                  dS dS )z'Consume a parameter expansion operator.Nr  r  ##%%%r!  //z/#z/%r  ^^,,,@)ro  rh  rl  _is_simple_param_op)r   r  r  s      r   _consume_param_operatorzLexer._consume_param_operatorm  s   ;;== 	4YY[[99LLNNN{{}} siikkG"7++ %W}$3r"" 	LLNNNI99LLNNN;;== TYY[[C%7%7t399LLNNN;;== TYY[[C%7%7t399LLNNN;;== 
 ))++c>>LLNNN4^^LLNNN4^^LLNNN4399LLNNN;;== TYY[[C%7%7t399LLNNN;;== TYY[[C%7%7t399LLNNN3tr   	start_posc                   d}|dz   }t                      }|| j        k     r| j        |         }|j        r|dk    rd|_        |dz  }2|j        r-|dk    r|dz   | j        k     r|dz  }S|dk    rd|_        |dz  }f|dk    rd|_        |dz  }y|dk    rd|_        |dz  }|dk    r|dz  }|dk    rdS |d	k    r|dz  }n|d
k    r|dz  }|dk    rdS |dz  }|| j        k     dS )zACheck for a matching ] in a parameter subscript before closing }.re   r  FrD   rg   rE   Tr  r  r  r   )r  rR  rO  r  r  )r   r1  depthrz   r6  r#   s         r   _param_subscript_has_closez Lexer._param_subscript_has_close  sN   M$+ooAA| 88#(ELQ| 99Q!4!4FA88#(ELQCxx#QCxx#QDyyQCxxuCxx
c
A::4FAE $+ooF ur   c                &   |                                  rdS |                                 }t          |          rH|dk    r,| j        dz   | j        k     r| j        | j        dz            dv rdS |                                  |S |                                rg }|                                  s|                                                                 ra|                    |                                            |                                  s&|                                                                 ad	                    |          S |
                                s|dk    r.g }|                                  s|                                 }|                                s|dk    r(|                    |                                            n|dk    r|                     | j                  sn|                    |                                            |                     ddt          j                  }|                    |           |                    d           nn|                                  |rd	                    |          S dS dS )	zKConsume a parameter name (variable name, special char, or array subscript).Nrf   re   z{'"ru   r  r  r  )ro  rh  _is_special_paramr
   rR  rO  rl  isdigitrw   rx   isalphar  r4  r  r  r
  )r   r  
name_charsr#   r  s        r   _consume_param_namezLexer._consume_param_name  sN   ;;== 	4YY[[R   	SyyTX\DK77DKST<UY_<_<_tLLNNNI::<< 	'$&Jkkmm 2		(;(;(=(= 2!!$,,..111 kkmm 2		(;(;(=(= 277:&&&::<< 	299Jkkmm IIKK99;; !s((%%dllnn5555#XX::48DD  %%dllnn555"66sCAQAZ[[G%%g...%%c*** kkmm    wwz***ttr   r  c                   |                                  s|                                 dk    rdS | j        }|                                  |                                  r	|| _        dS |                                 }|dk    r*|                                  |                     ||          S t          |          st          |          s|dk    r@|                                  t          | j        || j                  }t          |          |fS |
                                s|dk    r| j        }|                                  sX|                                 }|                                s|dk    r|                                  nn|                                  Xt          | j        || j                  }t          | j        || j                  }t          |          |fS || _        dS )a	  Read a parameter expansion starting at $.

        Returns (node, text) where node is the AST node and text is the raw text.
        in_dquote is True if this expansion is inside double quotes.
        Returns (None, "") if not a valid parameter expansion.
        rf   r  r  r  r  )ro  rh  r
   rl  _read_braced_param_is_special_param_unbraced	_is_digitr_   rO  ParamExpansionr8  r  )r   r  r\   r  r  
name_startr#   names           r   _read_param_expansionzLexer._read_param_expansion  s    ;;== 	DIIKK3..8;;== 	DH8YY[[99LLNNN**5)<<<%b)) 	,Yr]] 	,bCiiLLNNNdk5$(;;D!"%%t++::<< 
	.299Jkkmm IIKK99;; !s((LLNNNN kkmm  dk:tx@@Ddk5$(;;D!$''--xr   c                \   |                                  rt          d|          | j        }t          j        | _        |                                 }t          |          r|| _        |                     |          S |dk    r|                                  | 	                                }|rs|                                  s_|                                 dk    rG|                                  t          | j        || j                  }|| _        t          |          |fS |dz   | _        |dk    r.|                                  |                                  sjt          |                                           rI|                                  |                                  s!t          |                                           I| 	                                }|r{|                                  sjt          |                                           rI|                                  |                                  s!t          |                                           I|                                  s_|                                 dk    rG|                                  t          | j        || j                  }|| _        t          |          |fS |                                  st!          |                                           rn|                                 }|                     ddt$          j                  }t          | j        || j                  }|| _        t          ||z   |z             |fS |                                 }	|	>|                                  s*|                                 d	vr|                                 }	|	Z|	d
vrV|                     ddt$          j                  }
t          | j        || j                  }|| _        t          ||	|
          |fS |                                  r|| _        t          d|          |dz   | _        n
|dz   | _        | 	                                }|s|                                  sf|                                 dv sM|                                 dk    r8| j        dz   | j        k     r%t-          | j        | j        dz                      rd}nA|                     ddt$          j                  }d|z   dz   }|| _        t/          |          |fS |                                  r|| _        t          d|          |                                 dk    rG|                                  t          | j        || j                  }|| _        t/          |          |fS |                                 }	|	|                                  s|                                 dk    rj| j        dz   | j        k     rW| j        | j        dz            dv r@dt1          | j        | j                  z   }|dz  dk    rd}	n||                                 }	nf|                                  sI|                                 dk    r0| j        }|                                  |                                  s|                                 dk    r|                                 }|dk    rK| j        dz   | j        k     r8| j        | j        dz            }t3          |          r|                                  |                                  |                                  s|                                 dk    |                                  r|| _        t5          d|          |                                  d}	n|                                  sG|                                 dk    r/| j        dz   | j        k     r| j        | j        dz            dk    rd}	n|                                  s|                                 dv rd}	n|                                  sX|                                 dk    r@|                                 }	|                                  s|	|                                 z  }	n|                                 }	|                     |	t9          |          dk               	 |rt$          j        nt$          j        }|duo|                    d          }|                      ||          }
n# t          $ r}|| _        |d}~ww xY w|	dv r|
!                    d          r|
                    d          r}|
dd         }	 tE          |d| j#        j$                  }|%                                }|r/|                                 rtM          |dddd          }d|z   dz   }
n# tN          $ r Y nw xY wd|z   |	z   |
z   dz   }|| _        t/          ||	|
          |fS )zRead contents of ${...} after the opening brace.

        start is the position of the $.
        in_dquote is True if this expansion is inside double quotes.
        Returns (node, text).
        unexpected EOF looking for `}'r  r  r  rg   !r  Nz}"'`z"'`z-=+?r  re   ru   ${rf   )rE   r  r  rD   Unterminated backtick)r  rE   r   )r  r  r  r   rH   T)in_process_subrP  F)(ro  r!   rU  r   r   rh  r  _read_funsubrl  r:  r_   rO  r
   ParamLengthrZ   ParamIndirect_is_at_or_starr  r  r  r0  rR  r/  r?  rl   _is_escape_char_in_backtickr   r%  r   r  r   endswithr  rb   ParserrX  rW  
parse_list_format_cmdsub_node	Exception)r   r\   r  saved_dolbracer  paramr  suffixtrailingr  argr  dollar_countbacktick_posbcr  r  param_ends_with_dollarr>   inner
sub_parserparsed	formatteds                          r   r<  zLexer._read_braced_param+  sY	    ;;== 	P"#COOOO-,2YY[[2 	,#1D $$U+++99LLNNN,,..E 0T[[]] 0tyy{{c/A/A!$+udh??'5$"5))4//qyDH99LLNNNkkmm (A$))++(N(N  kkmm (A$))++(N(N ,,..E  %++-- #,Ediikk,R,R #LLNNN ++-- #,Ediikk,R,R #{{}} 6););LLNNN%dk5$(CCD+9D((//55{{}} J		)D)D J!\\^^F#77SBRB[\\H%dk5$(CCD+9D((()BCCTII1133:dkkmm:		78R8RB>b&6&6223=M=VWWC%dk5$(CCD+9D((C88$>>;;== X+9D(*+KQVWWWW 19 !19((** 	5;;== 5		v%%IIKK3&&1t{22+DK1,EFF 3  223=M=VWWg~+'5$%g..44;;== 	P#1D "#COOOO99;;#LLNNNdk5$(;;D#1D !%(($..))++: KKMM*$IIKK3&&HqL4;..K1-;; #DT[RVRZ#[#[[!#q((BBBB[[]] $tyy{{c'9'9#x++-- #DIIKK3,>,>BTzzdhlT[&@&@!%TX\!:6v>> + LLNNNLLNNN ++-- #DIIKK3,>,> ;;== P+9D($%<,OOOOKKMM$IIKK3&&HqL4;..K1-44[[]] 	$tyy{{j'@'@[[]] $tyy{{d':':\\^^{{}} )$,,..(B\\^^$$RUa888	/8S$++>N>SE%*$%6%N5>>#;N;N"..u6LMMCC 	 	 	#1D G	 s 3 3S8I8I"IE#E$H]^^^
#..00 0j//11 0 3FAtUD Q QI	/C/C   e|b 3&,-eR--t33s,   6A	e   
e
	eeA!g6 6
hhc                6    | j                             |          S )z8Read brace command substitution ${ cmd; } or ${| cmd; }.)rX  _parse_funsub)r   r\   s     r   rI  zLexer._read_funsub  s    |))%000r   ifthenelseelifficaseesacforwhileuntildodoneinfunctionselectcoproctime)rE  [[]]r  r  zdict[str, int]RESERVED_WORDSNF)rO  r	   rP  r$   r   r  r*  r@   r   r   r	   r#   r	   r   r$   )r   ry  r)  )r\   r   r   r  r   
r9  r   r  r	   r2  r   r0  r   r   r$   )Fr   )
r  r  r   rq   r  r$   r0  r   r   r$   )r   F)
r  r	   r  r	   r  r   r  r$   r   r	   )r  r   r  r$   r   r	   FFF)
r9  r   r  r$   r  r$   r  r$   r   r   r   r   r   r
  )r   r  r  r  r  r$   r   r  )r1  r   r   r$   r  r$   r   r
  )r\   r   r  r$   r   r
  r\   r   r   r
  )<r   r   r   r   r   rh  rl  ro  ru  rx  r  r  r  r  r  r  r  r  r   r  r  r  r  r	  r  r  r  r  r%  r0  r4  r:  rB  r<  rI  r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   ru  __annotations__r"   r   r   rN  rN    s$        ++5 5 5 5 5@% % % %   ' ' ' '? ? ? ?# # # #_ _ _ _B      $A A A A( MN.7 .7 .7 .7 .7b `at t t t tt #(E E E E EP ,0Ua a a a a "'!&"'{* {* {* {* {*z	D D D D81 1 1 1f! ! ! !" " " "H( ( ( (
( ( ( (
b8 b8 b8 b8H8 8 8 8$@ @ @ @D( ( ( (T( ( ( (T& & & & &Pg4 g4 g4 g4 g4R1 1 1 1
&il&	& 		& 			&
 	il& 		& 		& 	y}& 	& 	& 	il& 		& 	il& 	I&& 	)"&  	)"!&" 		#&$ ^))-& & &N      r   rN  r  c                   g }d}d}t                      }|t          |           k     r,| |         }|dk    r|dz   t          |           k     rl| |dz            dk    r]d}|dz
  }|dk    r(| |         dk    r|dz  }|dz  }|dk    r| |         dk    |dz  dk    r|r|                    d           |dz  }d}|dk    rd}|                    |           |dz  }|dk    r|j        s|s|j         |_        n.|dk    r|j        s|s|j         |_        n|d	k    r|j        s|sd
}|                    |           |dz  }|t          |           k     ,d                    |          S )zStrip backslash-newline line continuations, preserving newlines in comments.

    In comments, backslash-newline is replaced with just newline (to keep the comment
    terminator). Outside comments, backslash-newline is fully removed.
    r   FrD   re   rO   rg   r  rE   r  Tru   )r  r   rw   r  r  rx   )r  ry   rz   
in_commentr6  r#   num_preceding_backslashesrk   s           r   '_strip_line_continuations_comment_awarer    s    F	AJLLE
c$ii--G99QT**tAE{d/B/B()%AAq&&T!W__)Q.)Q q&&T!W__ )1,11 (MM$'''Q"
99JMM!FA88EL88$|+ELL#XXelX:X$|+ELL#XXelX:XJa	QA c$ii--B 776??r   base	redirectsr   c                    |rIg }|D ])}|                     |                                           *| dz   d                    |          z   S | S )z3Append redirect sexp strings to a base sexp string.rM   )rw   to_sexprx   )r  r  r   rA   s       r   _append_redirectsr  !  sY     , 	& 	&ALL%%%%czCHHUOO++Kr   c                  &    e Zd ZU dZded<   ddZdS )NodezBase class for all AST nodes.r	   r.  r   c                    t           )z0Convert node to S-expression string for testing.)NotImplementedErrorr   s    r   r  zNode.to_sexp0  s    !!r   Nr   )r   r   r   r   r  r  r"   r   r   r  r  +  s9         ''III" " " " " "r   r  c                      e Zd ZU dZded<   ded<   d)d*dZd+d
Zd,dZd-dZd-dZ	d.dZ
d/dZd-dZd-dZd-dZd-dZd0dZd1dZd-dZd2d!Zd2d"Zd3d4d&Zd-d'Zd+d(ZdS )5r  z-A word token, possibly containing expansions.r	   r   rq   r   Nr   c                8    d| _         || _        |g }|| _        d S )Nr   )r.  r   r   )r   r   r   s      r   r   zWord.__init__;  s%    	
=E


r   r   c                x   | j         }|                     |          }|                     |          }|                     |          }|                     |          }|                     |          }|                     |          }|                     |          }|                    dd          }|                    dd          }|	                    d          r|	                    d          s|dz   }|                    dd                              dd	                              d
d          }d|z   dz   S )NzrD   \\z\\\\rE   \"rO   \nrN   \tz(word ""))
r   _expand_all_ansi_c_quotes_strip_locale_string_dollars_normalize_array_whitespace_format_command_substitutions#_normalize_param_expansion_newlines_strip_arith_line_continuations_double_ctlesc_smartreplacerN  )r   r   escapeds      r   r  zWord.to_sexpB  s)   
..u5511%8800772259988??44U;; ))%00fj11dF++>>&!! 	#%..*D*D 	#FNE--U++33D%@@HHuUU7"T))r   ry   rR   byte_valr   r  c                0    |                     |           dS )zAAppend byte to result (CTLESC doubling happens later in to_sexp).N)rw   )r   ry   r  s      r   _append_with_ctlesczWord._append_with_ctlesc^  s    hr   c                   g }t                      }|D ]}|dk    r|j        s|j         |_        n|dk    r|j        s|j         |_        |                    |           |dk    rs|j        rWd}t	          t          |          dz
  dd          D ]}||         dk    r|dz  } |dz  dk    r|                    d           |                    d           d	                    |          S )
zEDouble CTLESC bytes unless escaped by backslash inside double quotes.r  rE   r   rg   rH   rD   re   ru   )r  r  r  rw   ranger   rx   )r   r   ry   r6  r#   rj   rk   s          r   r  zWord._double_ctlesc_smartb  s    	* 	*ACxxx#(</c%,#(</MM!F{{ < * H"3v;;?B;; " "!!9,,$MHH!!|q((f--- MM&)))wwvr   c                   g }d}t                      }|t          |          k     r||         }|dk    r0|j        s)|j         |_        |                    |           |dz  }n8|dk    r0|j        s)|j         |_        |                    |           |dz  }nt          ||d          r|j        s|                    d           |                    d           |dz  }|t          |          k     o||         d	k    }|r|                    d
           |dz  }d}|t          |          k     rM|dk    rF||         }|dk    rk|dz   t          |          k     rU|j        sN||dz            d	k    r|dz  }[|                    |           |                    ||dz                       |dz  }|dk    r|j        s|j         |_        n~|dk    r|j        s|j         |_        nc|                                sO|dk    r|dz  }nC|dk    r=|dz  }|dk    r2|r|                    d
           |                    |           |dz  }n4|                    |           |dz  }|t          |          k     r|dk    Fn|                    |           |dz  }|t          |          k     d                    |          S )zNormalize newlines at param expansion boundaries.

        When there's a newline immediately after ${, bash converts it to a space
        and adds a trailing space before the closing }.
        r   r  re   rE   rF  rf   r  rg   rO   rM   rD   r  ru   )r  r   r  r  rw   ro   r#  rx   )	r   r   ry   rz   r6  r#   had_leading_newliner3  r  s	            r   r  z(Word._normalize_param_expansion_newlines~  s    #e**nnaACxxx#(</a   Qc%,#(</a   Q$UAt44 )U\ )c"""c"""Q&'#e**n&IqT9I#& MM#&&&FA#e**nnqBTzza!ec%jj&8&8&8 Q<4//FA$b)))eAEl333Q Syyy+0<'7s5<+0<'7"__.. &99!QJEE3YY!QJE$zz#6 !7$*MM#$6$6$6 &b 1 1 1 !Q %MM"%%%FA7 #e**nn: a   Qk #e**nnl wwvr   rQ   c                    |sdS |dk    rdS dg}|D ]3}|dk    r|                     d           |                     |           4|                     d           d                    |          S )zJShell-quote a string using single quotes (matches bash's sh_single_quote).z''r  z\'z'\''ru   rv   )r   rQ   ry   r#   s       r   _sh_single_quotezWord._sh_single_quote  s     	4885 	! 	!ACxxg&&&&a    cwwvr   r\  c                   t                      }d}|t          |          k     rB||         dk    r|dz   t          |          k     r||dz            }t          |          }|dk    r|                    |           |dz  }n|dk    r|                    d           |dz  }n|dk    r|dz   t          |          k     r||dz            dk    r|d	z   }|t          |          k     rBt	          ||                   r-|dz  }|t          |          k     rt	          ||                   -t          ||d	z   |          }|t          |          k     r||         d
k    r|dz  }|s|S t          |d          dz  }|dk    r|S |                     ||           |}n|dz   }|t          |          k     rT||dz   k     rKt	          ||                   r6|dz  }|t          |          k     r||dz   k     rt	          ||                   6||dz   k    rDt          t          ||dz   |          d          }|dk    r|S |                     ||           |}n|                    t          ||                              |dz  }n|dk    r|dz   }|t          |          k     rT||dz   k     rKt	          ||                   r6|dz  }|t          |          k     r||dz   k     rt	          ||                   6||dz   k    rct          t          ||dz   |          d          }	|	dk    r|S |	                    t          |	                              d                     |}n|                    t          ||                              |dz  }n|dk    r|dz   }|t          |          k     rT||dz   k     rKt	          ||                   r6|dz  }|t          |          k     r||dz   k     rt	          ||                   6||dz   k    rct          t          ||dz   |          d          }	|	dk    r|S |	                    t          |	                              d                     |}n|                    t          ||                              |dz  }n|dk    r|d	z   t          |          k    rt||dz            }
d}|
dk    r'|dz   t          |          k    r||d	z            dk    rd}t          |
          dz  }|dk    r|S |                     ||           |d	|z   z  }n!|                    t          ||                              |dz  }n|dk    r|dz   }|t          |          k     rT||dz   k     rKt          ||                   r6|dz  }|t          |          k     r||dz   k     rt          ||                   6||dz   k    rGt          t          ||dz   |          d          dz  }|dk    r|S |                     ||           |}n0|S |dk    r|dk    r|dz   }|t          |          k     rT||dz   k     rKt          ||                   r6|dz  }|t          |          k     r||dz   k     rt          ||                   6t          t          ||dz   |          d          dz  }|dk    r|S |                     ||           |}np|                    d           |                    t          |                     |dz  }n3|	                    ||                             d                     |dz  }|t          |          k     B|S )zAExpand ANSI-C escapes to literal bytes (matches bash's ansicstr).r   rD   re   rg   r  r   xr  r-  r  r      r   u   rT   Ur6   r#   r   r&   r3   1r/   r:   )rR   r   rK   rw   r-   r_   r   r  ordr  chrrV   r0   )r   r\  ry   rz   r#   simplerk   hex_strr  	codepoint	ctrl_char
skip_extractrl_vals                r   _ansi_c_to_byteszWord._ansi_c_to_bytes  s   #e**nnQx4AECJJ$6$6!a%L)!,,Q;;MM&)))FAA#XXMM$'''FAA#XX1us5zz))eAElc.A.AE#e**nnuQx1H1HnFA  #e**nnuQx1H1Hn",UAE1"="=s5zz>>eAh#ooFA& *#)M#&w#3#3d#:#q==#)M00BBBE#e**nnQU}USTX?V?VFA  #e**nnQU}USTX?V?Vq1u99'*:eQUA+F+F'K'KH'1}}'- 44VXFFF !AA"MM#eAh--888FAA#XXAAc%jj..QQYY=q;R;RYQ c%jj..QQYY=q;R;RY1q5yy$'
5!a%(C(CR$H$H	$>>#)Mc)nn&;&;G&D&DEEEc%(mm444Q#XXAAc%jj..QRZZM%PQ(<S<SZQ c%jj..QRZZM%PQ(<S<SZ1q5yy$'
5!a%(C(CR$H$H	$>>#)Mc)nn&;&;G&D&DEEEc%(mm444Q#XX1uE

**$)!a%L	%&
$,,Q#e**1D1DqSTuY]I]I])*J#&y>>D#8#q==#)M00BBBQ^+c%(mm444Q#XXAAc%jj..QQYY?5QR8;T;TYQ c%jj..QQYY?5QR8;T;TY1q5yy#&z%Q'B'BA#F#F#M#q==#)M00BBB%#XX!s((AAc%jj..QQYY?5QR8;T;TYQ c%jj..QQYY?5QR8;T;TY":eQUA#>#>BBTIH1}}%,,VX>>>AAMM$'''MM#a&&)))FAAeAhoog66777QS #e**nnT r   c                   |                     d          r|                    d          s|S t          |dt          |          dz
            }|                     |          }|                    dd          }|                     |          S )zExpand ANSI-C escape sequences in $'...' strings.

        Two-phase approach matching bash's architecture:
        1. Expand escapes to literal bytes (ansicstr)
        2. Apply shell quoting to result (sh_single_quote)
        r  re   rT   r  )errors)rb   rN  r_   r   r  decoder  )r   r   r\  literal_bytesliteral_strs        r   _expand_ansi_c_escapeszWord._expand_ansi_c_escapes>	  s       %% 	%..*=*= 	L5!SZZ!^44--e44#**79*EE$$[111r   c           	        g }d}t                      }d}d}|t          |          k     r||         }|dk    r%|j        s| }|                    |           |dz  }G|rp|dk    rO|dz   t          |          k     r9|                    |           |                    ||dz                       |dz  }n|                    |           |dz  }|j        st	          ||d          r5|dz  }|                                 |                    d           |dz  }|dk    rB|dk    r<|j        s5|dz  }|                    |           |                                 |dz  }N|j        }|d	k    rd|sb|j         o.|dk    o(||dz
           d
k    ot          ||dz
            dz  dk    }	|	s|j         |_        |                    |           |dz  }n|dk    r0|j        s)|j         |_        |                    |           |dz  }n|dk    rW|dz   t          |          k     rA|j        s:|                    |           |                    ||dz                       |dz  }n6t          ||d          r
|j        s|st          ||          dz  dk    r|dz   }
|
t          |          k     rR||
         dk    r|
dz   t          |          k     r|
dz  }
n||
         d	k    r|
dz  }
n|
dz  }
|
t          |          k     Rt          |||
          }|                     t          |dt          |                              }|                                }|dk    r|r|                    d	          r|                    d	          rt          |dt          |          dz
            }|                    d          dk    rd                    |          }d}|                    d          }|dk    rg||dz   d         }d}|r|d         dv rd}nt|d                                         s|d         dk    rN|t          |          k     r;||         }|                                s|dk    sn|dz  }|t          |          k     ;|dk    r|t          |          k     r|d         dvrv||d         }|                    d          rt          |          dk    r
|dd         }dD ]}|                    |          rd} n|s|r|d         dvrdD ]
}||v rd} nn<|dk    r6t          |          dk    r#|d         }|dvr|dd         }dD ]
}||v rd} n|s|}|                    |           |
}n|                    |           |dz  }|t          |          k     d                    |          S )z:Find and expand ALL $'...' ANSI-C quoted strings in value.r   Fr  re   rD   rg   rF  r  r  rf   rE   z$'r  rH   ru   Nz@*#?-$!0123456789_r  z#?-r.  )
r*  r)  r'  r!  r(  r  r  r+  r,  r-  Tz%#/^,~:+-=?z%#/^,)r  r   r  rw   ro   r  r  r!  rl   rc   r_   r  r(  rb   rN  findrx   rfindr8  r  )r   r   ry   rz   r6  in_backtickr1  r  effective_in_dquote	is_ansi_crk   ansi_strexpandedouter_in_dquoter\  
result_str
in_patternlast_brace_idxafter_bracevar_name_lenr#   op_startr  r$  rests                            r   r  zWord._expand_all_ansi_c_quotesL	  s   #e**nnqBSyyy"-ob!!!Q ::!a%#e**"4"4MM"%%%MM%A,///FAAMM"%%%FA< &ua66 1$KJJLLLMM$'''FA3YY;??5<?1$KMM"%%%IIKKKFA"',Syy!4y $ QAQa!e+Q :%QGG!KqP	  ! 4',|#3ELb!!!Qs5<#(</b!!!QtAE

 2 25< 2b!!!eAEl+++Qq$//vv ,v 6eQ??!CqHH E#e**nnQx4''AECJJ,>,>QqSQQ #e**nn &eQ2266xCMM::  #("4"4"6"6!OO' $ ++C00 $ !))#.. $
 'xCMMA4EFFEzz&))R// &(WWV__
%*
)3)9)9$)?)?)Q..*4^a5G5I5I*JK+,L* 
:#.q>5I#I#I34LL%0^%;%;%=%= !:QSVAVAV*6[9I9I*I*I,7,E01		 )2qCxx,1(4(9	 +7[9I9I*I*I !-q 0 0$03{3C3C$C$C$/N%$?$?+6|}}+E#+#6#6s#;#; !<HPQ@Q@Q/7|H*a !. !.B'/':':2'>'> %.59
(-%. (2 !2h !28A;VcCcCc/& %2 %2 ,.>>9=J,1E ,:
 ".!2!2s;7G7G!7K7K-8^
#-W#<#<+6qrr?D/& %2 %2 ,.::9=J,1E ,6  * -',Hh'''b!!!Q] #e**nn^ wwvr   c                   g }d}d}d}t                      }t                      }d}|t          |          k     r||         }	|	dk    r^|dz   t          |          k     rH|j        sA|j        s:|                    |	           |                    ||dz                       |dz  }n!t	          ||d          rg|j        s`|j        sY|dk    s||dz
           dk    rD|dz  }d|_        d|_        |                    d           |                    d           |dz  }n|	d	k    r<|dk    r6|j        s/|j        s(|j        s!|dz  }|                    |	           |dz  }ng|	d
k    r7|dk    r1|j        s*|j        s#|dz  }d}|                    |	           |dz  }n*|	dk    r0|dk    r*|j        s#|s!|dz  }|                    |	           |dz  }n|	dk    r6|j        s/|dk    r)|j         |_        |                    |	           |dz  }n|	dk    r6|j        s/|dk    r)|j         |_        |                    |	           |dz  }n||	dk    r,|j        s%|dk    r| }|                    |	           |dz  }nJ|	dk    r=|j        s6|j        s/|dk    r)|j         |_        |                    |	           |dz  }n|	dk    r<|j        s5|j        s.|dk    r(|j         |_        |                    |	           |dz  }nt	          ||d          r|j        s|j        s|dk    s|dk    s|j        sy|j        sr|spdt          ||          z   }
|
dz  dk    r9|                    d           |dk    rd}n|dk    rd|_        nd|_        |dz  }n5|                    |	           |dz  }n|                    |	           |dz  }|t          |          k     d                    |          S )z@Strip $ from locale strings $"..." while tracking quote context.r   FrD   re   rg   rF  rf   r  r  r  r  r  rE   r  Tru   )r  r   r  rw   rc   r  rl   rx   )r   r   ry   rz   r1  r2  r6  brace_quotebracket_in_double_quoter  rX  s              r   r  z!Word._strip_locale_string_dollars
  s    ll"'#e**nnqBTzza!ec%jj000kN`0b!!!eAEl+++Qq$//UU $*U
 !VVuQU|s22q %*"%*"c"""c"""Qc		!OO $#* $ $* $
 q b!!!Qs{Qu|KL^"*/'b!!!Qc		ma///Md/ "b!!!Qs5<K14D4D#(</b!!!Qs5<K14D4D#(</b!!!Qs5<MA4E4E.E*E'b!!!Qs5<8J{]^)4);%;"b!!!Qs5<8J{]^)4);%;"b!!!Qq$// $* !1__(9(9(9#* ):/ ):
  !#DUA#N#NN!#q((MM#&&&$q((26//$q-1**'+FAA MM"%%%FAAb!!!Qy #e**nnz wwvr   c                   d}|t          |          k     r&||                                         s||         dk    s|S |dz  }|t          |          k     rd||                                         s||         dk    r>|dz  }|t          |          k     r&||                                         2||         dk    >|t          |          k     r||         dk    rd}|dz  }|t          |          k     rG|dk    rA||         dk    r|dz  }n||         dk    r|dz  }|dz  }|t          |          k     r|dk    A|dk    r|S |t          |          k     r||         dk    |t          |          k     r||         dk    r|dz  }|dz   t          |          k     r||         dk    r||dz            dk    s|S t          |d|dz             }|dz   }|                    d	          rt          |          dz
  }n|                     ||          }|dk     r|S t          ||dz   |          }t          ||dz   t          |                    }|                     |          }	|dz   |	z   d	z   |z   S )
zKNormalize whitespace inside array assignments: arr=(a  b	c) -> arr=(a b c).r   r  re   r  r  r  r  r  r   )r   r8  r  r_   rN  _find_matching_paren_normalize_array_inner)
r   r   rz   r3  r`   open_paren_posclose_paren_posr\  rU  ry   s
             r   r  z Word._normalize_array_whitespacel
  s    CJJE!H$4$4$6$6%(c//L	Q#e**nn%("2"2"4"4naCFA #e**nn%("2"2"4"4naC #e**nnqSEFAc%jj..UQYY8s??QJEE1X__QJEQ c%jj..UQYY zz #e**nnqS s5zz>>eAh#ooFAAE

""uQx35Q<3;N;NLE1a!e,,Q>># 	!%jj1nOO"77~NNO""5.1"4oFFE?Q#6E

CC,,U33|f$s*V33r   open_posc                   |t          |          k    s||         dk    rdS |dz   }d}t                      }|t          |          k     r|dk    r||         }|dk    r#|dz   t          |          k     r|j        s|dz  }L|dk    r|j        s|j         |_        |dz  }l|dk    r|j        s|j         |_        |dz  }|j        s|j        r|dz  }|d	k    rD|t          |          k     r0||         d
k    r$|dz  }|t          |          k     r||         d
k    $|dk    r|dz  }n|dk    r|dz  }|dk    r|S |dz  }|t          |          k     r|dk    dS )zLFind position of matching ) for ( at open_pos, handling quotes and comments.r  rH   re   r   rD   rg   r  rE   r  rO   r   )r   r  r  r  )r   r   r  rz   r3  r6  r  s          r   r  zWord._find_matching_paren
  s   s5zz!!U8_%;%;2qL#e**nnqBTzza!ec%jj000QSyyy#(</QSyyy#(</Q| u| QSyy#e**nnqT)9)9FA #e**nnqT)9)9Syy
s
A::HFA? #e**nn@ rr   c                   g }d}d}d}d}|t          |          k     r3||         }t          |          rO|s%|r#|dk    r|dk    r|                    d           d}|dk    s|dk    r|                    |           |dz  }n|dk    rxd}|dz   }|t          |          k     r0||         dk    r$|dz  }|t          |          k     r||         dk    $|                    t          |||dz                        |dz   }n;|dk    rd}|dz   }dg}	d}
|t          |          k     r:||         dk    rj|dz   t          |          k     rT||dz            d	k    r|d
z  }n|	                    ||                    |	                    ||dz                       |d
z  }nt	          ||d          r |	                    d           |
dz  }
|d
z  }n||         dk    r&|
dk    r |	                    d           |
dz  }
|dz  }nM||         dk    r!|
dk    r|	                    d           |dz  }n4|	                    ||                    |dz  }|t          |          k     :|                    d                    |	                     |}n|dk    r\|dz   t          |          k     rF||dz            d	k    r|d
z  }n|d}|                    t          |||d
z                        |d
z  }nLt	          ||d          rd}|dz   }d}|t          |          k     r|dk    r|dz   t          |          k     r&||         dk    r||dz            dk    r|dz  }|d
z  }nA|dz   t          |          k     r&||         dk    r||dz            dk    r|dz  }|d
z  }n|dz  }|t          |          k     r|dk    |                    t          |||                     |}n[t	          ||d          rjd}|d
z   }d}|t          |          k     r%|dk    r||         dk    r|dk    r||dz
           dk    r|dz  }n||         dk    r|dz  }n||         dk    rI|dz  }|t          |          k     r0||         dk    r$|dz  }|t          |          k     r||         dk    $nq||         dk    re|dz  }|t          |          k     rM||         dk    r|dz   t          |          k     r|d
z  };||         dk    rn|dz  }|t          |          k     M|dz  }|t          |          k     r|dk    |                    t          |||                     |}n|dk    s|dk    r||dz   t          |          k     re||dz            dk    rUd}|d
z   }d}|t          |          k     r|dk    r	||         dk    r|dz  }n||         dk    r|dz  }n||         dk    rI|dz  }|t          |          k     r0||         dk    r$|dz  }|t          |          k     r||         dk    $nq||         dk    re|dz  }|t          |          k     rM||         dk    r|dz   t          |          k     r|d
z  };||         dk    rn|dz  }|t          |          k     M|dz  }|t          |          k     r|dk    	|                    t          |||                     |}nVt	          ||d          r#d}|                    d           |dz  }|d
z  }n"|dk    r&|dk    r |                    |           |dz  }|dz  }n|dk    r&|dk    r |                    |           |dz  }|dz  }n|dk    rL|dk    rF|rD|t          |          k     r0||         d	k    r$|dz  }|t          |          k     r||         d	k    $nx|dk    r*|s|dk    r|dz  }d}|                    |           |dz  }nH|dk    r&|dk    r |                    |           |dz  }|dz  }nd}|                    |           |dz  }|t          |          k     3d                    |                                          S )zFNormalize whitespace inside array content, handling nested constructs.r   TrM   re   r  FrE   rD   rO   rg   rF  r  ru   $((r-  r  r   r  rf   r  r  r  r  r  r  )r   rP   rw   r_   ro   rx   rstrip)r   r\  
normalizedrz   in_whitespacer1  r2  r  rk   
dq_contentdq_brace_depthr3  s               r   r  zWord._normalize_array_inner
  s	   
#e**nnqBb!! h$ ) )q8H8H]^_M_M_%%c***$(M??ma&7&7%%b)))Qs %E#e**nnqSFA #e**nnqS!!*UAq1u"="=>>>Es !&E!U
!"#e**nnQx4''AECJJ,>,> Q<4//FAA&--eAh777&--eAEl;;;FAA,UAt<< "))$///&!+QqS^a-?-?"))#...&!+QqS^q-@-@"))#...Q"))%(333Q3 #e**nn4 !!"''*"5"5666tAE

 2 2Q<4''FAA %*M%%j1q5&A&ABBBFAA$UAu55 m %E#e**nn1us5zz))eAh#oo%A,RUBUBU
QQU++aCE!a%LTWDWDW
QQ #e**nn !!*UAq"9"9:::$UAt44 ] !&E#e**nnQx31q55U1q5\S5H5H
qS
qSQ#e**nnqSFA  #e**nnqSqSQ#e**nn$Qx4//AECJJ4F4F !Q ($Qx3 %FA  #e**nn FA% #e**nn( !!*UAq"9"9:::))rSyya!ec%jj.@.@U1q5\UXEXEX !&E#e**nnQx3
qS
qSQ#e**nnqSFA  #e**nnqSqSQ#e**nn$Qx4//AECJJ4F4F !Q ($Qx3 %FA  #e**nn FA% #e**nn( !!*UAq"9"9:::$UAt44 % %!!$'''q Qs{Q!!"%%%q Qs{Q!!"%%%q Qs{a//M/#e**nnqT)9)9FA #e**nnqT)9)9s ! 'MA$5$5!Q&M %!!"%%%Qs}q00!!"%%%"Q %!!"%%%QU #e**nnX wwz""))+++r   c                   g }d}|t          |          k     rt          ||d          rh|}|dz  }d}g }d}|t          |          k     r|dk    r||         dk    r)|                    d           |dz  }|dz  }|dk    rd}nS||         dk    r<|dk    rt          |          }|dz  }|dk    r|                    d           |dz  }n||         d	k    r|dz   t          |          k     r||dz            d
k    rd}t          |          dz
  }	|	dk    r#||	         d
k    r|	dz  }	|	dk    r||	         d
k    |	dk    r(||	         d	k    r|dz  }|	dz  }	|	dk    r||	         d	k    |dz  dk    r0|                    d	           |                    d
           |dz  }n|dz  }|dk    rd}n(|                    ||                    |dz  }|dk    rd}|t          |          k     r|dk    |dk    s|dk    rm|dk    rgd                    |          }
|dk    r0|
d|         }
|dk    rdnd}|                    d|
z   |z              na|                    d|
z   dz              nE|                    t	          |||                     n |                    ||                    |dz  }|t          |          k     d                    |          S )zAStrip backslash-newline (line continuation) from inside $((...)).r   r  r-  rg   rH   r  re   r   rD   rO   ru   N)))r   ro   rw   rx   r_   )r   r   ry   rz   r\   r3  arith_contentfirst_close_idxnum_backslashesrk   r  closings               r   r  z$Word._strip_arith_line_continuationsu  sp   #e**nn"5!U33 ?Q "')#e**nnQx3%,,S111
Q 199.0OqS A::.1-.@.@O
 199)00555QqT))a!ec%jj.@.@U1q5\UYEYEY*+..21ffq)9T)A)AFA  1ffq)9T)A)A1ffq)9T)A)A+q0OFA  1ffq)9T)A)A +Q.!33)00666)00666FAA FA A::.0O%,,U1X666Q A::.0OM #e**nnN A::%1**B1F1F ggm44G&",,")*:?*:"; +01**$$#ego&?@@@@ ego&;<<<< MM*UE1"="=>>>>eAh'''QC #e**nnD wwvr   r  r  c                H   g }t          |t                    r|                    |           nt          |t                    ri|j        D ]_}|j        D ]U}t          |t                    r|                    |           -|                    |                     |                     V`nut          |t                    r6|j	        -|                    |                     |j	                             n*t          |t                    st          |t                    r\|                    |                     |j                             |                    |                     |j                             nt          |t                    sTt          |t                    s?t          |t                     s*t          |t"                    st          |t$                    r/|                    |                     |j                             nt          |t(                    r|                    |                     |j                             |                    |                     |j                             |                    |                     |j                             not          |t0                    rZ|                    |                     |j                             |                    |                     |j                             |S )z?Recursively collect CommandSubstitution nodes from an AST node.)
isinstanceCommandSubstitutionrw   Arrayelementsr   r  _collect_cmdsubsArithmeticExpansion
expressionArithBinaryOp
ArithCommaleftrightArithUnaryOpArithPreIncrArithPostIncrArithPreDecrArithPostDecroperandArithTernary	conditionif_trueif_falseArithAssigntargetr   r   r  ry   elemps        r   r  zWord._collect_cmdsubs  s   d/00 	=MM$e$$ 	= @ @ @ @A!!%899 @a((((d&;&;A&>&>????	@@ 122 	=*d33DODDEEEm,, 	=
40L0L 	=MM$//	::;;;MM$//
;;<<<<t\**	=$--	= $..	= $--		=
 $..	= MM$//==>>>>l++ 	=MM$//??@@@MM$//==>>>MM$//>>????k** 	=MM$//<<===MM$//
;;<<<r   c                X   g }t          |t                    r|                    |           n|t          |t                    rg|j        D ]_}|j        D ]U}t          |t                    r|                    |           -|                    |                     |                     V`|S )z?Recursively collect ProcessSubstitution nodes from an AST node.)r  ProcessSubstitutionrw   r  r  r   r  _collect_procsubsr   s        r   r  zWord._collect_procsubs  s    d/00 	AMM$e$$ 	A A A A AA!!%899 Aa((((d&<&<Q&?&?@@@@	A
 r   Fin_arithr$   c                '   g }g }d}| j         D ]}|j        dk    r|                    |           #|j        dk    r|                    |           D|j        dk    rd}R|                    |                     |                     |                    |                     |                     |                    d          dk    pJ|                    d          dk    p1|                    d	          dk    p|                    d
          dk    }d}d}	d}
t                      }|
t          |          k     rT||
         dk    r|j	         |_	        |
dz  }
n ||
         dk    rh|j	        sa|
dz  }
|
t          |          k     r0||
         dk    r$|
dz  }
|
t          |          k     r||
         dk    $|
t          |          k     r|
dz  }
nt          ||
d          r4t          ||
d          s#t          ||
          st          ||
          sd}n{t          ||
d          st          ||
d          r@|j	        s9|
dk    s*||
dz
                                           s||
dz
           dvrd}	n|
dz  }
n|
dz  }
|
t          |          k     Td|v od|v pd|v }|s|s
|s|s|	s|s|S g }d}d}d}t                      }d}d}d}d}|t          |          k     r|dk    r]t          ||dz
                     rE||         dk    r9t          ||dz
            s&|dz  }|                    ||                    |dz  }w||         dk    r,|dk    r&|dz  }|                    ||                    |dz  }t          ||d          r6t          ||          s&|dz  }|                    ||                    |dz  }||         dk    r-|dk    r'|dz  }|                    ||                    |dz  }/t          ||d          r8t          ||          s(|r&|dz  }|dz  }|                    d           |dz  }x|dk    r=|dk    r7t          ||d          r&|dz  }|dz  }|                    d           |dz  }|dk    rf||         dk    r'|dz  }|                    ||                    |dz  }||         dk    r'|dz  }|                    ||                    |dz  }'t          ||d          rU|sSt!          ||dz             }|                    t#          |||                     |t          |          k     r|dz  }|}t          ||d          rst          ||d          sat          ||          sPt          ||          s?t!          ||dz             }|dk    r@|                    t#          |||                     |t          |          k     r|dz  }|},t#          ||dz   |dz
            }|t          |          k     r"||         }t%          |j                  }|dz  }nJ	 t)          |          }|                                }|rt%          |          nd}n# t,          $ r |}Y nw xY w|                    d          r|                    d|z   dz              n|                    d|z   dz              |}n||         dk    r|t          |          k     r|dz   }|t          |          k     rR||         dk    r|dz   t          |          k     r|dz  };||         dk    r|dz  }n|dz  }|t          |          k     R|                    t#          |||                     |dz  }|}nt          ||d          r|dz   t          |          k     rzt1          ||dz                      rat          ||          sPt3          ||dz             }|t          |          k     r||         nd }t5          |t6                    r|j        r|}t%          |j                  }||dz            d!k    }|rd
nd}t#          ||dz   |dz
            }|                    d"          } |r|                                rd#}!nK|                    d$          s|                    d%          r|                    d$          rd&nd#}!n| rd'}!nd(}!|                    ||z   |!z              |dz  }n$|                    t#          |||                     |}
nst          ||d          st          ||d          rG|j	        s?|dk    r8|dk    r1|dk    p*||dz
                                            o||dz
           dv}"|dk    rSt!          ||dz             }|                    t#          |||                     |t          |          k     r|dz  }|}.|t          |          k     r||         }#t!          ||dz             }||         }t?          |j                  }$t%          |j        dd|$d          }t#          ||dz   |dz
            }%|j        j        d)k    rd}&|&t          |%          k     r,|%|&         d*v r"|&dz  }&|&t          |%          k     r
|%|&         d*v "|%d |&         }'|%|&d          }(|(                    d          r|'rb|'                     d"d+                               d,d+          })t%          |j        d-          }*|                    |#dz   |)z   |*z   dz              n4|%                     d.d          }%|                    |#dz   |%z   dz              |dz  }|}t#          ||dz   |dz
            }%|%                     d.d          }+t?          |j                  r%||+k    r|                    |#dz   |+z   dz              n |#dz   |z   dz   },|                    |,           |dz  }|}n|"r@t          | j                   r+||         }#t!          ||dz             }|t          |          k    s(|dk    rD|t          |          k    r1||dz
           dk    r"|                    ||                    |dz  }	t#          ||dz   |dz
            }	 t)          |          }|                                }|r?|j!        t          |          k    r'd"|vr#t?          |          }$t%          |dd|$d          }n|}n# t,          $ r |}Y nw xY w|                    |#dz   |z   dz              |}nH|"r||         }#t!          ||dz             }|t          |          k    s(|dk    rD|t          |          k    r1||dz
           dk    r"|                    ||                    |dz  }t#          ||dz   |dz
            }|r|                    |#dz   |z   dz              nf|"                                r4|#                    d/          }(|                    |#dz   |(z   dz              n|                    |#dz   |z   dz              |}n+|                    ||                    |dz  }n	t          ||d          s4t          ||d          s#t          ||d	          st          ||d
          r t          ||          st#          |||dz                                  d,d+                               d"d+          }|dz   }d}-|t          |          k     rG|-dk    rA||         d0k    r|-dz  }-n||         d#k    r|-dz  }-|dz  }|t          |          k     r|-dk    At#          ||dz   |dz
            }|"                                dk    r|                    d1           n	 t)          |#                    d2                    }|                                }|rt%          |          }|$                    d3          }|$                    d/                              d"          rd'}.n|                    d4          rd&}.nd(}.|                    ||z   |.z              n|                    d1           n4# t,          $ r' |                    t#          |||                     Y nw xY w|}nt          ||d          rt          ||          s|dz   }d}-t                      }/|t          |          k     r|-dk    r||         }0|0dk    r#|dz   t          |          k     r|/j%        s|dz  }J|0dk    r|/j	        s|/j%         |/_%        n||0dk    r|/j%        s|/j	         |/_	        na|/&                                sMt          ||d          r%t          ||d          st!          ||dz             }|0d0k    r|-dz  }-n|0d#k    r|-dz  }-|dz  }|t          |          k     r|-dk    |-dk    rt#          ||dz   |          }nt#          ||dz   |dz
            }| '                    |          }1| (                    |1          }1|-dk    r|                    d|1z   d#z              n|                    d|1z              |}n||         dk    r.|j	         |_	        |                    ||                    |dz  }n||         dk    r|j	        s|dz   }|t          |          k     r0||         dk    r$|dz  }|t          |          k     r||         dk    $|t          |          k     r|dz  }|                    t#          |||                     |}n |                    ||                    |dz  }|t          |          k     d)                    |          S )5zIReplace $(...) and >(...) / <(...) with bash-oracle-formatted AST output.FcmdsubprocsubarithTz${ rH   z${	z${
z${|r   rE   re   r  r  r  z<(z>("'rF  r  r   $[r  rg   r-  r  ru   z$( r  rD   Nr  rO   r  r  z&  }z
 }; }subshell 	
rM   rN   )
in_procsub\
 	r  z${ }z 	
|r   &)*r   r.  rw   r  r  r  r  r  r   r  rc   _is_backslash_escaped_is_dollar_dollar_parenr  r  ro   _find_cmdsub_endr_   rQ  commandrO  rP  rR  rb   r  _find_funsub_endr  r  bracerN  isspace_starts_with_subshellr  r
   striplstripr  r  r#  r  _normalize_extglob_whitespacerx   )2r   r   r  cmdsub_partsprocsub_parts	has_arithr  has_brace_cmdsubhas_untracked_cmdsubhas_untracked_procsubidx
scan_quotehas_param_with_procsub_patternry   rz   
cmdsub_idxprocsub_idx
main_quoteextglob_depthdeprecated_arith_depthr4  r5  rk   r\  r  r_  parserr^  r  has_piper`   
orig_innerends_with_newlinerU  r   r  compactraw_contentleading_ws_end
leading_wsstrippednormalized_wsspacedraw_strippedfinal_outputr3  
terminatorr  r#   formatted_inners2                                                     r   r  z"Word._format_command_substitutions  s    	 		@ 		@Av!!##A&&&&9$$$$Q''''7"" 		##D$9$9!$<$<===$$T%;%;A%>%>???? JJu# 'zz&!!R''zz&!!R'' zz%  B&	 	  % %\\
CJJSzS  (2(9$9
!qss"":+<" qCJJ&&5:+<+<1HC CJJ&&5:+<+<U##1HCsD11'sE:: .eS99 0s;;	 (,$sD115DUCQU5V5V ' !88E#'N$:$:$<$<8sQwW\A\A\,0)qq? CJJB *.)[DEM<ZTUZ]&	!	 %	 )		
 *	 3	 L
\\
!"#e**nn A&uQU|44 !HOO-eQU;; $ "eAh'''QQx3=1#4#4"eAh'''Qua.. 7LUTU7V7V &!+&eAh'''QQx3#9A#=#=&!+&eAh'''Q $E1e44	-eQ77	 	
 q !Q&!e$$$QQ#4#9#9oeUVX\>]>]#9q !Q&!d###QQ8s??%*%MM%(+++FA1X__%*%MM%(+++FA #5!U33 I  %UAE22j155666L 1 111!OJ  q$//p'q%88p .eQ77p 0q99	p %UAE22 1$$MM*UAq"9"9:::!C$5$555"a
A"5!a%Q77L 1 111'
3D 3DL A AI!OJJ*!'!'!2!2!4!4CI$Q$7$?$?$?r		$ * * *$)			* '',, :MM%)"3c"9::::MM$"2S"8999qSZ#l2C2C%C%CE#e**nnQx4''AECJJ,>,>Q Qx3QFA #e**nn j155666a
 $E1d33{ECJJ&&#E!a%L11 '-eQ77 '
 %UAE22:Ds<GXGX:X:Xl:66^bk+>?? ;KDU ;&D 3DL A AI$QU|s2H&.9UUEF!+E1q5!a%!@!@J(2(;(;D(A(A%$ '	(9(9(;(; '!$"++C00 'I4F4Ft4L4L ')2););C)@)@!Ic* '!' "'MM&9"4v"=>>>!OJJ MM*UAq"9"9::: !400T4CE1d4S4ST")T +a//1$$ !VaE!a%L,@,@,B,B(B(`uQQRU|[`G`
 1$$(A66AMM*UAq"9"9:::"S%7%777#q(A]!3!333 %aI(A66A(5D3DLAAG 3DL!T7TX Y YI",UAE1q5"A"AK|(J66)**S-=-=== +N ;w F F*a/N +S-=-=== +N ;w F F &1.%A
#.~#?#..s33 %) S0:0B0B40M0M0U0UVZ\_0`0`)<T\V[)\)\)\ &i#o.MPV.VY\.\ ] ] ] ] /:.A.A&".M.M &i#o.Kc.Q R R R'1,K !A$",UAE1q5"A"AK#.#6#6vr#B#BL -T\:: 4yL?X?Xi#o&Ds&JKKKK'03'BS'Hl3331$KAA .C
OO . %aI(A66A3u::~~!a%%AUOOaRSeX[H[H[eAh///Q &ua!eQU;;E*!'!'!2!2!4!4 " .fjCJJ&>&>4uCTCT&;F&C&CG(;FAtWVZ([([II(-I$ * * *$)			*MM)c/I"="CDDDAA  %aI(A66A3u::~~!a%%AUOOaRSeX[H[H[eAh///Q &ua!eQU;;E Ei#o&=&CDDDD E#(<<#6#6i#o&@3&FGGGGi#o&=&CDDDAA MM%(+++FAA $E1e44f&ua88f 'ua88f 'ua77	f
 ,E155f $E1a!e44<<T3GGOOPTVYZZE#e**nnQx3
qS
FA #e**nn #5!a%Q77;;==B&&MM&))))?!'X(>(>!?!?!'!2!2!4!4! 2(;F(C(CI(1(8(8(=(=I$||E22;;DAA 3-3

!*!3!3D!9!9 3-1

-2
"MM&9*<z*IJJJJ"MM&111$ ? ? ?j1&=&=>>>>>? %UAt44 ;=RSXZ[=\=\ ;E(ll#e**nnaADyyQUSZZ%7%7@R%7Q Cxx(:x1<1C-C**c+*<1<1C-C**(2244 
'.ua>> %!1eH H % !1A > >A$88!QJEE#XX!QJEFA) #e**nn. 199&ua!eQ77EE&ua!eQU;;E"&"D"DU"K"K"&"D"D_"U"UA::MM$"83">???? MM$"8999qS(2(9$9
!eAh'''Q qS):E#e**nnqSFA #e**nnqSs5zz>>FAj155666eAh'''Qq #e**nnr wwvs=   6Y9 9ZZA&t+ +t:9t:CAB+ B+.ACCACc                2   g }d}t                      }d}|t          |          k     r||         dk    r.|j         |_        |                    ||                    |dz  }Nt	          ||d          r6t          ||          s&|dz  }|                    ||                    |dz  }||         dk    r,|dk    r&|dz  }|                    ||                    |dz  }|dz   t          |          k     r||dz            dk    r||         }|dv r|j        s|dk    r|                    |           |                    d           |dz  }d}g }g }	d	}
|t          |          k     r|dk    r||         d
k    r<|dz   t          |          k     r&|	                    |||dz                       |dz  }c||         dk    r'|dz  }|	                    ||                    |dz  }nz||         dk    r|dz  }|dk    rpd                    |	          }d|v r|                    |           n?|
r(|                    |                                           n|                    |           n|	                    ||                    |dz  }n||         dk    r|dk    r|dz   t          |          k     r*||dz            dk    r|	                    d           |dz  }nd}
d                    |	          }d|v r|                    |           n'|                    |                                           g }	|dz  }n |	                    ||                    |dz  }|t          |          k     r|dk    |                    d                    |                     |dk    r|                    d           |dz  }|                    ||                    |dz  }|t          |          k     d                    |          S )zINormalize whitespace around | in >() and <() patterns for regex contexts.r   rE   re   r  r  r  z><rg   FrD   r   ru   r  r  r  T | )r  r   r  rw   rc   r  rx   r  )r   r   ry   rz   extglob_quoter-  prefix_charr3  pattern_partscurrent_partr/  part_contents               r   r  z"Word._normalize_extglob_whitespace  sv   "!"#e**nnQx3+8+?'?$eAh'''Qua.. 7LUTU7V7V &!+&eAh'''QQx3#9A#=#=&!+&eAh'''Q 1us5zz!!eAElc&9&9#Ah$&&}/C&H^bcHcHcMM+...MM#&&&FAE$&M#%L$Hc%jj..UQYY 8t++AE

0B0B(//a!a%i0@AAAFA$"1X__!QJE(//a999FAA"1X__!QJE$zz/1ww|/D/D#'<#7#7$1$8$8$F$F$F$F%- !G$1$8$89K9K9M9M$N$N$N$N$1$8$8$F$F$F %(//a999FAA"1X__! 1us5zz11eAElc6I6I , 3 3D 9 9 9 !Q ,0/1ww|/D/D#'<#7#7$1$8$8$F$F$F$F$1$8$89K9K9M9M$N$N$N/1 !Q(//a999FAW c%jj..UQYYZ MM%**]";";<<<zzc***QMM%(###FAi #e**nnj wwvr   c                
   |                      | j                  }|                     |          }|                     |          }|                     |          }|                    dd          }|                    d          S )zGReturn value with command substitutions formatted for cond-term output.r  zrO   )r  r   r  r  r  r  r  r   r   s     r   get_cond_formatted_valuezWord.get_cond_formatted_value  sw     ..tz::11%882259922599fj11||D!!!r   r   )r   r	   r   r   r   )ry   rR   r  r   r   r  )r   r	   r   r	   rQ   r	   r   r	   )r\  r	   r   rR   )r   r	   r  r   r   r   )r\  r	   r   r	   )r  r  r   rq   rv  )r   r	   r  r$   r   r	   )r   r   r   r   r  r   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  rF  r"   r   r   r  r  5  s        77JJJ    * * * *8          8? ? ? ?B   n n n n`2 2 2 2v v v vpf f f fP)4 )4 )4 )4V' ' ' 'Rs, s, s, s,jF F F FP! ! ! !F   I I I I IV[ [ [ [z" " " " " "r   r  c                  :    e Zd ZU dZded<   ded<   dddZddZdS )Commandz(A simple command (words + redirections).
list[Word]wordsrq   r  Nr   c                8    d| _         || _        |g }|| _        d S )Nr  )r.  rK  r  )r   rK  r  s      r   r   zCommand.__init__+  s&    	
I"r   r   r	   c                   g }| j         D ])}|                    |                                           *| j        D ])}|                    |                                           *d                    |          }|sdS d|z   dz   S )NrM   z	(command)	(command r   )rK  rw   r  r  rx   )r   r   wrA   r\  s        r   r  zCommand.to_sexp2  s     	& 	&ALL%%%% 	& 	&ALL%%%% 	;U"S((r   r   )rK  rJ  r  r   r   r   r   r   r   r  r   r  r"   r   r   rI  rI  %  sa         22# # # # #	) 	) 	) 	) 	) 	)r   rI  c                  6    e Zd ZU dZded<   ddZddZddZdS )PipelinezA pipeline of commands.rq   commandsc                "    d| _         || _        d S )Npipeline)r.  rS  )r   rS  s     r   r   zPipeline.__init__C      	 r   r   r	   c                   t          | j                  dk    r| j        d                                         S g }d}|t          | j                  k     r| j        |         }|j        dk    r|dz  }6|dz   t          | j                  k     o| j        |dz            j        dk    }|                    ||f           |dz  }|t          | j                  k     t          |          dk    r.|d         }|d         }|d         }|                     ||          S |t          |          dz
           }|d         }|d         }	|                     ||	          }
t          |          dz
  }|dk    rs||         }|d         }|d         }|r,|j        dk    r!d|                                z   dz   |
z   dz   }
n"d|                     ||          z   d	z   |
z   dz   }
|dz  }|dk    s|
S )
Nre   r   	pipe-bothrg   r  z(pipe z (redirect ">&" 1) r   rM   )r   rS  r  r.  rw   	_cmd_sexp)r   cmdsrz   cmdneeds_redirectpairneeds	last_pairlast_cmd
last_needsry   rk   s               r   r  zPipeline.to_sexpG  s   t}""=#++---#dm$$$$-"Cx;&&QUS%7%77dDM!a%<P<UYd<dNKKn-...FA #dm$$$$ t99>>7Dq'CGE>>#u---TQ'	Q<q\
*55IIM1ff7Dq'CGE TY..!CKKMM14IIFRUXX!DNN3$>$>>DvMPSSFA 1ff r   r[  r  r\  r$   c                   |s|                                 S |j        dk    rg }|j        D ])}|                    |                                            *|j        D ])}|                    |                                            *|                    d           dd                    |          z   dz   S |                                 S )zHGet s-expression for a command, optionally injecting pipe-both redirect.r  z(redirect ">&" 1)rN  rM   r   )r  r.  rK  rw   r  rx   )r   r[  r\  r   rO  rA   s         r   rY  zPipeline._cmd_sexpm  s     	!;;== 8y  EY * *QYY[[))))] * *QYY[[))))LL,---%0366{{}}r   N)rS  rq   r   )r[  r  r\  r$   r   r	   )r   r   r   r   r  r   r  rY  r"   r   r   rR  rR  >  se         !!! ! ! !$ $ $ $L     r   rR  c                  F    e Zd ZU dZded<   ddZddZdd
ZddZddZ	dS )Listz#A list of pipelines with operators.rq   r   c                "    d| _         || _        d S )NrU   r.  r   r   r   s     r   r   zList.__init__  s    	


r   r   r	   c                   t          | j                  }dddddd}t          |          dk    r|t          |          dz
           j        dk    r|t          |          dz
           j        dk    s!|t          |          dz
           j        d	k    rt          |d
t          |          dz
            }t          |          dk    rc|t          |          dz
           j        dk    rB|t          |          dz
           j        dk    v|t          |          dz
           j        d	k    t          |          dk    r|d
                                         S |t          |          dz
           j        dk    r|t          |          dz
           j        dk    rt          t          |          dz
  d
d          D ]}||         j        dk    r||         j        dk    s||         j        d	k    rt          |d
|          }t          ||dz   t          |          dz
            }t          |          dk    r"t          |                                          }n|d
                                         }t          |          dk    r"t          |                                          }n|d
                                         }d|z   dz   |z   dz   c S t          |d
t          |          dz
            }t          |          dk    r d|d
                                         z   dz   S t          |          }	d|	                                z   dz   S | 	                    ||          S )Nandorsemi
background)r  r  r  rO   r  re   operatorr  rO   r   r  r-  r  (semi z (background r  (background r   )
rU   r   r   r.  r  rs   r  r  rd  _to_sexp_with_precedence)
r   r   op_namesrz   r  r  	left_sexp
right_sexpr  
inner_lists
             r   r  zList.to_sexp  s%    TZ  t&\ZZ JJNNc%jj1n%*j88s5zzA~&)S00E#e**q.4I4LPT4T4TUAs5zzA~66E	 JJNNc%jj1n%*j88s5zzA~&)S00E#e**q.4I4LPT4T4T u::??8##%%% Ua %33c%jj1n8M8PTW8W8W3u::>1b11 V V8=J..E!HK34F4F%PQ(+Y]J]J]#E1a00D$UAE3u::>BBE4yy1}}$(JJ$6$6$8$8		$(GOO$5$5	5zzA~~%)%[[%8%8%:%:

%*1X%5%5%7%7
#i//AJNQUUUUU"5!SZZ!^<<K;1$$%A(>(>(@(@@3FFk**J!J$6$6$8$883>>,,UH===r   rq  dict[str, str]c                   g }t          t          |                    D ]J}||         j        dk    r7||         j        dk    s||         j        dk    r|                    |           K|rg }d}|D ]@}t          |||          }|r&|d         j        dk    r|                    |           |dz   }At          ||t          |                    }|r&|d         j        dk    r|                    |           |sdS |                     |d         |          }	t          dt          |                    D ]*}d|	z   dz   |                     ||         |          z   d	z   }	+|	S |                     ||          S )
Nrm  r  rO   r   re   ()rn  rM   r   )r  r   r.  r  rw   rs   _to_sexp_amp_and_higher)
r   r   rq  semi_positionsrz   segmentsr\   r
   segry   s
             r   rp  zList._to_sexp_with_precedence  s    s5zz"" 	) 	)AQx}
**as0B0BeAhkUYFYFY%%a((( 	HE%    ueS11 )3q6;*44OOC(((a5%U44C %s1v{j00$$$ t11(1+xHHF1c(mm,,   228A;IIJ 	  M++E8<<<r   c           	        t          |          dk    r|d                                         S g }t          dt          |          dz
  d          D ]9}||         j        dk    r&||         j        dk    r|                    |           :|rg }d}|D ]+}|                    t          |||                     |dz   },|                    t          ||t          |                               |                     |d         |          }t          dt          |                    D ]*}d|z   dz   |                     ||         |          z   dz   }+|S |                     ||          S )	Nre   r   rg   rm  r  ro  rM   r   )r   r  r  r.  r  rw   rs   _to_sexp_and_or)	r   r   rq  amp_positionsrz   rz  r\   r
   ry   s	            r   rx  zList._to_sexp_amp_and_higher  s   u::??8##%%%q#e**q.!,, 	( 	(AQx}
**uQx{c/A/A$$Q''' 	HE$    s ; ;<<<aOOHUE3u::>>???))(1+x@@F1c(mm,,  " **8A;AAB 	  M##E8444r   c                   t          |          dk    r|d                                         S |d                                         }t          dt          |          dz
  d          D ][}||         }||dz            }|                    |j        |j                  }d|z   dz   |z   dz   |                                z   dz   }\|S )Nre   r   rg   r  rM   r   )r   r  r  rJ   r  )r   r   rq  ry   rz   r  r[  op_names           r   r}  zList._to_sexp_and_or  s    u::??8##%%%q!!##q#e**q.!,, 	N 	NAqBA,Cll25"%00G7]S(61C7#++--G#MFFr   N)r   rq   r   )r   rq   rq  ru  r   r	   )
r   r   r   r   r  r   r  rp  rx  r}  r"   r   r   rd  rd  ~  s         --   &> &> &> &>P#= #= #= #=J5 5 5 5<
 
 
 
 
 
r   rd  c                  .    e Zd ZU dZded<   ddZd	dZdS )
Operatorz$An operator token (&&, ||, ;, &, |).r	   r  c                "    d| _         || _        d S )Nrm  )r.  r  )r   r  s     r   r   zOperator.__init__  s    	r   r   c                ^    dddddd}d|                     | j        | j                  z   dz   S )	Nri  rj  rk  bgpipe)r  r  r  r  r  r  r   )rJ   r  )r   namess     r   r  zOperator.to_sexp  sA    
 
 UYYtw000366r   N)r  r	   r   rP  r"   r   r   r  r    sM         ..GGG   7 7 7 7 7 7r   r  c                       e Zd ZdZd ZddZdS )PipeBothz%Marker for |& pipe (stdout + stderr).c                    d| _         d S )NrX  r.  r   s    r   r   zPipeBoth.__init__  s    			r   r   r	   c                    dS )Nz(pipe-both)r"   r   s    r   r  zPipeBoth.to_sexp  s    }r   Nr   r   r   r   r   r   r  r"   r   r   r  r    s=        //          r   r  c                       e Zd ZdZd ZddZdS )EmptyzEmpty input.c                    d| _         d S Nemptyr  r   s    r   r   zEmpty.__init__       			r   r   r	   c                    dS r  r"   r   s    r   r  zEmpty.to_sexp#  s    rr   Nr   r  r"   r   r   r  r    s=               r   r  c                  .    e Zd ZU dZded<   ddZd	dZdS )
CommentzA comment (# to end of line).r	   r  c                "    d| _         || _        d S )Ncomment)r.  r  )r   r  s     r   r   zComment.__init__,  s    				r   r   c                    dS r  r"   r   s    r   r  zComment.to_sexp0  s    rr   N)r  r	   r   rP  r"   r   r   r  r  '  sM         ''III        r   r  c                  H    e Zd ZU dZded<   ded<   dZded<   ddd	ZddZdS )RedirectzA redirection.r	   r  r  r  rH   r   fdc                >    d| _         || _        || _        || _        d S )Nredirect)r.  r  r  r  )r   r  r  r  s       r   r   zRedirect.__init__<  s"    	r   r   c                x	   | j                             d          }|                    d          rd}|t          |          k     rn||                                         s||         dk    rG|dz  }|t          |          k     rd||                                         s||         dk    r>|dz  }|t          |          k     r&||                                         2||         dk    >|t          |          k     rx||         dk    rl|dz  }|t          |          k     r0||         dk    r$|dz  }|t          |          k     r||         dk    $|t          |          k     r||         dk    r|dz  }|t          |          k     r-||         dk    r!t          ||dz   t          |                    }| j        j        }| j        	                    |          }| j        
                    |          }| j                            |          }| j                            |          }|                    d          r|                    d	          s|dz   }|                    d
          r1|dk    rd}n|dk    rd}t          |dt          |                    }|                                r;t          |          dk    r(d|z   dz   t!          t          |                    z   dz   S |                    d          rg|d d                                         rKt          |d d                   dk    r0d|z   dz   t!          t          |d d                             z   dz   S |dk    rdS |                    d          r
|d d         n|}d|z   dz   |z   dz   S |dk    s|dk    r|                                r;t          |          dk    r(d|z   dz   t!          t          |                    z   dz   S |dk    rdS |                    d          rg|d d                                         rKt          |d d                   dk    r0d|z   dz   t!          t          |d d                             z   dz   S |                    d          r
|d d         n|}d|z   dz   |z   dz   S d|z   dz   |z   dz   S )N
0123456789r  re   r  r  r  r  rD   r  r  r  r  r  r  i(redirect "" r   -rH   &-z(redirect ">&-" 0)" "r  )r  r  rb   r   r8  r  r_   r  r   r  r  r  r  rN  r7  r   r	   )r   r  rk   
target_valraw	fd_targetout_vals          r   r  zRedirect.to_sexpB  s   W^^L))== 	8A3r77{{1{2a5C<<Q#b''kkr!u}}k"Q%3,,FA #b''kkr!u}}k"Q%3,, s2ww;;2a5C<<FAc"gg++"Q%3,,Q c"gg++"Q%3,,3r77{{r!u||Qs2ww;;2a5C<<#BAs2ww77B[&
[:::FF
[==jII
[>>zJJ
[@@LL
t$$ 	+Z-@-@-H-H 	+#d*J  %% 	ASyysZC
OO<<C{{}} GSZ!7!7$r)D03s3xx==@3FF||C   LS"X%5%5%7%7 LCCRCMMZ<W<W$r)D03s3ss8}}3E3EEKKT!!++$'LL$5$5>CRC3I 2%-	9D@@::t!!## NJ:(E(E$r)D03s:3G3GG#MMS  ++ ##C((SssO++--S 
3B3((J66$r)D03s:crc?7K7K3L3LLsRR)3)<)<S)A)AQj"oozG 2%-7$>>r!E)J6==r   N)rH   )r  r	   r  r  r  r   r   )r   r   r   r   r  r  r   r  r"   r   r   r  r  5  sn         GGGLLLBLLLL    D> D> D> D> D> D>r   r  c                      e Zd ZU dZded<   ded<   dZded<   dZded<   d	Zd
ed<   dZded<   d	Z	d
ed<   	 	 	 	 dddZ
ddZdS )HereDocz"A here document <<DELIM ... DELIM.r	   rm   r  Fr$   
strip_tabsquotedrH   r   r  Tcomplete
_start_posc                v    d| _         || _        || _        || _        || _        || _        || _        d| _        d S )NheredocrH   )r.  rm   r  r  r  r  r  r  )r   rm   r  r  r  r  r  s          r   r   zHereDoc.__init__  s@     	"$ r   r   c                    | j         rdnd}| j        }|                    d          r|                    d          s|dz   }d| d| dS )Nr|  r  rD   r  r  r  r  )r  r  rN  )r   r  r  s      r   r  zHereDoc.to_sexp  sf    o/UU4,D!! 	%'*:*:6*B*B 	%nG/R//G////r   N)FFrH   T)rm   r	   r  r	   r  r$   r  r$   r  r   r  r$   r   )r   r   r   r   r  r  r  r  r  r  r   r  r"   r   r   r  r    s         ,,NNNLLLJFBLLLLHJ !    $0 0 0 0 0 0r   r  c                  >    e Zd ZU dZded<   dZded<   dddZdd
ZdS )SubshellzA subshell ( list ).r  bodyNlist[Redirect | HereDoc] | Noner  c                0    d| _         || _        || _        d S )Nr  r.  r  r  r   r  r  s      r   r   zSubshell.__init__  s    		"r   r   r	   c                j    d| j                                         z   dz   }t          || j                  S )Nz
(subshell r   r  r  r  r  r   r  s     r   r  zSubshell.to_sexp  s1    di//111C7 t~666r   r   r  r  r  r  r   r   r   r   r   r  r  r   r  r"   r   r   r  r    sc         JJJ15I5555# # # # #
7 7 7 7 7 7r   r  c                  >    e Zd ZU dZded<   dZded<   dddZdd
ZdS )
BraceGroupzA brace group { list; }.r  r  Nr  r  c                0    d| _         || _        || _        d S )Nbrace-groupr  r  s      r   r   zBraceGroup.__init__  s    !		"r   r   r	   c                j    d| j                                         z   dz   }t          || j                  S )Nz(brace-group r   r  r  s     r   r  zBraceGroup.to_sexp  s1    !2!2!4!44s: t~666r   r   r  r   r  r"   r   r   r  r    sc         ""JJJ15I5555# # # # #
7 7 7 7 7 7r   r  c                  V    e Zd ZU dZded<   ded<   dZded<   ded	<   	 	 dddZddZdS )IfzAn if statement.r  r  	then_bodyNNode | None	else_bodyrq   r  r   c                T    d| _         || _        || _        || _        |g }|| _        d S )Nrb  )r.  r  r  r  r  )r   r  r  r  r  s        r   r   zIf.__init__  s6     	"""I"r   r   r	   c                   d| j                                         z   dz   | j                                        z   }| j        r|dz   | j                                        z   }|dz   }| j        D ]}|dz   |                                z   }|S )Nz(if rM   r   )r  r  r  r  r  )r   ry   rA   s      r   r  z
If.to_sexp  s    $.00222S84>;Q;Q;S;SS> 	=c\DN$:$:$<$<<F# 	0 	0Ac\AIIKK/FFr   r   )r  r  r  r  r  r  r  r   r   )r   r   r   r   r  r  r   r  r"   r   r   r  r    s         OOOOOO!I!!!! "&'+# # # # #     r   r  c                  D    e Zd ZU dZded<   ded<   ded<   ddd	ZddZdS )WhilezA while loop.r  r  r  rq   r  Nr   c                F    d| _         || _        || _        |g }|| _        d S )Nrj  r.  r  r  r  r   r  r  r  s       r   r   zWhile.__init__  -    	"	I"r   r   r	   c                    d| j                                         z   dz   | j                                        z   dz   }t          || j                  S )Nz(while rM   r   r  r  r  r  r  r  s     r   r  zWhile.to_sexp  J    4>11333c9DI<M<M<O<OORUU t~666r   r   r  r  r  r  r  r   r   rP  r"   r   r   r  r    sg         OOOJJJ# # # # #7 7 7 7 7 7r   r  c                  D    e Zd ZU dZded<   ded<   ded<   ddd	ZddZdS )UntilzAn until loop.r  r  r  rq   r  Nr   c                F    d| _         || _        || _        |g }|| _        d S )Nrk  r  r  s       r   r   zUntil.__init__  r  r   r   r	   c                    d| j                                         z   dz   | j                                        z   dz   }t          || j                  S )Nz(until rM   r   r  r  s     r   r  zUntil.to_sexp  r  r   r   r  r   rP  r"   r   r   r  r    sg         OOOJJJ# # # # #7 7 7 7 7 7r   r  c                  P    e Zd ZU dZded<   ded<   ded<   ded	<   	 dddZddZd
S )ForzA for loop.r	   varlist[Word] | NonerK  r  r  rq   r  Nr   c                T    d| _         || _        || _        || _        |g }|| _        d S )Nri  r.  r  rK  r  r  r   r  rK  r  r  s        r   r   zFor.__init__   s6     	
	I"r   r   c                &   d}| j         rKg }| j         D ])}|                    |                                           *dd                    |          z   }t	          | j        g           }|                    | j                  }|                    dd                              dd          }| j        (d|z   dz   | j	                                        z   d	z   |z   S t          | j                  d
k    r(d|z   dz   | j	                                        z   d	z   |z   S g }| j        D ])}|                    |                                           *d                    |          }	d|z   dz   |	z   dz   | j	                                        z   d	z   |z   S )Nru   rM   rD   r  rE   r  z(for (word "z") (in (word "\"$@\"")) r   r   z") (in) z") (in ) )r  rw   r  rx   r  r  r  r  rK  r  r   )
r   rU  redirect_partsrA   	temp_wordvar_formattedvar_escaped
word_partsrO  	word_strss
             r   r  zFor.to_sexp+  s   > 	4N^ 3 3%%aiikk2222388N333F2&&	!??II#++D&99AA#uMM: ./ )##%%& 	
  __!!!K/*<ty?P?P?R?RRUXX[aaaJZ / /!!!))++....,,I  	
 )##%%&  	r   r   r  r	   rK  r  r  r  r  r   r   rP  r"   r   r   r  r    sz         HHHJJJ ^b	# 	# 	# 	# 	#' ' ' ' ' 'r   r  c                L   t          | g           }|                    |           }|                    |          }|                    |          }|                    dd                              dd          }|                    dd                              dd          }|S )	z(Format arithmetic value for sexp output.rD   r  rE   r  rO   r  rN   r  )r  r  r  r  r  )rQ   rO  vals      r   _format_arith_valr  U  s    QA

%
%a
(
(C

(
(
-
-C

)
)#
.
.C
++dF
#
#
+
+C
7
7C
++dE
"
"
*
*4
7
7CJr   c                  Z    e Zd ZU dZded<   ded<   ded<   ded<   ded	<   	 dddZddZd
S )ForArithz:A C-style for loop: for ((init; cond; incr)); do ... done.r	   initcondincrr  r  rq   r  Nr   c                b    d| _         || _        || _        || _        || _        |g }|| _        d S )N	for-arith)r.  r  r  r  r  r  )r   r  r  r  r  r  s         r   r   zForArith.__init__i  s=      					I"r   r   c           
        d}| j         rKg }| j         D ])}|                    |                                           *dd                    |          z   }| j        r| j        nd}| j        r| j        nd}| j        r| j        nd}t          |          }t          |          }t          |          }	| j                                        }
d| d| d|	 d|
 d| 
S )	Nru   rM   r  z(arith-for (init (word "z")) (test (word "z")) (step (word "z")) r   )	r  rw   r  rx   r  r  r  r  r  )r   rU  r  rA   init_valcond_valincr_valinit_strcond_strincr_strbody_strs              r   r  zForArith.to_sexpu  s!   > 	4N^ 3 3%%aiikk2222388N333F $	2499s $	2499s $	2499s$X..$X..$X..9$$&& B(  B  BX  B  B`h  B  Bnv  B  By  B  B  	Br   r   )
r  r	   r  r	   r  r	   r  r  r  r   r   rP  r"   r   r   r  r  `  s         DDIIIIIIIIIJJJ [_
# 
# 
# 
# 
#B B B B B Br   r  c                  P    e Zd ZU dZded<   ded<   ded<   ded	<   	 dddZddZd
S )SelectzA select statement.r	   r  r  rK  r  r  rq   r  Nr   c                T    d| _         || _        || _        || _        |g }|| _        d S )Nrp  r  r  s        r   r   zSelect.__init__  s6     	
	I"r   r   c                ,   d}| j         rKg }| j         D ])}|                    |                                           *dd                    |          z   }| j                            dd                              dd          }| j        [g }| j        D ])}|                    |                                           *d                    |          }| j        r	d|z   dz   }nd	}nd
}d|z   dz   |z   dz   | j                                        z   dz   |z   S )Nru   rM   rD   r  rE   r  z(in r   z(in)z(in (word "\"$@\""))z(select (word "z") )r  rw   r  rx   r  r  rK  r  )	r   rU  r  rA   r  r  rO  r  	in_clauses	            r   r  zSelect.to_sexp  sR   > 	4N^ 3 3%%aiikk2222388N333Fh&&tV44<<S%HH:!JZ / /!!!))++....,,Iz #"Y.4		"		 1I  	
 i!!"  		
r   r   r  r   rP  r"   r   r   r  r    sz         HHHJJJ ^b	# 	# 	# 	# 	#
 
 
 
 
 
r   r  c                  F    e Zd ZU dZded<   ded<   ded<   	 ddd
ZddZdS )CasezA case statement.r  r   list[CasePattern]patternsrq   r  Nr   c                F    d| _         || _        || _        |g }|| _        d S )Nrg  )r.  r   r  r  )r   r   r  r  s       r   r   zCase.__init__  s/     		 I"r   r   r	   c                    g }|                     d| j                                        z              | j        D ])}|                     |                                           *d                    |          dz   }t          || j                  S )Nz(case rM   r   )rw   r   r  r  rx   r  r  )r   r   r  r  s       r   r  zCase.to_sexp  s    X	 1 1 3 33444 	& 	&ALL%%%%xx$ t~666r   r   )r   r  r  r  r  r   r   rP  r"   r   r   r  r    sq         JJJ W[# # # # #7 7 7 7 7 7r   r  tuple[int, list[str]]c                <   dg}|dz   }|t          |           k     rK| |         dk    r?|                    | |                    |dz  }|t          |           k     r| |         dk    ?|t          |           k     r |                    | |                    |dz  }||fS )z:Consume '...' from start. Returns (end_index, chars_list).r  re   r   rw   rQ   r\   r  rz   s       r   _consume_single_quoter
    s    EE	A
c!ff**1QqT	Q c!ff**1 	3q66zzQqT	Qu:r   c                   dg}|dz   }|t          |           k     r| |         dk    r| |         dk    r6|dz   t          |           k     r |                    | |                    |dz  }|                    | |                    |dz  }|t          |           k     r| |         dk    |t          |           k     r |                    | |                    |dz  }||fS )zLConsume "..." from start, handling escapes. Returns (end_index, chars_list).rE   re   rD   r  r	  s       r   _consume_double_quoter    s    EE	A
c!ff**1Q44<<AECFFNNLL1FAQqT	Q c!ff**1 	3q66zzQqT	Qu:r   r3  c                    |}|t          |           k     rF| |         dk    rdS | |         dk    s| |         dk    r|dk    rdS |dz  }|t          |           k     FdS )z.Check if there's a ] before | or ) at depth 0.r  Tr  r   r   Fre   r   )rQ   r\   r3  rz   s       r   _has_bracket_closer    so    A
c!ff**Q43;;4aDCKK1Q43;;EQJJ5	Q c!ff** 5r   tuple[int, list[str], bool]c                .   |dz   }|t          |           k     r| |         dk    s| |         dk    r|dz  }|t          |           k     r%| |         dk    rt          | |dz   |          r|dz  }d}|t          |           k     rM| |         dk    rd}n>| |         dk    r|dk    rn+| |         d	k    r|dk    rn|dz  }|t          |           k     M|s	|dz   d
gdfS d
g}|dz   }|t          |           k     r8| |         dk    s| |         dk    r |                    | |                    |dz  }|t          |           k     r@| |         dk    r4t          | |dz   |          r |                    | |                    |dz  }|t          |           k     rK| |         dk    r?|                    | |                    |dz  }|t          |           k     r| |         dk    ?|t          |           k     r |                    | |                    |dz  }||dfS )zOConsume [...] bracket expression. Returns (end_index, chars_list, was_bracket).re   rE  r  r  FTr   r   r  r  )r   r  rw   )rQ   r\   r3  scan_pos
is_bracketr  rz   s          r   _consume_bracket_classr    sY    qyH#a&&akS00AhK34F4FA#a&&Qx[C//aAu55 	MHJ
SVV

X;#JX;#%1**X;#%1**A SVV

  )	C5%((EE	A3q66zzqts{{adckkQqT	Q3q66zzadckkaQ.. 	LL1FA
c!ff**1QqT	Q c!ff**1 	3q66zzQqT	Qudr   c                  H    e Zd ZU dZded<   ded<   dZded<   dddZdd
ZdS )CasePatternz%A pattern clause in a case statement.r	   patternr  r  r  r;  c                >    d| _         || _        || _        || _        d S )Nr  )r.  r  r  r;  )r   r  r  r;  s       r   r   zCasePattern.__init__3  s"    		$r   r   c                   g }g }d}d}|t          | j                  k     r| j        |         }|dk    rN|dz   t          | j                  k     r3|                    t          | j        ||dz                        |dz  }nI|dk    s|dk    s|dk    s|dk    s|d	k    re|dz   t          | j                  k     rJ| j        |dz            d
k    r6|                    |           |                    d
           |dz  }|dz  }nt	          | j        |d          r6|                    |           |                    d
           |dz  }|dz  }nz|d
k    r'|dk    r!|                    |           |dz  }|dz  }nM|dk    r'|dk    r!|                    |           |dz  }|dz  }n |dk    r:t          | j        ||          }|d         }|                    |d                    n|dk    r?|dk    r9t          | j        |          }|d         }|                    |d                    n|dk    r?|dk    r9t          | j        |          }|d         }|                    |d                    nV|dk    r6|dk    r0|                    d	                    |                     g }|dz  }n|                    |           |dz  }|t          | j                  k     |                    d	                    |                     g }|D ]6}|                    t          |                                                     7d	                    |          }	d|	z   dz   g}
| j        r0|
                    d| j                                        z              n|
                    d           |
                    d           d	                    |
          S )Nr   rD   re   rg   r.  rF   *r  rE  r  r  r   r  r  rE   r  ru   rM   z
(pattern (z ())r   r  rw   r_   ro   r  r  r
  r  rx   r  r  r  )r   alternativescurrentrz   r3  r  ry   	word_listaltpattern_strr   s              r   r  zCasePattern.to_sexp9  s    #dl####aBTzza!ec$,&7&777z$,1q5AABBBQsbCii299c		R3YYEC----LQ'3.. r"""s###
Q$T\1d;;  r"""s###
Qsuqyyr"""
Qsuqyyr"""
Qs/aGG1Ivay))))suzz.t|Q??1Ivay))))suzz.t|Q??1Ivay))))suzz##BGGG$4$4555Qr"""Q_ #dl####` 	BGGG,,---	 	2 	2CT#YY..001111hhy))+c129 	 LLty002223333LLSwwu~~r   N)r  )r  r	   r  r  r;  r	   r   )r   r   r   r   r  r;  r   r  r"   r   r   r  r  ,  su         //LLLJ% % % % %D D D D D Dr   r  c                  8    e Zd ZU dZded<   ded<   d
dZddZd	S )FunctionzA function definition.r	   rA  r  r  c                0    d| _         || _        || _        d S )Nro  )r.  rA  r  )r   rA  r  s      r   r   zFunction.__init__  s    					r   r   c                V    d| j         z   dz   | j                                        z   dz   S )Nz(function "r  r   )rA  r  r  r   s    r   r  zFunction.to_sexp  s,    ty(4/$)2C2C2E2EEKKr   N)rA  r	   r  r  r   rP  r"   r   r   r!  r!    s\           IIIJJJ   
L L L L L Lr   r!  c                  L    e Zd ZU dZded<   dZded<   dZded<   dddZdd
ZdS )r?  z0A parameter expansion ${var} or ${var:-default}.r	   rT  Nr  r  rW  c                >    d| _         || _        || _        || _        d S )NrT  r.  rT  r  rW  r   rT  r  rW  s       r   r   zParamExpansion.__init__  s"    	
r   r   c                z   | j                             dd                              dd          }| j        ~| j                            dd                              dd          }| j        | j        }nd}|                    dd                              dd          }d|z   dz   |z   dz   |z   dz   S d|z   dz   S )	NrD   r  rE   r  ru   z(param "r  r  rT  r  r  rW  )r   escaped_param
escaped_oparg_valescaped_args        r   r  zParamExpansion.to_sexp  s    
**488@@eLL7v66>>sEJJJx#(!//$77??UKKK-5
BUJ[X[___M)D00r   r   rT  r	   r  r  rW  r  r   )	r   r   r   r   r  r  rW  r   r  r"   r   r   r?  r?    st         ::JJJBC    
1 
1 
1 
1 
1 
1r   r?  c                  .    e Zd ZU dZded<   ddZd	dZdS )
rJ  z%A parameter length expansion ${#var}.r	   rT  c                "    d| _         || _        d S )Nz	param-len)r.  rT  )r   rT  s     r   r   zParamLength.__init__  s    	


r   r   c                p    | j                             dd                              dd          }d|z   dz   S )NrD   r  rE   r  z(param-len "r  )rT  r  r   r  s     r   r  zParamLength.to_sexp  s9    *$$T622::3FF'$..r   N)rT  r	   r   rP  r"   r   r   rJ  rJ    sM         //JJJ   / / / / / /r   rJ  c                  D    e Zd ZU dZded<   ded<   ded<   dddZdd
ZdS )rK  z<An indirect parameter expansion ${!var} or ${!var<op><arg>}.r	   rT  r  r  rW  Nc                >    d| _         || _        || _        || _        d S )Nzparam-indirectr&  r'  s       r   r   zParamIndirect.__init__  s"    $	
r   r   c                z   | j                             dd                              dd          }| j        ~| j                            dd                              dd          }| j        | j        }nd}|                    dd                              dd          }d|z   dz   |z   dz   |z   dz   S d|z   dz   S )	NrD   r  rE   r  ru   z(param-indirect "r  r  r)  )r   r  r+  r,  r-  s        r   r  zParamIndirect.to_sexp  s    *$$T622::3FF7v66>>sEJJJx#(!//$77??UKKK&058:EMP[[^bbb"W,t33r   r   r.  r   rP  r"   r   r   rK  rK    sd         FFJJJNNNOOO    
4 
4 
4 
4 
4 
4r   rK  c                  :    e Zd ZU dZded<   ded<   dddZdd
ZdS )r  z3A command substitution $(...), `...`, or ${ cmd; }.r  r  r$   r  Fc                0    d| _         || _        || _        d S )Nr  )r.  r  r  )r   r  r  s      r   r   zCommandSubstitution.__init__  s    	


r   r   r	   c                    | j         rd| j                                        z   dz   S d| j                                        z   dz   S )Nz(funsub r   z(cmdsub )r  r  r  r   s    r   r  zCommandSubstitution.to_sexp  sH    : 	= 4 4 6 66<<DL00222S88r   Nrv  )r  r  r  r$   r   rP  r"   r   r   r  r    s[         ==MMMKKK    
9 9 9 9 9 9r   r  c                  .    e Zd ZU dZded<   d	dZd
dZdS )r  z7An arithmetic expansion $((...)) with parsed internals.ArithNode | Noner  c                "    d| _         || _        d S )Nr
  r.  r  r   r  s     r   r   zArithmeticExpansion.__init__  s    	$r   r   r	   c                R    | j         dS d| j                                         z   dz   S )Nz(arith)z(arith r   )r  r  r   s    r   r  zArithmeticExpansion.to_sexp  s-    ?"94?22444s::r   N)r  r:  r   rP  r"   r   r   r  r    sP         AA    % % % %; ; ; ; ; ;r   r  c                  H    e Zd ZU dZded<   ded<   ded<   	 	 dddZddZdS )ArithmeticCommandz4An arithmetic command ((...)) with parsed internals.r:  r  list[Redirect | HereDoc]r  r	   r3  Nru   r  c                F    d| _         || _        |g }|| _        || _        d S )N	arith-cmd)r.  r  r  r3  )r   r  r  r3  s       r   r   zArithmeticCommand.__init__  s2      	$I"&r   r   c                   t          | j                                      | j        d          }|                    dd                              dd                              dd                              d	d
          }d|z   dz   }| j        rPg }| j        D ])}|                    |                                           *d                    |          }|dz   |z   S |S )NT)r  rD   r  rE   r  rO   r  rN   r  z(arith (word ""))rM   )r  r3  r  r  r  rw   r  rx   )r   r_  r  ry   r  rA   redirect_sexpss          r   r  zArithmeticCommand.to_sexp  s     )**HHt I 
 
	 dF++WS%  WT5!!WT5!!	 	 "G+e3> 	1N^ 3 3%%aiikk2222 XXn55NC<.00r   r  )r  r:  r  r  r3  r	   r   rP  r"   r   r   r@  r@    su         >>    ''''
 6:	' ' ' ' '     r   r@  c                  .    e Zd ZU dZded<   ddZd	dZdS )
ArithNumberz(A numeric literal in arithmetic context.r	   r   c                "    d| _         || _        d S )Nnumber)r.  r   rE  s     r   r   zArithNumber.__init__$  s    	


r   r   c                    d| j         z   dz   S )Nz	(number "r  )r   r   s    r   r  zArithNumber.to_sexp(  s    TZ'$..r   N)r   r	   r   rP  r"   r   r   rH  rH    sM         22JJJ   / / / / / /r   rH  c                       e Zd ZdZd ZddZdS )
ArithEmptyzEA missing operand in arithmetic context (e.g., in $((|)) or $((1|))).c                    d| _         d S r  r  r   s    r   r   zArithEmpty.__init__/  r  r   r   r	   c                    dS )Nz(empty)r"   r   s    r   r  zArithEmpty.to_sexp2  s    yr   Nr   r  r"   r   r   rM  rM  ,  s=        OO       r   rM  c                  .    e Zd ZU dZded<   ddZd	dZdS )
ArithVarz7A variable reference in arithmetic context (without $).r	   rA  c                "    d| _         || _        d S )Nr  )r.  rA  r   rA  s     r   r   zArithVar.__init__;  s    				r   r   c                    d| j         z   dz   S )Nz(var "r  )rA  r   s    r   r  zArithVar.to_sexp?  s    $)#d**r   N)rA  r	   r   rP  r"   r   r   rQ  rQ  6  sM         AAIII   + + + + + +r   rQ  c                  B    e Zd ZU dZded<   ded<   ded<   ddZdd	Zd
S )r  z!A binary operation in arithmetic.r	   r  	ArithNoder  r  c                >    d| _         || _        || _        || _        d S )Nz	binary-opr.  r  r  r  r   r  r  r  s       r   r   zArithBinaryOp.__init__J  s"    		


r   r   c                    d| j         z   dz   | j                                        z   dz   | j                                        z   dz   S )Nz(binary-op "r  rM   r   )r  r  r  r  r   s    r   r  zArithBinaryOp.to_sexpP  sG    TW$t+di.?.?.A.AACG$*J\J\J^J^^add	
r   N)r  r	   r  rV  r  rV  r   rP  r"   r   r   r  r  C  sb         ++GGGOOO   
 
 
 
 
 
r   r  c                  8    e Zd ZU dZded<   ded<   d
dZddZd	S )r  z A unary operation in arithmetic.r	   r  rV  r  c                0    d| _         || _        || _        d S )Nzunary-opr.  r  r  r   r  r  s      r   r   zArithUnaryOp.__init__\  s    	r   r   c                V    d| j         z   dz   | j                                        z   dz   S )Nz(unary-op "r  r   )r  r  r  r   s    r   r  zArithUnaryOp.to_sexpa  s,    tw&-0D0D0F0FFLLr   N)r  r	   r  rV  r   rP  r"   r   r   r  r  V  s_         **GGG   
M M M M M Mr   r  c                  .    e Zd ZU dZded<   d	dZd
dZdS )r  zPre-increment ++var.rV  r  c                "    d| _         || _        d S )Nzpre-incrr.  r  r   r  s     r   r   zArithPreIncr.__init__j      	r   r   r	   c                @    d| j                                         z   dz   S )Nz
(pre-incr r   r  r  r   s    r   r  zArithPreIncr.to_sexpn       dl22444s::r   Nr  rV  r   rP  r"   r   r   r  r  e  P            ; ; ; ; ; ;r   r  c                  .    e Zd ZU dZded<   d	dZd
dZdS )r  zPost-increment var++.rV  r  c                "    d| _         || _        d S )Nz	post-incrrb  rc  s     r   r   zArithPostIncr.__init__w      	r   r   r	   c                @    d| j                                         z   dz   S )Nz(post-incr r   rf  r   s    r   r  zArithPostIncr.to_sexp{       t|33555;;r   Nrh  r   rP  r"   r   r   r  r  r  P            < < < < < <r   r  c                  .    e Zd ZU dZded<   d	dZd
dZdS )r  zPre-decrement --var.rV  r  c                "    d| _         || _        d S )Nzpre-decrrb  rc  s     r   r   zArithPreDecr.__init__  rd  r   r   r	   c                @    d| j                                         z   dz   S )Nz
(pre-decr r   rf  r   s    r   r  zArithPreDecr.to_sexp  rg  r   Nrh  r   rP  r"   r   r   r  r    ri  r   r  c                  .    e Zd ZU dZded<   d	dZd
dZdS )r  zPost-decrement var--.rV  r  c                "    d| _         || _        d S )Nz	post-decrrb  rc  s     r   r   zArithPostDecr.__init__  rl  r   r   r	   c                @    d| j                                         z   dz   S )Nz(post-decr r   rf  r   s    r   r  zArithPostDecr.to_sexp  rn  r   Nrh  r   rP  r"   r   r   r  r    ro  r   r  c                  B    e Zd ZU dZded<   ded<   ded<   ddZdd	Zd
S )r  z'Assignment operation (=, +=, -=, etc.).r	   r  rV  r  r   c                >    d| _         || _        || _        || _        d S )Nassign)r.  r  r  r   )r   r  r  r   s       r   r   zArithAssign.__init__  s"    	


r   r   c                    d| j         z   dz   | j                                        z   dz   | j                                        z   dz   S )Nz	(assign "r  rM   r   )r  r  r  r   r   s    r   r  zArithAssign.to_sexp  sG    $'!D(4;+>+>+@+@@3FI[I[I]I]]`cc	
r   N)r  r	   r  rV  r   rV  r   rP  r"   r   r   r  r    se         11GGG   
 
 
 
 
 
r   r  c                  B    e Zd ZU dZded<   ded<   ded<   ddZdd	Zd
S )r  z'Ternary conditional expr ? expr : expr.rV  r  r  r  c                >    d| _         || _        || _        || _        d S )Nternary)r.  r  r  r  )r   r  r  r  s       r   r   zArithTernary.__init__  s"    	" r   r   r	   c                    d| j                                         z   dz   | j                                        z   dz   | j                                        z   dz   S )Nz	(ternary rM   r   )r  r  r  r  r   s    r   r  zArithTernary.to_sexp  sl    n$$&&' l""$$% 	
 m##%%& 	
r   N)r  rV  r  rV  r  rV  r   rP  r"   r   r   r  r    sh         11! ! ! !	
 	
 	
 	
 	
 	
r   r  c                  8    e Zd ZU dZded<   ded<   d
dZddZd	S )r  zComma operator expr, expr.rV  r  r  c                0    d| _         || _        || _        d S )Ncommar.  r  r  r   r  r  s      r   r   zArithComma.__init__  s    		


r   r   r	   c                z    d| j                                         z   dz   | j                                        z   dz   S )Nz(comma rM   r   r  r  r  r   s    r   r  zArithComma.to_sexp  s8    49,,...4tz7I7I7K7KKcQQr   N)r  rV  r  rV  r   rP  r"   r   r   r  r    s_         $$OOO   
R R R R R Rr   r  c                  8    e Zd ZU dZded<   ded<   d
dZddZd	S )ArithSubscriptzArray subscript arr[expr].r	   arrayrV  indexc                0    d| _         || _        || _        d S )N	subscript)r.  r  r  )r   r  r  s      r   r   zArithSubscript.__init__  s    	



r   r   c                V    d| j         z   dz   | j                                        z   dz   S )Nz(subscript "r  r   )r  r  r  r   s    r   r  zArithSubscript.to_sexp  s,    
*T1DJ4F4F4H4HH3NNr   N)r  r	   r  rV  r   rP  r"   r   r   r  r    s_         $$JJJ   
O O O O O Or   r  c                  .    e Zd ZU dZded<   ddZd	dZdS )
ArithEscapez.An escaped character in arithmetic expression.r	   charc                "    d| _         || _        d S )Nescape)r.  r  )r   r  s     r   r   zArithEscape.__init__  s    				r   r   c                    d| j         z   dz   S )Nz	(escape "r  )r  r   s    r   r  zArithEscape.to_sexp  s    TY&--r   N)r  r	   r   rP  r"   r   r   r  r    sM         88III   . . . . . .r   r  c                  .    e Zd ZU dZded<   ddZd	dZdS )
ArithDeprecatedz*A deprecated arithmetic expansion $[expr].r	   r  c                "    d| _         || _        d S )Nzarith-deprecatedr<  r=  s     r   r   zArithDeprecated.__init__  s    &	$r   r   c                    | j                             dd                              dd                              dd          }d|z   dz   S )	NrD   r  rE   r  rO   r  z(arith-deprecated "r  )r  r  r2  s     r   r  zArithDeprecated.to_sexp  sK    /))$77??UKKSSTXZ_``$w.55r   N)r  r	   r   rP  r"   r   r   r  r    sM         44OOO% % % %6 6 6 6 6 6r   r  c                  .    e Zd ZU dZded<   d	dZd
dZdS )ArithConcatzCA concatenation of prefix + expansion in arithmetic (e.g., 0x$var).list[ArithNode]r   c                "    d| _         || _        d S )Nzarith-concatrf  rg  s     r   r   zArithConcat.__init__  s    "	


r   r   r	   c                    g }| j         D ])}|                    |                                           *dd                    |          z   dz   S )Nz(arith-concat rM   r   )r   rw   r  rx   )r   sexpsr  s      r   r  zArithConcat.to_sexp  sO     	& 	&ALL%%%%#((5//1C77r   N)r   r  r   rP  r"   r   r   r  r    sP         MM   8 8 8 8 8 8r   r  c                  .    e Zd ZU dZded<   ddZd	dZdS )
r  zAn ANSI-C quoted string $'...'.r	   r  c                "    d| _         || _        d S )Nzansi-cr.  r  r   r  s     r   r   zAnsiCQuote.__init__      	r   r   c                    | j                             dd                              dd                              dd          }d|z   dz   S )	NrD   r  rE   r  rO   r  z	(ansi-c "r  r  r  r2  s     r   r  zAnsiCQuote.to_sexp  K    ,&&tV44<<S%HHPPQUW\]]W$t++r   Nr  r	   r   rP  r"   r   r   r  r    sM         ))LLL   , , , , , ,r   r  c                  .    e Zd ZU dZded<   ddZd	dZdS )
r  z"A locale-translated string $"...".r	   r  c                "    d| _         || _        d S )Nlocaler  r  s     r   r   zLocaleString.__init__!  r  r   r   c                    | j                             dd                              dd                              dd          }d|z   dz   S )	NrD   r  rE   r  rO   r  z	(locale "r  r  r2  s     r   r  zLocaleString.to_sexp%  r  r   Nr  r   rP  r"   r   r   r  r    sM         ,,LLL   , , , , , ,r   r  c                  8    e Zd ZU dZded<   ded<   d
dZddZd	S )r  z(A process substitution <(...) or >(...).r	   r  r  r  c                0    d| _         || _        || _        d S )Nr	  )r.  r  r  )r   r  r  s      r   r   zProcessSubstitution.__init__0  s    	"r   r   c                V    d| j         z   dz   | j                                        z   dz   S )Nz
(procsub "r  r   )r  r  r  r   s    r   r  zProcessSubstitution.to_sexp5  s,    dn,t3dl6J6J6L6LLsRRr   N)r  r	   r  r  r   rP  r"   r   r   r  r  *  s\         22NNNMMM   
S S S S S Sr   r  c                  .    e Zd ZU dZded<   d	dZd
dZdS )NegationzPipeline negation with !.r  rU  c                "    d| _         || _        d S )Nnegation)r.  rU  )r   rU  s     r   r   zNegation.__init__>  rV  r   r   r	   c                R    | j         dS d| j                                         z   dz   S )Nz(negation (command))z
(negation r   )rU  r  r   s    r   r  zNegation.to_sexpB  s.    = ))dm33555;;r   N)rU  r  r   rP  r"   r   r   r  r  9  sM         ##NNN! ! ! !< < < < < <r   r  c                  >    e Zd ZU dZded<   dZded<   dddZdd
ZdS )Timez#Time measurement with time keyword.r  rU  Fr$   posixc                0    d| _         || _        || _        d S )Nrr  )r.  rU  r  )r   rU  r  s      r   r   zTime.__init__O  s    	 


r   r   r	   c                    | j         | j        rdS dS | j        rd| j                                         z   dz   S d| j                                         z   dz   S )Nz(time -p (command))z(time (command))z	(time -p r   z(time )rU  r  r  r   s    r   r  zTime.to_sexpT  sf    = z *,,)): 	?!6!6!8!883>>$-//111C77r   Nrv  )rU  r  r  r$   r   )r   r   r   r   r  r  r   r  r"   r   r   r  r  I  sc         --NNNE    
	8 	8 	8 	8 	8 	8r   r  c                  :    e Zd ZU dZded<   ded<   dddZddZdS )ConditionalExprz*A conditional expression [[ expression ]].CondNode | strr  rA  r  Nr  c                8    d| _         || _        |g }|| _        d S )N	cond-exprr  r  s      r   r   zConditionalExpr.__init__f  s&    		I"r   r   r	   c                   | j         }t          |t                    rG|                    dd                              dd                              dd          }d|z   dz   }nd	|                                z   d
z   }| j        rPg }| j        D ])}|                    |                                           *d                    |          }|dz   |z   S |S )NrD   r  rE   r  rO   r  z(cond "r  z(cond r   rM   )r  r  r	   r  r  r  rw   rx   )r   r  r  ry   r  rA   rF  s          r   r  zConditionalExpr.to_sexpm  s     ydC   	5ll40088eDDLLTSXYYG(4/FF.4F> 	1N^ 3 3%%aiikk2222 XXn55NC<.00r   r   )r  r  r  r  r   rP  r"   r   r   r  r  `  sa         44''''# # # # #     r   r  c                  8    e Zd ZU dZded<   ded<   d
dZddZd	S )	UnaryTestz0A unary test in [[ ]], e.g., -f file, -z string.r	   r  r  r  c                0    d| _         || _        || _        d S )N
unary-testr]  r^  s      r   r   zUnaryTest.__init__  s     	r   r   c                Z    | j                                         }d| j        z   dz   |z   dz   S )Nz(cond-unary "" (cond-term "rE  )r  rF  r  )r   operand_vals     r   r  zUnaryTest.to_sexp  s4     l;;==(+;;kIEQQr   N)r  r	   r  r  r   rP  r"   r   r   r  r    s\         ::GGGMMM   
R R R R R Rr   r  c                  B    e Zd ZU dZded<   ded<   ded<   ddZdd	Zd
S )
BinaryTestz8A binary test in [[ ]], e.g., $a == $b, file1 -nt file2.r	   r  r  r  r  c                >    d| _         || _        || _        || _        d S )Nbinary-testrX  rY  s       r   r   zBinaryTest.__init__  s"    !		


r   r   c                    | j                                         }| j                                        }d| j        z   dz   |z   dz   |z   dz   S )Nz(cond-binary "r  z") (cond-term "rE  )r  rF  r  r  )r   left_val	right_vals      r   r  zBinaryTest.to_sexp  sl     95577J7799	g   	 
  	
r   N)r  r	   r  r  r  r  r   rP  r"   r   r   r  r    s_         BBGGGJJJKKK   
 
 
 
 
 
r   r  c                  8    e Zd ZU dZded<   ded<   d
dZddZd	S )CondAndz+Logical AND in [[ ]], e.g., expr1 && expr2.CondNoder  r  c                0    d| _         || _        || _        d S )Ncond-andr  r  s      r   r   zCondAnd.__init__  s    		


r   r   r	   c                z    d| j                                         z   dz   | j                                        z   dz   S )Nz
(cond-and rM   r   r  r   s    r   r  zCondAnd.to_sexp  s9    di//111C7$*:L:L:N:NNQTTTr   Nr  r  r  r  r   rP  r"   r   r   r  r    s\         55NNNOOO   
U U U U U Ur   r  c                  8    e Zd ZU dZded<   ded<   d
dZddZd	S )CondOrz*Logical OR in [[ ]], e.g., expr1 || expr2.r  r  r  c                0    d| _         || _        || _        d S )Ncond-orr  r  s      r   r   zCondOr.__init__  s    		


r   r   r	   c                z    d| j                                         z   dz   | j                                        z   dz   S )Nz	(cond-or rM   r   r  r   s    r   r  zCondOr.to_sexp  s9    TY..000369K9K9M9MMPSSSr   Nr  r   rP  r"   r   r   r  r    s\         44NNNOOO   
T T T T T Tr   r  c                  .    e Zd ZU dZded<   d	dZd
dZdS )CondNotz#Logical NOT in [[ ]], e.g., ! expr.r  r  c                "    d| _         || _        d S )Ncond-notrb  rc  s     r   r   zCondNot.__init__  rd  r   r   r	   c                4    | j                                         S r   rf  r   s    r   r  zCondNot.to_sexp  s    |##%%%r   N)r  r  r   rP  r"   r   r   r  r    sP         --   & & & & & &r   r  c                  .    e Zd ZU dZded<   d	dZd
dZdS )	CondParenz-Parenthesized group in [[ ]], e.g., ( expr ).r  r\  c                "    d| _         || _        d S )N
cond-paren)r.  r\  )r   r\  s     r   r   zCondParen.__init__  s     	


r   r   r	   c                @    d| j                                         z   dz   S )Nz(cond-expr r   )r\  r  r   s    r   r  zCondParen.to_sexp  s     tz11333c99r   N)r\  r  r   rP  r"   r   r   r  r    sM         77OOO   : : : : : :r   r  c                  .    e Zd ZU dZded<   d	dZd
dZdS )r  z#An array literal (word1 word2 ...).rJ  r  c                "    d| _         || _        d S )Nr  )r.  r  )r   r  s     r   r   zArray.__init__  s    	 r   r   r	   c                    | j         sdS g }| j         D ])}|                    |                                           *d                    |          }d|z   dz   S )Nz(array)rM   z(array r   )r  rw   r  rx   )r   r   r>   r\  s       r   r  zArray.to_sexp  sc    } 	9 	& 	&ALL%%%%5 3&&r   N)r  rJ  r   rP  r"   r   r   r  r    sP         --! ! ! !' ' ' ' ' 'r   r  c                  >    e Zd ZU dZded<   dZded<   dddZdd
ZdS )Coprocz"A coprocess coproc [NAME] command.r  r  Nr  rA  c                0    d| _         || _        || _        d S )Nrq  )r.  r  rA  )r   r  rA  s      r   r   zCoproc.__init__  s    				r   r   r	   c                n    | j         r| j         }nd}d|z   dz   | j                                        z   dz   S )Nr   z	(coproc "r  r   )rA  r  r  rS  s     r   r  zCoproc.to_sexp  sB    9 	9DDDT!D(4<+?+?+A+AACGGr   r   )r  r  rA  r  r   )r   r   r   r   r  rA  r   r  r"   r   r   r  r    si         ,,MMMD    
H H H H H Hr   r  r  c                D   | j         }|dk    r&| j                                        }| j        dz   |z   S |dk    rE| j                                        }| j                                        }|dz   | j        z   dz   |z   S |dk    r,t          | j                  dz   t          | j                  z   S |dk    r,t          | j                  dz   t          | j                  z   S |dk    rd	t          | j                  z   S |d
k    rdt          | j                  z   dz   S dS )z2Format the body of a [[ ]] conditional expression.r  rM   r  r  z && r  z || r  ! r  (  )ru   )r.  r  rF  r  r  r  _format_cond_bodyr\  )r  r.  r  r  r  s        r   r  r  %  s0   9D|l;;==w}{**}95577J7799	#~'#-	99z ++f47H7T7TTTy ++f47H7T7TTTz'5555|'
333d::2r   c                    | j         dk    rdS | j         dk    r(| j        D ]}|j         dk    rt          |          c S dS | j         dk    r#| j        rt          | j        d                   S dS dS )zTCheck if a node starts with a subshell (for compact redirect formatting in procsub).r  TrU   rm  FrU  r   )r.  r   r  rS  )r  r  s     r   r  r  :  s    yJtyF 	0 	0Av##,Q///// $uyJ= 	;(q)9:::u5r   Findentr  compact_redirectsprocsub_firstc           	     L    | dS t          d|          }t          d|dz             }| j        dk    rdS | j        dk    rwg }| j        D ]p}|                    |j                  }	|                    |	          }	|                    |	          }	|                    |	          }	|                    |	           qg }
| j	        D ]"}|j        dk    r|
                    |           #| j	        D ]'}|                    t          ||d	                     (|rr| j        rk| j	        rd|dt          | j                           }|t          | j                  d         }d                    |          d                    |          z   }nd                    |          }|
D ]}|t          |          z   }|S | j        d
k    rmg }d}|t          | j                  k     r| j        |         }|j        dk    r|dz  }6|dz   t          | j                  k     o| j        |dz            j        dk    }|                    ||f           |dz  }|t          | j                  k     g }d}|t          |          k     r%||         \  }}t          |||d|o|dk              }|t          |          dz
  k    }d}|j        dk    r |j	        r|j	        D ]}|j        dk    rd} n|rA|r:|                    d          }|dk    r|d|         dz   ||d         z   }n|dz   }n|dz   }|sK|rI|                    d          }|dk    r|d|         dz   ||d         z   }|                    |           n|                    |           |dz  }|t          |          k     %|o|o|d         d         j        dk    }d}d}|t          |          k     rZ||         }|dk    r2|                    d          r	|dz   |z   }n|r	|dz   |z   }n|dz   |z   }n|}|dz  }|t          |          k     Z|S | j        dk    rd}| j        D ]r}|j        dk    r!|j	        r|j	        D ]}|j        dk    rd} n.|j        d
k    r9|j        D ]1}|j        dk    r |j	        r|j	        D ]}|j        dk    rd} n|r n2sg }d}d}| j        D ]}|j        dk    r|j        dk    r|r.|t          |          dz
                               d          rd}Jt          |          dk    rJ|t          |          dz
           dk    r.|t          |          dz
                               d          rd}|                    d           d}|j        dk    r|r|t          |          dz
           dk    rd}|rH|t          |          dz
                               d          r|                    |rdnd           d}5|                    d           d}N|j        dk    r|rd|t          |          dz
           v rd|t          |          dz
           v r|t          |          dz
           }d|v s|                    d          r|dz   |t          |          dz
  <   |                    d          }|d|         dz   ||d         z   |t          |          dz
  <   |                    d           3|rd|t          |          dz
           v rd|t          |          dz
           v re|t          |          dz
           }|                    d          }|d|         dz   |j        z   dz   ||d         z   |t          |          dz
  <   |                    d|j        z              |r@|t          |          dz
                               d          s|                    d           t          |||||o|dk              } t          |          dk    r%|t          |          dz
           }d |v sd!|v rd| z   } |rd| z   } d}|                    |            |dz  }d                    |          }!d"|!v r|!                    d          r|!dz   S |!                    d          r6t+          |!dt          |!          dz
            }!|!                    d          6|sK|!                    d          r6t+          |!dt          |!          dz
            }!|!                    d          6|!S | j        d#k    r~t          | j        |          }"t          | j        |dz             }#d$|"z   d%z   |z   |#z   dz   }| j        r,t          | j        |dz             }$|dz   |z   d&z   |z   |$z   dz   }|dz   |z   d'z   }|S | j        d(k    rlt          | j        |          }"t          | j        |dz             }%d)|"z   d*z   |z   |%z   d+z   |z   d,z   }| j	        r| j	        D ]}|dz   t          |          z   }|S | j        d-k    rlt          | j        |          }"t          | j        |dz             }%d.|"z   d*z   |z   |%z   d+z   |z   d,z   }| j	        r| j	        D ]}|dz   t          |          z   }|S | j        d/k    r| j        }&t          | j        |dz             }%| j        g }'| j        D ]}|'                    |j                   d                    |'          }(|(r$d0|&z   d1z   |(z   d+z   |z   d2z   |z   |%z   d+z   |z   d,z   }n;d0|&z   d3z   |z   d2z   |z   |%z   d+z   |z   d,z   }nd0|&z   d4z   |z   d2z   |z   |%z   d+z   |z   d,z   }| j	        r| j	        D ]}|dz   t          |          z   }|S | j        d5k    rrt          | j        |dz             }%d6| j        z   d7z   | j        z   d7z   | j        z   d8z   |z   |%z   d+z   |z   d,z   }| j	        r| j	        D ]}|dz   t          |          z   }|S | j        d9k    r| j        j        })g }*d}|t          | j                  k     r| j        |         }|j         !                    dd          }+|j        rt          |j        |d:z             }%nd}%|j"        },t          d|d:z             }-t          d|dz             }.|%r|-|%z   dz   nd}/|dk    r%|*                    d|+z   d;z   |/z   |.z   |,z              n!|*                    |+d;z   |/z   |.z   |,z              |dz  }|t          | j                  k     dt          d|dz             z                       |*          }0d}1| j	        rFg }| j	        D ]$}|                    t          |                     %dd                    |          z   }1d<|)z   d=z   |0z   dz   |z   d>z   |1z   S | j        d?k    r[| j#        }2| j        j        d@k    r| j        j        n| j        }3t          |3|dz             $                    d          }%dA|2 dB| |% dCS | j        dk    rt          | j        |||          }%d}1| j	        rCg }| j	        D ]$}|                    t          |                     %d                    |          }1|r|1rdD|%z   dEz   |1z   S dD|%z   dFz   S |1rdG|%z   dHz   |1z   S dG|%z   dIz   S | j        d@k    rt          | j        |          }%|%$                    d          }%|%                    d          rdJndK}4d}1| j	        rCg }| j	        D ]$}|                    t          |                     %d                    |          }1|1rdL|%z   |4z   dz   |1z   S dL|%z   |4z   S | j        dMk    rdN| j%        z   dOz   S | j        dPk    rtM          | j                  }%dQ|%z   dRz   S | j        dSk    r!| j'        rdTt          | j'        |          z   S dTS | j        dUk    r,| j(        rdVndW}5| j'        r|5t          | j'        |          z   S |5S dS )XzUFormat an AST node for command substitution output (bash-oracle pretty-print format).Nru   rM   r   r  r  r  T)r2  heredoc_op_onlyrU  r   rX  re   FrO   rH   z 2>&1z |r  z  r  r>  rU   rm  r  r-  rg   r  r  r  )rM   rO   z || 
z && 
z &
rb  zif z; then
zelse
rf  rj  zwhile z; do
z;
rm  rk  zuntil ri  zfor z in zdo
z in ;
z
 in "$@";
r  zfor ((z; z))
do
rg  r3   z)
zcase z inrh  ro  r  z	function z () 
{ 
z
}r  r  r   r  z ) r  r  r  z{ rC  z((r  r  z[[ z ]]r  r  rr  ztime -p ztime ))r{   r.  rK  r  r   r  r  r  rw   r  _format_redirectr   rx   _format_heredoc_bodyrS  rQ  r  rN  r   r  rb   r_   r  r  r  r  r  r  r  r  r   r  r  r  r;  rA  r  r3  r  rU  r  )6r  r  r  r  r  spinner_spr   rO  r  heredocsrA   r  r  ry   hrZ  rz   r[  r\  result_partsr&  r_  is_lasthas_heredocfirst_nlcompact_pipepartr  skipped_semi	cmd_countlastformatted_cmdrQ   r  r  r  r  r  	word_valsrK  r   r  patterm
pat_indentterm_indent	body_partr  r  rA  
inner_bodyr;  r`   s6                                                         r   rQ  rQ  J  s    |r	S&	!	!B3
++HyGryI 	 	A--ag66C0055C//44C11#66CLL"$ 	# 	#Av""""" 	_ 	_ALL)!5FX\]]]^^^^ 	% 	% 	%0TZ01J"3tz??#4#45NXXj))BGGN,C,CCFFXXe__F 	6 	6A21555FFyJ(*#dm$$$$-"Cx;&&QUS%7%77dDM!a%<P<UYd<dNKKn-...FA #dm$$$$ CIIoo"&s)C+VZ0J#( I SYY]*GKx9$$$  Av**&* +  4 4(~~d33H2~~$-ixi$87$BYxyyEY$Y		$-$7		 )G 3I /{ / %>>$//r>> ))8) 4t ;i		>R RI##I....##I...1HCC CIIooH "LdLtAwqz*/LC%%%%$DQww??4(( 3#d]T1FF! 3#c\D0FF#e^d2FF1HC C%%%% yF 	 	Av""q{"  Av**&* + :%%:  Cx9,,,!$ & &A v22.2 %  3 #  	 N	 N	Av##43;; !&Vq"9"B"B4"H"H !'+  Fq(("3v;;?3t;;"3v;;?3<<TBB < (, MM#&&&#(LLTT\\ !&Vq"9S"@"@',  !&Vq"9"B"B4"H"H !\&CcctDDD', MM$'''#(LLTS[[ , F3v;;?$;;; F3v;;?$;;;%c&kkAo64<<4??3+?+?<6:TkF3v;;?33'+yyH6:9H9o6LtT\T]T]6^F3v;;?33d++++ 2 F3v;;?$;;; F3v;;?$;;;%c&kkAo6#'99T?? (Oc1AD83>hiiP s6{{Q// cADj1111 '&Vq"9"B"B;"O"O 'MM#&&& 3vz+<m>^PY]^P^! ! v;;??!#f++/2D4''8t+;+;(+m(; )$'-$7M#(Lm,,,Q		GGFOOQ;;1::d++;s7Njjoo 	-1aQ!,,A jjoo 	- 	1**T"" 1q!SVVaZ00 **T"" 1yD"4>6::'
CC	
*X5	ACG> 	P+DNFQJGGId]R'(2X=	ICOF$#d*yG"4>6::"49fqj99D8+h6=EJVS> 	<^ < <#(8(;(;;yG"4>6::"49fqj99D8+h6=EJVS> 	<^ < <#(8(;(;;yEh"49fqj99:!#%IZ * *  ))))HHY''E   	
     	 
  " SL9,r1F:XELuTWYY\bb  },r1F:XELuTWYY\bb  > 	<^ < <#(8(;(;;yK"49fqj99i i 	
 i    	 
  	 > 	<^ < <#(8(;(;;yFy #dm$$$$a A)##C//Cv *166A:>><D$S&1*55J%c6A:66K48B
T)D00dIAvvc	E 1I = Kd RSSSSei 7+ E LMMMFA! #dm$$$$" k#vz:::@@JJ	> 	7(*N^ ; ;%%&6q&9&9::::chh~666I~%3d:R?&H9TTyJy'+y~'F'FTY^^DI
":vz::AA#FF@4@@H@d@@@@yJ"49fjBSTT	> 	1(*N^ ; ;%%&6q&9&9::::00I 	$ 5TzD(944:## 	3$;&22d{T!!yM!!"49f55{{3!]]400;TTe
	> 	1(*N^ ; ;%%&6q&9&9::::00I 	>$;+c1I==d{Z''yKd&&--yK ++t|e##yJ= 	E-dmVDDDDtyF#z6w= 	G/vFFFF2r   rA   Redirect | HereDocr2  r  c                   | j         dk    rl| j        rd}nd}| j        dk    rt          | j                  |z   }| j        rd| j        z   dz   }n| j        }|r||z   S ||z   dz   | j        z   | j        z   dz   S | j        }|dk    rd}n|d	k    rd
}| j        j	        }| j        
                    |          }| j                            |          }| j                            |          }|                    d          rd}|dk    r;|                    d
          r&d}t          |dt!          |          dz
            dz   }t          |dt!          |                    }|dk    p,t!          |          dk    o|d                                         }|r"|dk    s|dk    r|rdnd}n |d
k    s|dk    rd	}n|dk    rd}n|d	k    rd
}||z   S |                    d          r||z   S |r||z   S |dz   |z   S )z2Format a redirect for command substitution output.r  r|  r  r   r  rO   z1>r  z0<r  r  Fr  Tre   r  r  z0>r  rM   )r.  r  r  r	   r  rm   r  r  r  r   r  r  r  rb   rN  r_   r   r7  )	rA   r2  r  r  delimr  was_input_close	after_ampis_literal_fds	            r   r  r    sR    	v< 	BBB 4!88QTRB8 	 !+%+EEKE 	:EzD 19,q{:TAA	
B	Tzz	tX^FX//77FX226::FX33F;;F T>>bkk#..>"OB3r77Q;//#5Bvq#f++66	!S([S^^a-?-ZIaLDXDXDZDZ 	SyyB$JJ,6TT$sbDjj TzztF{	{{3 F{ F{8fr   c                ,    d| j         z   | j        z   dz   S )z@Format just the heredoc body part (content + closing delimiter).rO   )r  rm   )rA   s    r   r  r    s    !)ak)D00r   r   r3  c                   |}|}t                      }|t          |           k     r| |         }|dk    r#|dz   t          |           k     r|j        r|dz  }E|dk    r|j        s|j         |_        |dz  }e|dk    r|j        s|j         |_        |dz  }|j        s|j        r|dz  }t	          | |d          rt          | |d          r|dz  }|dz  }nYt	          | |d          r$t          | |d          r|dz  }|d	k    rd
S |dz  }n$|dk    r|dz  }n|dk    r|d	k    r|dz  }nn|dz  }|t          |           k     dS )zLook ahead from start to find if esac closes all cases before a closing ).

    Returns True if we find esac that brings case_depth to 0.
    Returns False if we hit a ) that would close the command substitution.
    rD   re   rg   r  rE   rg  r   rh  r   Tr  r   F)r  r   r  r  rc   _is_word_boundary)r   r\   r3  rz   r3  r6  r#   s          r   _lookahead_for_esacr    s    	AELLE
c%jj..!H99QU+++FA88EL8$|+ELFA88EL8$|+ELFA< 	5< 	FA5!V,, 	1B5!Q1O1O 	QJEFAAUAv.. 	3DUAq3Q3Q 	QJEzztFAA#XXFAA#XXqyyQFAI c%jj..J 5r   c                   |dz   }|t          |           k     rX| |         dk    rL| |         dk    r|dz   t          |           k     r|dz  }n|dz  }|t          |           k     r| |         dk    L|t          |           k     r|dz  }|S )zLSkip past a backtick command substitution. Returns position after closing `.re   r  rD   rg   r  )r   r\   rz   s      r   _skip_backtickr  I  s    	A
c%jj..U1X__8tAE

 2 2FAAFA	 c%jj..U1X__
 	3u::~~	QHr   c                    |}|t          |           k     r0| |         dk    r$|dz  }|t          |           k     r| |         dk    $|t          |           k     r|dz   n|S )zPSkip from after opening ' to after closing '. Mirrors bash skip_single_quoted().r  re   r  )rQ   r\   rz   s      r   _skip_single_quotedr  V  sd    A
c!ff**1	Q c!ff**1AJJ1q55A%r   c                   |t          |           }}dx}}||k     r| |         }|rd}|dz  }|dk    rd}|dz  }&|r|dk    rd}|dz  }6|dk    rd}|dz  }D|dk    rO|dz   |k     rF| |dz            dk    rt          | |dz             }v| |dz            d	k    rt          | |dz             }|d
k    r|dz   S |dz  }||k     |S )zJSkip from after opening " to after closing ". Handles $(), ${}, backticks.Fre   rD   Tr  rf   r  rg   r  rE   )r   r  _find_braced_param_end)rQ   r\   rz   r@   r  backqr#   s          r   _skip_double_quotedr  ^  s,   #a&&qAI
a%%aD 	IFA99IFA 	CxxFA88EFA88A		Qx3$QA..Qx3*1a!e4488q5L	Q9 a%%: Hr   c                R   d}|dz   }|t          |           k     r| |         }t          | |d          rt          | |dz             }@|dk    r|dz  }n;|dk    r5|dk    r|dz  }n)|dz   t          |           k     r| |dz            dk    rdS d	S |dz  }|t          |           k     d	S )
a  Check if $(( at position starts a valid arithmetic expression.

    Scans forward looking for )) at the top paren level (excluding nested $()).
    Returns True if valid arithmetic, False if this is actually $( ( ... ) )
    (command substitution containing a subshell).
    r   r-  r  rg   r  re   r   TF)r   ro   r  )r   r\   
scan_parenscan_iscan_cs        r   _is_valid_arithmetic_startr    s     JQYF
3u::

vufd33 	%eVaZ88FS==!OJJs]]A~~a

!c%jj((U6A:->#-E-Et u!! 3u::

" 5r   c                    d}|}t                      }|t          |           k     r|dk    r| |         }|dk    r#|dz   t          |           k     r|j        s|dz  }J|dk    r|j        s|j         |_        |dz  }j|dk    r|j        s|j         |_        |dz  }|j        s|j        r|dz  }|dk    r|dz  }n|dk    r|dz  }|dk    r|dz   S |dz  }|t          |           k     r|dk    t          |           S )	zFind the end of a ${ cmd; } brace command substitution.

    Starts after the opening ${. Returns position after the closing }.
    Handles nested braces, quotes, and command substitutions.
    re   r   rD   rg   r  rE   r  r  )r  r   r  r  )r   r\   r3  rz   r6  r#   s         r   r  r    s<    EALLE
c%jj..UQYY!H99QU++EL+FA88EL8$|+ELFA88EL8$|+ELFA< 	5< 	FA88QJEE#XXQJEzz1u	Q- c%jj..UQYY. u::r   c                
   d}|}d}d}d}d}|t          |           k     r|dk    r| |         }|dk    r|dz   t          |           k     r|dz  }E|dk    rt          | |dz             }_|dk    rt          | |dz             }y|dk    r|dk    r||k    sx| |dz
           d	k    si| |dz
           d
k    sZ| |dz
           dk    sK| |dz
           dk    s<| |dz
           dk    s-| |dz
           dk    s| |dz
           dk    s| |dz
           dk    rE|t          |           k     r0| |         dk    r$|dz  }|t          |           k     r| |         dk    $Ht          | |d          r|dz  }|t          |           k     rH| |         d	k    s| |         d
k    r0|dz  }|t          |           k     r| |         d	k    $| |         d
k    0|t          |           k     r| |         dk    r|dz  }|t          |           k     rX| |         dk    rL| |         dk    r|dz   t          |           k     r|dz  }n|dz  }|t          |           k     r| |         dk    L|t          |           k     r|dz  }n|t          |           k     rm| |         dk    ra|dz  }|t          |           k     r0| |         dk    r$|dz  }|t          |           k     r| |         dk    $|t          |           k     r|dz  }n?|t          |           k     r,| |         dvr"|dz  }|t          |           k     r
| |         dv"#t	          | |d          r3t          | |          r|dz  }|dz  }Pt          | |dz             }	|	}g|dk    r#|dk    rt          | |d          r|dz  }|dz  }|dk    rt          | |          }|dk    r#t          | |d          rt          | |          }t          | |d          rt          | |d          r|dz  }d}|dz  }|dk    r+t          | |d          rt          | |d          r	d}|dz  }2t          | |d          r%t          | |d          r|dk    r|dz  }d}|dz  }ht          | |d          r|dz  }|dk    r|r|dk    s|dk    r|dz  }nE|dz  }n?|dk    r9|r |dk    rt          | |dz   |          s|dz  }n|dk    r|dk    r|dz  }n|dz  }|dz  }|t          |           k     r|dk    |S )zFind the end of a $(...) command substitution, handling case statements.

    Starts after the opening $(. Returns position after the closing ).
    re   r   FrD   rg   r  rE   r  rM   rN   rO   r  r  r  r  r   r}  r-  z
 	
;|&<>()r  r  r  r  rg  r   rn  Trh  r  )r   r  r  rc   ro   r  r  r  _skip_heredocr  r  )
r   r\   r3  rz   r3  in_case_patternsr4  r5  r#   rk   s
             r   r  r    s6   
 EAJK
c%jj..UQYY!H99QU++FA88#E1q511A88#E1q511A
 HHq  U

Q<3&&Q<4''Q<4''Q<3&&Q<3&&Q<3&&Q<3&&Q<3&& c%jj..U1X%5%5Q c%jj..U1X%5%55!U++ 	FAc%jj..eAh#ooqT9I9IQ c%jj..eAh#ooqT9I9I 3u::~~%(c//Q#e**nnqSQx4''AECJJ,>,>QQ	 #e**nnqS
 s5zz>>FASZZE!HOOQ#e**nnqSFA #e**nnqSs5zz>>FA #e**nnq)G)GFA #e**nnq)G)Gua// 	)%33 q Q A..AA??0A55/%QRTX:Y:Y51KFA 88ua((A!q$ ? ?eQ''A5!V,, 	1B5!Q1O1O 	!OJ$FA>>oeQ==>BSTY[\^_B`B`>#FA5!V,, 	1B5!Q1O1O 	A~~a
#( FA5!T** 	FA88$ a??%*%%QJE#XX JNN*5!a%DD QJEq$q((%*% 
	Q} c%jj..UQYY~ Hr   c                   d}|}d}t           j        }|t          |           k     r|dk    r| |         }|dk    r|dz   t          |           k     r|dz  }E|dk    r&|t           j        k    r|st	          | |dz             }q|dk    r	| }|dz  }|r|dz  }|t           j        k    r|dv rt           j        }n |t           j        k    r|d	v rt           j        }|d
k    r,|t           j        k    r|st          | |d          }|dk    r|}|dk    s|dk    r:|dz   t          |           k     r$| |dz            dk    rt          | |dz             }A|dk    r|dz  }n|dk    r|dz  }|dk    r|dz   S t          | |d          rt          | |dz             }t          | |d          rt          | |dz             }|dz  }|t          |           k     r|dk    |S )z>Find end of ${...}. Starts after ${. Returns position after }.re   Fr   rD   rg   r  rE   r   z:-=?+/r  rH   r  r  r  r  r  r  rF  )
r   r   r   r   r  r   _skip_subscriptr  ro   r  )r   r\   r3  rz   	in_doubler  r#   r]   s           r   r  r  O  sB   EAI"(N
c%jj..UQYY!H99QU++FA88-*===i=#E1q511A88%IFA 	FA]000Q&[[*0NN}222qH}}*/N88-*===i=!%A..CbyyHHSa!ec%jj&8&8U1q5\S=P=P A..A88QJEE#XXQJEzz1uua.. 	 A..Aua.. 	&ua!e44A	QY c%jj..UQYYZ Hr   c                   |dz   }|t          |           k     r| |         dk    r|dz  }|t          |           k     rBt          | |                   r-|dz  }|t          |           k     rt          | |                   -|}d}|t          |           k     r| |         dk    s| |         dk    r}| |         }|dz  }|}|t          |           k     r0| |         |k    r$|dz  }|t          |           k     r| |         |k    $t          | ||          }|t          |           k     r|dz  }n|t          |           k     r| |         dk    r|dz  }|}|t          |           k     r|dz  }|t          |           k     rBt          | |                   s-|dz  }|t          |           k     rt          | |                   -t          | ||          }nf|t          |           k     rBt          | |                   s-|dz  }|t          |           k     rt          | |                   -t          | ||          }d}t	                      }d	}|t          |           k     r| |         d
k    r| |         }	|	dk    r%|dz   t          |           k     r|j        s|r|dz  }R|	dk    r|j        s|s|j         |_        |dz  }t|	dk    r|j        s|s|j         |_        |dz  }|	dk    r|j        s	| }|dz  }|j        s	|j        s|r|dz  }|	dk    r|dz  }n|	dk    r|dk    rn)|dz  }|dz  }|t          |           k     r| |         d
k    |t          |           k     r| |         dk    r|S |t          |           k     r| |         d
k    r|dz  }|t          |           k     r|}
|}|t          |           k     r0| |         d
k    r$|dz  }|t          |           k     r| |         d
k    $t          | |
|          }|t          |           k     rd}t          t          |          dz
  dd          D ]}||         dk    r|dz  } |dz  dk    rn{|dd         }|dz  }|}|t          |           k     r0| |         d
k    r$|dz  }|t          |           k     r| |         d
k    $|t          | ||          z   }|t          |           k     |dz   t          |           k     r%| |dz            dk    r|                    d          }n|}||k    r|t          |           k     r|dz   S |S |	                    |          rTt          |          t          |          k    r4t          |          t          |          z
  }|
|z   t          |          z   S |t          |           k     r|dz   }n|}|t          |           k     |S )zKSkip past a heredoc starting at <<. Returns position after heredoc content.rg   r  re   NrE   r  rD   r   FrO   r  r  r   rH   rN   )
r   rZ   r_   r  r  r  r  r  r  rb   )r   r\   rz   delim_start
quote_charrm   r0  r6  r  r#   
line_startline_endr   trailing_bsrk   next_line_startr6  tabs_strippeds                     r   r"  r"    sN   	A3u::~~%(c//	Q
c%jj..6uQx@@.	Q c%jj..6uQx@@. KJ3u::~~58s??eAh#oo1X
	Q#e**nnqZ!7!7FA #e**nnqZ!7!7uk155	s5zz>>FA	
SZZE!H,,	Qs5zz>>FA#e**nn\%(%;%;nFA #e**nn\%(%;%;nuk155		 #e**nn\%(%;%;nFA #e**nn\%(%;%;nuk155	 KLLEK
c%jj..U1X--!H99QU++++FA88EL88$|+ELFA88EL88$|+ELFA88EL8)/KFA< 	5< 	; 	FA881KK#XXa1K	Q? c%jj..U1X--B 	3u::~~%(c//3u::~~%(d**	Q
c%jj..
U##h4(?(?MH U##h4(?(?%X66U##K3t99q="b11  7d??1$KKQ!##9DMH&OSZZ''E(Ot,C,CA SZZ''E(Ot,C,C*UOXFFFD U##" 19s5zz!!eEAI&6#&=&={{4((HHHy  #e**$$!|# y)) 	?c(mmc)nn.L.LIIH5M-I>>c%jj  1AAAY c%jj..Z Hr   rO  
delimiterslist[tuple[str, bool]]tuple[int, int]c                   |s||fS |}|t          |           k     r0| |         dk    r$|dz  }|t          |           k     r| |         dk    $|t          |           k    r||fS |}|dz  }|D ]\  }}|t          |           k     r|}|}|t          |           k     r0| |         dk    r$|dz  }|t          |           k     r| |         dk    $t          | ||          }	|t          |           k     rd}
t          t          |	          dz
  dd          D ]}|	|         dk    r|
dz  }
 |
dz  dk    rn{|	dd         }	|dz  }|}|t          |           k     r0| |         dk    r$|dz  }|t          |           k     r| |         dk    $|	t          | ||          z   }	|t          |           k     |r|	                    d          }n|	}||k    r|t          |           k     r|dz   n|}n|                    |          rUt          |          t          |          k    r5t          |	          t          |          z
  }||z   t          |          z   }n.|t          |           k     r|dz   n|}|t          |           k     ||fS )	a  Find heredoc content in source starting at start.
    Returns (content_start, content_end) where content_start is position after newline
    and content_end is position after all heredoc content.
    delimiters is list of (delimiter, strip_tabs) tuples.
    rO   re   r   rH   rD   rg   NrN   )r   r_   r  r  rb   )rO  r\   r/  r
   content_startrm   r  r*  r+  r   r,  rk   r-  line_strippedr.  s                  r   _find_heredoc_content_endr5    s      e|
C
F

st 3 3q F

st 3 3
c&kke|M1HC!+ &G &G	:CKKJHS[[((VH-=-E-EA S[[((VH-=-E-Efj(;;DS[[((s4yy1}b"55  AAw$#q(?a''CRCyA"*V,,1AT1I1IMH V,,1AT1I1Ij(KKK S[[((   % $D 1 1 $	))&.V&<&<hll( ''	22 s=7I7ICPYNN7Z7Z #D		C,>,> > =03y>>A"*S[["8"8(Q,,hCK CKKL #r   word_lenc                    |dk    r-| |dz
           }|                                 s|dk    rdS |dv rdS ||z   }|t          |           k     r(| |                                          s| |         dk    rdS dS )a+  Check if the word at pos is a standalone word (not part of larger word).

    For reserved words to be recognized, they must be preceded by whitespace,
    command separators, or be at the start of the string. Characters like }
    can be part of command names (e.g., }case is a valid command).
    r   re   r  Fz{}!T)r  r   )rQ   r
   r6  r  r]   s        r   r  r  @  s     Qwwqz<<>> 	TS[[5 5==5
.C
SVV||3))|QsVs]]u4r   >   rl  rf  rb  rn  ri  rg  rm  re  rd  rh  rc  rk  rj  rq  rp  ro     -G-L-N-O-R-S-a-b-c-d-e-f-g-h-k-o-p-r-s-t-u-v-w-x-z-n   -ef-eq-ge-gt-le-lt-ne-nt-otr  r  r  !====~>   rb  ri  rg  rk  rj  rp  >   letevalaliaslocalexportdeclaretypesetreadonlyc                    | dk    p| dk    S )Nr  rE   r"   r,   s    r   	_is_quoteri        8qCxr   c                    g }d}| D ]?}|dk    s|dk    r|s|                     d           d}(|                     |           d}@d                    |          }|                    d          S )z;Collapse consecutive tabs/spaces to single space and strip.FrM   rN   Tru   r  )rw   rx   r  )rQ   ry   prev_was_wsr#   joineds        r   _collapse_whitespacern    s    FK    88qDyy #c"""KKMM!KKWWV__F<<r   c                v    d}t          t          |           dz
  dd          D ]}| |         dk    r|dz  } |S )z'Count trailing backslashes in a string.r   re   rH   rD   )r  r   )rQ   rh   rz   s      r   _count_trailing_backslashesrp    sL    E3q66A:r2&&  Q44<<QJEELr   c                   g }d}|t          |           k     r5|dz   t          |           k     r3| ||dz            dk    r!|                    d           |dz  }d}g }|t          |           k     r|dk    r| |         dk    r!|dz  }|                    | |                    n| |         dk    rv|dz  }|dk    rOd                    |          }t          |          }|                    |           |                    d           n7|                    | |                    n|                    | |                    |dz  }|t          |           k     r|dk    n|dz   t          |           k     r3| ||dz            dk    r!|                    d           |dz  }d}g }|t          |           k     r|dk    r| |         d	k    r!|dz  }|                    | |                    n| |         d
k    rv|dz  }|dk    rOd                    |          }t          |          }|                    |           |                    d
           n7|                    | |                    n|                    | |                    |dz  }|t          |           k     r|dk    n|dz   t          |           k     rV| |         dv rK| |dz            dk    r;|                    | |                    |                    d           |dz  }d}g }|t          |           k     r|dk    r| |         dk    r!|dz  }|                    | |                    n| |         dk    rv|dz  }|dk    rOd                    |          }t          |          }|                    |           |                    d           n7|                    | |                    n|                    | |                    |dz  }|t          |           k     r|dk    n |                    | |                    |dz  }|t          |           k     5d                    |          S )z)Normalize heredoc delimiter for matching.r   re   rg   r  r  r   ru   rF  r  r  r  )r   rw   rx   rn  )rm   ry   rz   r3  r\  	inner_strs         r   _normalize_heredoc_delimiterrs    s   F	A
c)nn

q53y>>!!iAE	&:d&B&BMM$FAEEc)nn$$Q<3&&QJELL1....q\S((QJEzz$&GGENN	$8$C$C	i000c****Yq\2222LL1...Q c)nn$$" US^^##	!a!e)(<(D(DMM$FAEEc)nn$$Q<3&&QJELL1....q\S((QJEzz$&GGENN	$8$C$C	i000c****Yq\2222LL1...Q c)nn$$" US^^##	!(<(<1q5AQUXAXAXMM)A,'''MM#FAEEc)nn$$Q<3&&QJELL1....q\S((QJEzz$&GGENN	$8$C$C	i000c****Yq\2222LL1...Q c)nn$$" MM)A,'''FAM c)nn

N 776??r   c                z    | dk    p5| dk    p/| dk    p)| dk    p#| dk    p| dk    p| dk    p| dk    p| d	k    p| d
k    S )NrM   rN   rO   r  r  r  r  r   r  r  r"   r,   s    r   r  r    s    	S 		9		9		 8		 8			
 8		 8		 8		 8		 8r   c                2    | dk    p| dk    p| dk    p| dk    S )z@Check if character triggers brace command substitution (funsub).rM   rN   rO   r  r"   r,   s    r   r  r    s'    89qDy9AI9c9r   c                >    | dk    p| dk    p| dk    p| dk    p| dk    S )Nr.  rF   r  r  rE  r"   r,   s    r   r  r  "  s0    8CqCxC18CqCxC18Cr   c                    | dk    p| dk    S )Nr  r  r"   r,   s    r   r  r  &  rj  r   c                b    | dk    p)| dk    p#| dk    p| dk    p| dk    p| dk    p| dk    p| dk    S )	NrF   rf   rE  r  r.  r  r  r  r"   r,   s    r   r6  r6  *  sS    	SdAHdSdAHdSdAHdPQUXPXd\]ad\dr   c                V    | dk    p#| dk    p| dk    p| dk    p| dk    p| dk    p| dk    S )zISpecial params valid after bare $ (excludes & which is a shell metachar).rF   rf   rE  r  r.  r  r  r"   r,   s    r   r=  r=  0  sE    8[qCx[18[qCx[18[qCx[STX[S[[r   c                    | dk    o| dk    S )Nr&   r'   r"   r,   s    r   r>  r>  5  r1   r   c                    | dk    p| dk    S )Nr  rO   r"   r,   s    r   _is_semicolon_or_newliner|  9  r[   r   c                z    | dk    p5| dk    p/| dk    p)| dk    p#| dk    p| dk    p| dk    p| dk    p| d	k    p| d
k    S )z;Check if char ends a word context (whitespace or metachar).rM   rN   rO   r  r  r  r  r  r  r   r"   r,   s    r   _is_word_end_contextr~  =  s     	
S 		9		9		 8		 8			
 8		 8		 8		 8		 8r   re   rg   opencloser  c                   t          |           }|t          z  r|}n||k    s| |         |k    rdS |dz   }d}d}d}	||k     r|dk    r| |         }
|rd}|dz  }|t          z  }|s|
dk    rd}|dz  }9|	r|
dk    rd}	|dz  }I|s|
dk    rd}	|dz  }Y|s|
dk    rt          | |dz             }u|s|
d	k    rt	          | |dz             }|s%t          | |d
          rt          | |dz             }|s%t          | |d          rt          | |dz             }|s|
|k    r|dz  }n|
|k    r|dz  }|dz  }||k     r|dk    |dk    r|ndS )a<  Skip a matched pair of brackets, handling quotes and escapes.

    Mirrors bash's skip_matched_pair() in subst.c:2086.
    Returns index after closing bracket, or -1 if unmatched.

    Flags:
        _SMP_LITERAL (1): No quote/escape processing
        _SMP_PAST_OPEN (2): start already points past open bracket
    rH   re   Fr   rD   Tr  r  rE   r  rg   rF  )r   _SMP_PAST_OPEN_SMP_LITERALr  r  ro   r  r  )rQ   r\   r  r  r  r@   rz   r3  r  r  r#   literals               r   _skip_matched_pairr  R  s    	AA~ A::5T))2AIEIE
a%%EAIIaD 	IFA,& 	199IFA 	CxxFA 	188EFA 	188#Aq1u--A 	188#Aq1u--A 	.q!T:: 	 AE**A 	.q!T:: 	&q!a%00A 	199QJEE%ZZQJE	QI a%%EAIIJ 

11"r   c                (    t          | |dd|          S )zSkip a bracketed subscript starting at s[start]='['.

    Mirrors bash's skipsubscript() in subst.c:2186.
    Flags are passed through to _skip_matched_pair().
    r  r  )r  )rQ   r\   r  s      r   r%  r%    s     aS%888r   c                `   | sdS | d                                          s| d         dk    sdS d}|t          |           k     r| |         }|dk    r|S |dk    rp|dz  rt          nd}t          | ||          }|dk    rdS |}|t          |           k     r| |         dk    r|dz  }|t          |           k     r| |         dk    r|S dS |dk    r,|dz   t          |           k     r| |dz            dk    r|dz   S dS |                                s|dk    sdS |dz  }|t          |           k     dS )	zReturn index of '=' if s is an assignment word, else -1.

    Handles: NAME=, NAME+=, NAME[sub]=, NAME[sub]+=
    Matches bash's assignment() function in general.c.

    Flags:
        & 2: Use literal subscript matching (for compound assignments)
    rH   r   r  re   r  r  rg   r  )r8  r   r  r%  r  )rQ   r  rz   r#   	sub_flagsr]   s         r   _assignmentr    sa     raDLLNN adckkr	A
c!ff**aD88H88).:I!!Q	22CbyyrA3q66zzadckkQ3q66zzadckk2881us1vv~~!AE(c//1u2		 	qCxx2	Q+ c!ff**, 2r   r  r  c                "   | sdS | d                                          s| d         dk    sdS d                    |           }d}|t          |          k     rd||                                         s||         dk    r>|dz  }|t          |          k     r&||                                         2||         dk    >|t          |          k     rA||         dk    rdS t	          ||t
                    }|dk    rdS |}|t          |          k     AdS )	zECheck if chars form name or name[subscript]... for array assignments.Fr   r  ru   re   r  rH   T)r8  rx   r   r  r%  r  )r  rQ   rz   r]   s       r   r  r    s
    u!H %(c//u
A	A
c!ff**!A$,,..*AaDCKK	Q c!ff**!A$,,..*AaDCKK
c!ff**Q43;;5aL11"995 c!ff** 4r   c                >    t          |           pt          |           S r   )r6  r>  r,   s    r   _is_special_param_or_digitr    s    Q/9Q<</r   c                    | dk    pG| dk    pA| dk    p;| dk    p5| dk    p/| dk    p)| dk    p#| dk    p| d	k    p| d
k    p| dk    p| dk    p| dk    S )Nr  r  r  r  rF   r  r(  r!  r  r,  r.  r  r  r"   r,   s    r   _is_param_expansion_opr    s    	S 	8	8	 8	 8		
 8	 8	 8	 8	 8	 8	 8	 8r   c                2    | dk    p| dk    p| dk    p| dk    S )Nr  r  rF   r  r"   r,   s    r   r/  r/    s'    87qCx7187qCx7r   c                &    | dk    p| dk    p| dk    S )Nrf   r  rD   r"   r,   s    r   rM  rM    s    8,qCx,19,r   c                h    t          |           p#| dk    p| dk    p| dk    p| dk    p| dk    p| dk    S )Nr  r  r   r  r  r  )rP   r,   s    r   _is_negation_boundaryr    sL    !dSdAHdSdAHdPQUXPXd\]ad\ddr   r&  c                ~    d}|dz
  }|dk    r(| |         dk    r|dz  }|dz  }|dk    r| |         dk    |dz  dk    S )zEReturn True if value[idx] is escaped by an odd number of backslashes.r   re   rD   rg   r"   )r   r&  rj   rk   s       r   r  r    sc    HaA
q&&U1X%%A	Q q&&U1X%% a<1r   c                ~    d}|dz
  }|dk    r(| |         dk    r|dz  }|dz  }|dk    r| |         dk    |dz  dk    S )a	  Return True if $( at idx is actually $$( where $$ is PID, not command sub.

    Count consecutive $ before idx. If odd, the $( is consumed by $$ (PID param).
    E.g., $$(  -> $$ + ( literal (1 $ before, odd)
          $$$( -> $$ + $( cmdsub (2 $ before, even)
    r   re   rf   rg   r"   )r   r&  rX  rk   s       r   r  r    sc     LaA
q&&U1X__	Q q&&U1X__ !q  r   c                    | dk    p| dk    S )Nr  r   r"   r,   s    r   	_is_parenr    rj  r   c                    | dk    p| dk    S )NrE  r  r"   r,   s    r   _is_caret_or_bangr    rj  r   c                    | dk    p| dk    S )Nr.  r  r"   r,   s    r   rL  rL    rj  r   c                ,    t          |           p| dk    S )Nr  )r>  r,   s    r   _is_digit_or_dashr    s    Q<<#18#r   c                    | dk    p| dk    S )NrO   r   r"   r,   s    r   _is_newline_or_right_parenr    s    9 S r   c                &    | dk    p| dk    p| dk    S )Nr  rO   r  r"   r,   s    r   _is_semicolon_newline_bracer  !  s    8,qDy,AH,r   c                (    t          |           dk    S )z)Check if s looks like an assignment word.rH   )r  rW   s    r   _looks_like_assignmentr  %  s    q>>Rr   rA  c                    | sdS | d                                          s| d         dk    sdS | dd         D ]}|                                s	|dk    s dS  dS )zBCheck if name is a valid bash identifier (variable/function name).Fr   r  re   NT)r8  r  )rA  r#   s     r   _is_valid_identifierr  *  sr     uGOO aCu!""X  		 	qCxx554r   c                  H   e Zd ZdZdddZddZddZddZddZddZ	ddZ
ddZddZddZddZddZddZdd Zdd!Zdd#Zdd$Zdd&Zdd(Zdd)Zdd*Zdd+Zdd,Zdd.Zdd0Zdd1Zdd2Zdd3Zdd4Z dd5Z!dd7Z"dd:Z#dd;Z$dd<Z%	 dddBZ&	 dddJZ'	 dddLZ(	 dddPZ)	 	 	 dddRZ*ddTZ+ddUZ,ddWZ-ddXZ.ddYZ/ddZZ0dd[Z1dd^Z2dd_Z3ddd`Z4ddaZ5ddbZ6dddZ7ddeZ8ddfZ9ddgZ:ddhZ;ddlZ<ddmZ=ddnZ>ddoZ?ddpZ@ddqZAddrZBddsZCddtZDdduZEddvZFddwZGddxZHddyZIddzZJdd{ZKdd|ZLdd}ZMdd~ZNddZOddZPddZQddZRdddZSddZTddZUddZVddZWddZXddZYddZZddZ[ddZ\h dZ]h dZ^ddZ_ddZ`ddZaddZbddZcddZdddZeddZfd dZgddZhddZiddZjddZkddZlddZmddZnddZoddZpd	dZqd
dZrddZsddZtddZuddZvddZwddÄZxddĄZyddńZzdddǄZ{ddȄZ|ddɄZ}dd˄Z~dd̄Zdd΄ZdS (  rO  z"Recursive descent parser for bash.FrO  r	   rH  r$   rP  c                   || _         d| _        t          |          | _        g | _        d| _        d| _        || _        || _        t                      | _
        t          ||          | _        | | j        _        g d| _        t          j        | _        t$          j        | _        d | _        t*          | _        d| _        d| _        d| _        d| _        d| _        d| _        d S )Nr   rH   FrP  )NNNNru   )rO  r
   r   rR  rV  _cmdsub_heredoc_endr  _in_process_subrW  rB  _ctxrN  _lexerrX  _token_historyr   r   rT  r   rU  rY  r[  r\  r]  r^  r_  
_arith_src
_arith_pos
_arith_len)r   rO  rH  rP  s       r   r   zParser.__init__?  s    v;;02 )+ ,1)-"...	"67;;;"2J2J2J"2"7$1$6&*"1!&!&"'!  r   flagr   r   r  c                $    | j         |z  | _         dS )zSet a parser state flag.NrT  r   r  s     r   
_set_statezParser._set_stateb  s    !/$6r   c                &    | j         | z  | _         dS )zClear a parser state flag.Nr  r  s     r   _clear_statezParser._clear_statef  s    !/4%7r   c                    | j         |z  dk    S )z$Check if a parser state flag is set.r   r  r  s     r   	_in_statezParser._in_statej  s    "T)a//r   r  c                    t          | j        | j        t          | j                  | j                                        | j                  S )zSave current parser state for nested parsing.

        Based on bash's save_parser_state(). Used when entering nested
        constructs like command substitutions to preserve context.
        r  )r  rT  rU  rU   rV  r  rI  rY  r   s    r   _save_parser_statezParser._save_parser_staten  sK      +/!$"899i**,,o
 
 
 	
r   savedc                    |j         | _        |j        | _        |j        | _        | j                            |j                   dS )a  Restore parser state after nested parsing.

        Based on bash's restore_parser_state(). Note: position is NOT restored
        since we've advanced through the nested content. Heredocs are also not
        restored since they were consumed during nested parsing.
        N)	r  rT  r  rU  r  rY  r  rL  r  )r   r  s     r   _restore_parser_statezParser._restore_parser_state|  sA     #/$3/	u/////r   r  r   c                ^    || j         d         | j         d         | j         d         g| _         dS )z/Record token in history, shifting older tokens.r   re   rg   N)r  r  s     r   _record_tokenzParser._record_token  s8     """	
r   r  r  r  c                \   | j         t          j        k    rdS |t          |          dk    rdS |d         }| j         t          j        k    r2|r0|dv rt          j        | _         dS |dk    rt          j        | _         dS | j         t          j        k    r|dv rt          j        | _         dS dS dS )zhUpdate dolbrace state based on operator seen.

        Based on bash's parse.y lines 4010-4027.
        Nr   r   r!  r  r"  r#  s       r   r%  zParser._update_dolbrace_for_op  s    
 =#555F:RAFU
=#66696V##'4':$S  '4';$=#666]**'4'7$$$ 76**r   c                X   | j         j        z| j         j        j        | j        k    sT| j         j        | j        k    s?| j         j        | j        k    s*| j         j        | j        k    s| j         j	        | j
        k    rd| j         _        | j         j        | j        k    r| j        | j         _        | j        | j         _        | j        | j         _        | j        d         | j         _        | j        | j         _        | j        | j         _        | j        | j         _        | j
        | j         _
        dS )z(Sync Lexer position and state to Parser.Nr   )r  rS  r
   ra  r\  rb  r]  rc  r^  rd  r_  rY  rT  r  rZ  r   s    r   _sync_lexerzParser._sync_lexer  s     ;#/(,88;3t7III;74;QQQ;74;QQQ;8D<SSS+/(;?dh&&"hDKO!%$($6!'+':1'=$$($6!(,(>%(,(>%)-)@&&&r   c                (    | j         j        | _        dS )z'Sync Parser position to Lexer position.N)r  r
   r   s    r   _sync_parserzParser._sync_parser  s    ;?r   c                <   | j         j        z| j         j        j        | j        k    r`| j         j        | j        k    rK| j         j        | j        k    r6| j         j        | j        k    r!| j         j	        | j
        k    r| j         j        S | j        }|                                  | j                                         }| j        | j         _        | j        | j         _        | j        | j         _        | j
        | j         _	        | j         j        | j         _        || _        |S )zPeek at next token via Lexer.)r  rS  r
   ra  r\  rb  r]  rc  r^  rd  r_  r  r	  r`  )r   	saved_posry   s      r   _lex_peek_tokenzParser._lex_peek_token  s    
 K$0(,880D4FFF48NNN48NNN59PPP;++H	''))+/+=(/3/E,/3/E,040G-%)[_"r   c                   | j         j        | j         j        j        | j        k    r| j         j        | j        k    r| j         j        | j        k    rk| j         j        | j        k    rV| j         j	        | j
        k    rA| j                                         }| j         j        | _        | j         j        | j         _        n|                                  | j                                         }| j        | j         _        | j        | j         _        | j        | j         _        | j
        | j         _	        |                                  |                     |           |S )z+Get next token via Lexer and sync position.)r  rS  r
   ra  r\  rb  r]  rc  r^  rd  r_  r  r`  r  r  r  r  s     r   _lex_next_tokenzParser._lex_next_token  s'    K$0(,880D4FFF48NNN48NNN59PPP +((**C{1DH"k8DKOO +((**C/3/ADK,373IDK0373IDK0484KDK13
r   c                    |                                   | j                                         |                                  dS )zSkip blanks via Lexer.N)r  r  r  r  r   s    r   _lex_skip_blankszParser._lex_skip_blanks  s@    !!!r   c                    |                                   | j                                        }|                                  |S )z<Skip comment via Lexer. Returns True if comment was skipped.)r  r  r  r  r   ry   s     r   _lex_skip_commentzParser._lex_skip_comment  s>    **,,r   c                    |                                  }|j        }|t          j        t          j        t          j        t          j        t          j        t          j        t          j	        fv S )a  Check if next token is a simple command terminator.

        Returns True for tokens that terminate a simple command:
        - EOF (including via _eof_token mechanism)
        - NEWLINE
        - PIPE (but not PIPE_AMP)
        - SEMI (but not SEMI_SEMI, SEMI_AMP, SEMI_SEMI_AMP)
        - LPAREN, RPAREN
        - AMP (but not AMP_GREATER, AMP_GREATER_GREATER, AND_AND)
        - RBRACE (at command position)
        )
r  r   r}   r   r   r   r   r   r   r   r   r  rB   s      r   _lex_is_command_terminatorz!Parser._lex_is_command_terminator  sT     ""$$HMNNM
 
 	
r   tuple[int, str]c                    |                                  }|j        }|t          j        k    r|t          j        k    s |t          j        k    r|t          j        k    r	||j        fS dS )zOPeek operator token. Returns (token_type, value) or (0, "") if not an operator.)r   ru   )r  r   r}   r   r   r   r   r   r  s      r   _lex_peek_operatorzParser._lex_peek_operator#  sb    ""$$H A):$:$:"""qI,>'>'>sy>!wr   c                    |                                  }|j        t          j        k    rdS |j        }|                    d          r
|dd         }|t          v s|dv r|S dS )zCPeek reserved word. Returns word value if reserved, None otherwise.Nr  r  r  r  rs  rt  rE  rr  )r  r   r}   r   r   rN  ru  )r   r  r   s      r   _lex_peek_reserved_wordzParser._lex_peek_reserved_word/  ss    ""$$8y~%%4 y==   	9D >!!T-P%P%PKtr   r   c                6    |                                  }||k    S )z0Check if next token is a specific reserved word.)r  )r   r   reserveds      r   _lex_is_at_reserved_wordzParser._lex_is_at_reserved_word?  s    //114r   expectedc                    |                                  }|j        t          j        k    rdS |j        }|                    d          r
|dd         }||k    r|                                  dS dS )zJTry to consume a word token matching expected. Returns True if successful.Fr  Nr  T)r  r   r}   r   r   rN  r  )r   r  r  r   s       r   _lex_consume_wordzParser._lex_consume_wordD  sv    ""$$8y~%%5y==   	9D8  """4ur   c                    |                                  }|j        }|t          j        k    rdS |t          j        k    rdS |t          j        k    rdS dS )z:Peek case terminator (;;, ;&, ;;&). Returns value or None.r  r  r{  N)r  r   r}   r   r   r   r  s      r   _lex_peek_case_terminatorz Parser._lex_peek_case_terminatorR  sX    ""$$H	###4	"""4	'''5tr   c                "    | j         | j        k    S )z(Check if we've reached the end of input.rn  r   s    r   ro  zParser.at_end^  rp  r   c                R    |                                  rdS | j        | j                 S rf  ro  rO  r
   r   s    r   rh  zParser.peekb  s&    ;;== 	4{48$$r   c                v    |                                  rdS | j        | j                 }| xj        dz  c_        |S rj  r  r   r  s     r   rl  zParser.advanceh  s9    ;;== 	4["A	r   offsetc                V    | j         |z   }|dk     s|| j        k    rdS | j        |         S )zwPeek at character at offset from current position.

        Returns empty string if position is out of bounds.
        r   ru   rg  r   r  r
   s      r   peek_atzParser.peek_atp  s7    
 h77cT[((2{3r   r@   c                H    t          | j        | j        | j        |z             S rr  rs  rt  s     r   ru  zParser.lookaheadz  rv  r   c                    | j         dz   | j        k    rdS | j        | j         dz            }|dk    r|dk    rdS | j        | j         dz            dk    S )zLCheck if ! at current position is followed by >( or <( process substitution.rg   Fre   r  r  r  rg  )r   	next_chars     r   _is_bang_followed_by_procsubz#Parser._is_bang_followed_by_procsub~  s^    8a<4;&&5K1-		S 0 05{48a<(C//r   c                   |                                  s|                                  |                                  rdS |                                 }|dk    r|                                  nJ|dk    rB|                     d          dk    r)|                                  |                                  ndS |                                  dS dS )zASkip spaces, tabs, comments, and backslash-newline continuations.r  rD   re   rO   N)ro  r  rh  r  r  rl  r  s     r   skip_whitespacezParser.skip_whitespace  s    ++-- 	!!###{{}} BSyy&&((((tQ4 7 7 ++-- 	 	 	 	 	r   c                   |                                  sT|                                 }t          |          r]|                                  |dk    rB|                                  | j        dk    r#| j        | j        k    r| j        | _        d| _        n|dk    rm|                                  sX|                                 dk    r@|                                  |                                  s|                                 dk    @nJ|dk    rB|                     d          dk    r)|                                  |                                  ndS |                                  RdS dS )zKSkip spaces, tabs, newlines, comments, and backslash-newline continuations.rO   rH   r  rD   re   N)ro  rh  rP   rl  _gather_heredoc_bodiesr  r
   r  r  s     r   skip_whitespace_and_newlinesz#Parser.skip_whitespace_and_newlines  sJ   ++-- 	Bb!! :://111/255$:RUYU]:]:]#'#;350s++-- #DIIKK4,?,?LLNNN ++-- #DIIKK4,?,?tQ4 7 7) ++-- 	 	 	 	 	r   c                    |                                  rdS |                                 }| j        || j        k    rdS |dk    rdS |dk    r1| j        dz   }|| j        k    rdS t          | j        |                   S dS )a  Check if we're at a bracket that terminates a list (closing subshell or brace group).

        Returns True for ')' always (since it's a metachar).
        Returns True for '}' only if it's standalone (followed by word-end context or EOF).
        This handles cases like 'a&}}' where '}}' is a word, not a brace-group closer.
        Also returns True if we're at the EOF token (for funsub parsing).
        FNTr   r  re   )ro  rh  rY  r
   rR  r~  rO  )r   r  next_poss      r   _at_list_terminating_bracketz#Parser._at_list_terminating_bracket  s     ;;== 	5YY[[?&2+@+@499499x!|H4;&&t'H(=>>>ur   c                    | j         dS |                                 }| j         dk    r|j        t          j        k    S | j         dk    r |j        t          j        k    o
|j        dk    S dS )z;Check if next token is the EOF token (grammar-level check).NFr   r  )rY  r  r   r}   r   r   r   r  s     r   _at_eof_tokenzParser._at_eof_token  sj    ?"5""$$?c!!8y///?c!!8y~-B#)s2BBur   r   c                    g }	 |                                   |                                 }|n|                    |           A|r|ndS )z4Collect trailing redirects after a compound command.TN)r  parse_redirectrw   )r   r  r  s      r   _collect_redirectszParser._collect_redirects  sb    		'  """**,,HX&&&	' &/yy4/r   contextr  c                n   |                                  dk    rH|                                 }|+t          d| |                                 j                  |j        S |                     d          r|                     dh          }|(t          d|                                 j                  |                                  |                     d          s+t          d| |                                 j                  |S t          d	| |                                 j                  )
z<Parse a loop body that can be either do/done or brace group.r  NzExpected brace group body in r  rl  rm  Expected commands after 'do'zExpected 'done' to close zExpected 'do' or '{' in )	rh  parse_brace_groupr   r  r
   r  r  parse_list_untilr  )r   r  r  r  s       r   _parse_loop_bodyzParser._parse_loop_body  sH   99;;#**,,E} =G==4CWCWCYCYC]    :!!$'' 		((&22D| !?TEYEYE[E[E_````--///))&11  999t?S?S?U?U?Y    K>W>>DDXDXDZDZD^____r   c                   | j         }|                                  |                                 s!t          |                                           r	|| _         dS g }|                                 s>t          |                                           s|                                 }t          |          rn|dk    r-| j         dz   | j        k     r| j        | j         dz            dk    rn|dk    rb| j         dz   | j        k     rO|                    | 	                                           |                    | 	                                           |                    | 	                                           |                                 s"t          |                                           |rd
                    |          }nd}|| _         |S )z+Peek at the next word without consuming it.NrD   re   rO   ru   )r
   r  ro  r  rh  ri  rR  rO  rw   rl  rx   )r   r  r  r  r   s        r   	peek_wordzParser.peek_word  s   H	;;== 	L55 	 DH4++-- 	)TYY[[(A(A 	)B}} TzzdhlT[88T[TU=VZ^=^=^TzzdhlT[88T\\^^,,,T\\^^,,,LL((( ++-- 	)TYY[[(A(A 	)  	775>>DDDr   c                   | j         }|                                  |                                 }|}d}|2| j        r+t	          |          dk    r|d         dk    r|dd         }d}||k    r	|| _         dS |                                  |r|                                  |D ]}|                                  |                                 dk    r| j         dz   | j        k     r| j        | j         dz            dk    rl|                                  |                                  |                                 dk    r,| j         dz   | j        k     r| j        | j         dz            dk    ldS )	zTry to consume a specific word. Returns True if successful.

        Note: This is kept for edge cases (process sub leading }, variable names).
        Most reserved word consumption has been migrated to _lex_consume_word().
        FNre   r   r  TrD   rO   )	r
   r  r   r  r   rl  rh  rR  rO  )r   r  r  r   keyword_wordhas_leading_bracer  s          r   consume_wordzParser.consume_word  su    H	~~ ! 4TQ4PQ7VY>>8L $8## DH5 	 	LLNNN 	 	ALLNNNN IIKK4DHqL4;$>$>4;txZ[|C\`dCdCdLLNNNLLNNN IIKK4DHqL4;$>$>4;txZ[|C\`dCdCd tr   r   r9  r  r2  r0  c                d    |                                   | j                            ||||          S )r  )r  r  r  r  s        r   r  zParser._is_word_terminator9  s2     	{..sB{SSSr   Tr  r  r   rq   r\   r  c                   |                     d           |                                 su|                                 dk    r\|                                 }|dk    r| j        dz   | j        k     r| j        | j        dz            }|r/|dk    r)|                                  |                                  n|                     |                                            |                     |                                            nm|dk    r@|                     ||d          s'|                     |                                            n'|                     |                                            |                                 s|                                 dk    \|                                 rt          d|	          |                     |                                            d
S )zJScan double-quoted string with expansions. Assumes opening quote consumed.rE   rD   re   rO   rf   Tr  r  r  N)	rw   ro  rh  r
   rR  rO  rl  r  r   )r   r  r   r\   r  r#   r  s          r   r  zParser._scan_double_quote@  s    	S++-- 	-DIIKK3$6$6		ADyyTX\DK77TX\2+ 1$LLNNNLLNNNNLL000LL0000c33E5D3QQ 1LL000T\\^^,,, ++-- 	-DIIKK3$6$6 ;;== 	E8eDDDDT\\^^$$$$$r   r  c                   | j         dz   | j        k     r| j        | j         dz            dk    r| j        | j         dz            dk    r|                                 }|d         r8|                    |d                    |                    |d                    dS |                                 }|d         r8|                    |d                    |                    |d                    dS dS | j         dz   | j        k     ro| j        | j         dz            dk    rV|                                 }|d         r8|                    |d                    |                    |d                    dS dS | j         dz   | j        k     ro| j        | j         dz            dk    rV|                                 }|d         r8|                    |d                    |                    |d                    dS dS |                     |          }|d         r8|                    |d                    |                    |d                    dS dS )zGHandle $ expansions. Returns True if expansion parsed, False if bare $.rg   re   r  r   TFr  )r
   rR  rO  r  rw   r  r  r  )r   r  r   r  ry   s        r   r  zParser._parse_dollar_expansionX  s7    HqL4;&&DHqL)S00DHqL)S005577Fay VAY'''VAY'''t5577Fay VAY'''VAY'''t58a<$+%%$+dhl*Cs*J*J6688Fay VAY'''VAY'''t58a<$+%%$+dhl*Cs*J*J5577Fay VAY'''VAY'''t5,,Y77!9 	LL###LL###4ur   r  r  r   c                <    || _         |                     ||          S )zOUnified word parser with context-aware termination. Sets context and delegates.)r\  
parse_word)r   r9  r  r  s       r   _parse_word_internalzParser._parse_word_internal  s"     !/1ABBBr   r  c                `   |                                   |                                 rdS || _        || _        || _        |                                 }|j        t          j        k    rd| _        d| _        d| _        dS | 	                                 d| _        d| _        d| _        |j
        S )zGParse a word token by consuming WORD token with pre-parsed Word object.NF)r  ro  r]  r^  r_  r  r   r}   r   r  r   )r   r  r  r  r  s        r   r	  zParser.parse_word  s     	;;== 	4!1!1"3""$$8y~%%%*D"%*D"&+D#4!&!&"'xr   r
  c                f   |                                  s|                                 dk    rdS | j        }|                                  |                                  s|                                 dk    r	|| _        dS |                                  |                                 }|                     t          j        t          j        z             d| _	        | 
                                }|t                      }|                                  |                                  s|                                 dk    r|                     |           || _        dS |                                  | j        }t          | j        ||          }|                     |           t!          |          |fS )zParse a $(...) command substitution using EOF token mechanism.

        Returns (node, text) where node is CommandSubstitution and text is raw text.
        rf   r  r  r   )ro  rh  r
   rl  r  r  r   r   r   rY  rP  r  r  r  r_   rO  r  )r   r\   r  r[  text_endr  s         r   r  z"Parser._parse_command_substitution  sv   
 ;;== 	DIIKK3..8;;== 	DIIKK3..DH8 ''))(58H8UUVVV oo;''C 	))+++;;== 	DIIKK3..&&u---DH88$+uh77""5)))"3''--r   c                "   |                                   |                                 s,|                                 dk    r|                                  |                                 }|                     t          j        t          j        z             d| _	        | 
                                }|t                      }|                                  |                                 s|                                 dk    r&|                     |           t          d|          |                                  t          | j        || j                  }|                     |           |                                  t'          |d          |fS )zParse brace command substitution ${ cmd; } or ${| cmd; }.

        Called from Lexer when ${ followed by funsub char is detected.
        start is position of $, and we're at the char after {.
        r  r  NrD  r  T)r  )r  ro  rh  rl  r  r  r   r   r   rY  rP  r  r  r  r!   r_   rO  r
   r  r  )r   r\   r  r[  r  s        r   ra  zParser._parse_funsub  sV    	{{}} 	!3!3LLNNN''))(58H8UUVVVoo;''C))+++;;== 	PDIIKK3..&&u---"#COOOO$+udh77""5)))"3d333T99r   r  c                2    t          |j                  dk    S )z.Check if a word is an assignment (name=value).rH   )r  r   )r   r   s     r   _is_assignment_wordzParser._is_assignment_word  s    4:&&",,r   c                T&   |                                  s|                                 dk    rdS | j        }|                                  g }dg}g }d}d}d}|                                  s~|s|                                 dk    rc|r| j        }|}	|	| j        k     r2| j        |	         dk    r!|	dz  }	|	| j        k     r| j        |	         dk    !t          | j        ||	          }
|r|
                    d          n|
}||k    r|
D ],}|                    |           |                    |           -|	| _        | j        | j        k     rT| j        | j                 dk    r>|                    d           |                    d           |                                  d}t          |          dk    r|
                    d          \  }}d	}n|                    |          rt          |          t          |          k    rt          |
          t          |          z
  }|t          |          z   }t          |          D ]8}|                    |
|                    |                    |
|                    9||z   | _        d}t          |          dk    r|
                    d          \  }}d	}n|
D ],}|                    |           |                    |           -|	| _        | j        | j        k     rT| j        | j                 dk    r>|                    d           |                    d           |                                  |                                 }|d
k    r| j        dz   | j        k     r| j        | j        dz            }|dk    r)|                                  |                                  nt          |          rh|                                  |                                 }|                    |           |                    d
           |                    |           n>|                                 }|                    |           |                    |           &|dk    r| j        dz   | j        k     rq| j        | j        dz            dk    rW| j        dz   | j        k     r| j        | j        dz            dk    r|                    |                                            |                    d           |                    |                                            |                    d           |                    |                                            |                    d           |                                  st          |                                           rs|                                 }|                    |           |                    |           |                                  s!t          |                                           s|                                  st          |                                           s|                                 dvr|                                 d
k    r| j        dz   | j        k     r~|                                 }|                    |           |                    |           |                                 }|                    |           |                    |           n|                                 dv r|                                 }|                                 }|                    |           |                    |           |                                  s|                                 |k    r|dk    rV|                                 d
k    r>|                                 }|                    |           |                    |           |                                 }|                    |           |                    |           |                                  s|                                 |k    |                                  s>|                                 }|                    |           |                    |           n>|                                 }|                    |           |                    |           |                                  s8t          |                                           s|                                 dv	|                    |                                            |                    d           |                    |                                            |                    d           d}|                                  sV|                                 dk    r>d	}|                    |                                            |                    d           |                                  st          |                                           rs|                                 }|                    |           |                    |           |                                  s!t          |                                           sg }|                                  s|                                 }t!          |          r=|                                 }|                    |           |                    |           |                                  s|                                 |k    r|                                 }|                    |           |                    |           |                    |           |                                  s|                                 |k    |                                  s>|                                 }|                    |           |                    |           nh|d
k    rd|                                 }|                    |           |                    |           |                                  sS|                                 }|                    |           |                    |           |                    |           |                                  st#          |                                           s|                                 }|                    |           |                    |           |                    |           |                                  s!t#          |                                           n|                                  st#          |                                           s|                                 dk    r|                                 }t!          |          r<|                                 }|                    |           |                    |           |                                  s|                                 |k    r|                                 }|                    |           |                    |           |                    |           |                                  s|                                 |k    |                                  s>|                                 }|                    |           |                    |           n|d
k    r|                                 }|                    |           |                    |           |                                  sS|                                 }|                    |           |                    |           |                    |           nS|                                 }|                    |           |                    |           |                    |           |                                  s:t#          |                                           s|                                 dk    d                    |          }|r|                    ||f           |dk    rm|                                 }|                    |           |                    |           t          |          dk    r|
                    d          \  }}d	}%|                                 }|                    |           |                    |           |                                  s|J|                                 dk    c|                                  rt'          d|          |                                  |                    d           d                    |          }d                    |          }t          |          dk    rjt)          | j        | j        |          \  }}||k    rF|t          | j        ||          z   }| j        dk    r|| _        nt-          | j        |          | _        t/          || j                  }|                                }|t5                      }t7          |          |fS )zParse a `...` command substitution.

        Returns (node, text) where node is CommandSubstitution and text is raw text.
        r  r  Fru   rO   re   rN   r   TrD   r  rg   rw  r  rE   r  rG  r  rH   r  )ro  rh  r
   rl  rR  rO  r_   r  rw   r   r!  rb   r  rM  rZ   rP   ri  r  rx   r   r5  r  maxrO  rW  rP  r  r  ) r   r\   r  
text_charsr  in_heredoc_bodycurrent_heredoc_delimcurrent_heredoc_stripr*  r+  r   
check_liner  r.  end_posrz   r#   r  r  r6  r  delimiter_charsdchr  escrm   r  r  heredoc_startheredoc_endr]  r[  s                                    r   r  z#Parser._parse_backtick_substitution  sA   
 ;;== 	DIIKK3..8 $&U
35 " %++-- ]	"_ ]	"		s8J8J -!X
%,,X1F$1N1NMH ,,X1F$1N1N!$+z8DD2GQT[[...T
!666" . .%,,R000"))"----'DHx$+--$+dh2G42O2O%,,T222"))$///&+O+,,q00GWG[G[\]G^G^D-/D*.**+@AA 'c*ooX[)Y Y G G %(IIJ$?M+c2G.H.HHG"7^^ 3 3%,,T!W555"))$q'2222)G3DH&+O+,,q00GWG[G[\]G^G^D-/D*. # . .%,,R000"))"----'DHx$+--$+dh2G42O2O%,,T222"))$///		A DyyTX\DK77TX\2T>>LLNNNLLNNNN088 *LLNNN"llnnG!((111%%d+++%%g.... B!((,,,%%b))) CxxDHqL4;664;txRS|;TX[;[;[8a<$+--$+dhl2Ks2R2R!((888%%c***!((888%%c***!((888%%c***"kkmm .0I$))++0V0V .!\\^^%,,R000"))"--- #kkmm .0I$))++0V0V .
 !KKMM 2 .tyy{{ ; ; 2 !IIKKt3399;;$..48a<$+3M3M!%B)00444&--b111!%B)00444&--b1111!YY[[E11$(IIKKE!%B)00444&--b111&*kkmm 6		u8L8L#(C<<DIIKK44G4G)-B$1$8$8$<$<$<$.$5$5b$9$9$9%)\\^^ - 4 4R 8 8 8 * 1 1" 5 5 5 '+kkmm 6		u8L8L $(;;== 6%)\\^^ - 4 4R 8 8 8 * 1 1" 5 5 5!%B)00444&--b111? !KKMM 2 .tyy{{ ; ; 2 !IIKKt33< $$T\\^^444!!#&&&$$T\\^^444!!#&&&"
{{}} +););!%J!((888%%c***++-- *,Ediikk,R,R *B!((,,,%%b))) ++-- *,Ediikk,R,R *
 .0{{}} ?<B }} =< $%,,U333"))%000"&++-- 8DIIKK54H4H"&,,..C)00555&--c222+223777	 #'++-- 8DIIKK54H4H
  ${{}} 7&*llnnG)00999&--g666t"llnn%,,S111"))#...#{{}} 8"&,,..C)00555&--c222+223777"&++-- 8TYY[[8Q8Q 8"&,,..C)00555&--c222+223777	 #'++-- 8TYY[[8Q8Q 8 !% <$0$=$= < !%		s 2 2!%B(}} <(, - 4 4U ; ; ; * 1 1% 8 8 8*.++-- !@DIIKK5<P<P*.,,..C$1$8$8$=$=$=$.$5$5c$:$:$:$3$:$:3$?$?$?	 +/++-- !@DIIKK5<P<P
 (,{{}} !?.2llnnG$1$8$8$A$A$A$.$5$5g$>$>$>!#t&*llnn - 4 4S 9 9 9 * 1 1# 6 6 6'+{{}} !@*.,,..C$1$8$8$=$=$=$.$5$5c$:$:$:$3$:$:3$?$?$?&*llnn - 4 4S 9 9 9 * 1 1# 6 6 6 / 6 6s ; ; ;? !% <$0$=$= < !%		s 2 2< GGO44	 E$++Y
,CDDD Dyy\\^^$$R(((!!"%%%'((1,,CSCWCWXYCZCZ@)+@&*O B  $$$b!!!{ ++-- ]	"_ ]	"		s8J8J~ ;;== 	A4%@@@@#wwz""''-((   1$$)BTX'7* *&M; ]**!Jt{M;$W$WW+r11/:D,,/243K[/Y/YD, GT];;;
##%%;''C"3''--r   c                ,   |                                  s!t          |                                           sdS | j        }|                                 }|                                  s|                                 dk    r	|| _        dS |                                  |                                 }| j        }d| _        |                     t          j	                   d| _
        	 |                                 }|t                      }|                                  |                                  s|                                 dk    rt          d|          |                                  | j        }t          | j        ||          }t#          |          }|                     |           || _        t'          ||          |fS # t          $ r}|                     |           || _        |dz   | j        k     r| j        |dz            nd	}	|	d
v r||dz   | _        | j        | j        _        | j                            dd           | j        j        | _        t          | j        || j                  }t#          |          }d|fcY d}~S d}~ww xY w)a1  Parse a <(...) or >(...) process substitution using EOF token mechanism.

        Returns (node, text) where node is ProcessSubstitution and text is raw text.
        If the content can't be parsed as a valid command, returns (None, text) so
        the caller can treat it as literal characters.
        r  r  Tr   NzInvalid process substitutionr  rg   ru   r  )ro  r  rh  r
   rl  r  r  r  r   r   rY  rP  r  r  r   r_   rO  r  r  r  rR  r  r  )
r   r\   r  r  old_in_process_subr[  r  r  r>   content_start_chars
             r   r  z"Parser._parse_process_substitution  s    ;;== 	 1$))++ > > 	8LLNN	;;== 	DIIKK3..DH8 ''))!1#(5666*	//##C{gg --///{{}} L		s 2 2 !?UKKKKLLNNNxHdk5(;;D:4@@D&&u---#5D &y#66<< 	 	 	&&u---#5D  <A19t{;R;RUQY!7!7XZ "W,, qyDH"hDKOK++C555{DHdk5$(;;D:4@@D:+	s    %C"G 
JB6JJJc                2   |                                  s|                                 dk    rdS | j        }|                                  |                     t
          j                   g }	 |                                  |                                  r0|                     t
          j                   t          d|          |                                 dk    rn|| 
                    dd          }|N|                                 dk    rnK|                     t
          j                   t          d	| j                  |                    |           |                                  s|                                 dk    r5|                     t
          j                   t          d
| j                  |                                  t          | j        || j                  }|                     t
          j                   t          |          |fS )zParse an array literal (word1 word2 ...).

        Returns (node, text) where node is Array and text is raw text.
        Called when positioned at the opening '(' after '=' or '+='.
        r  r  TzUnterminated array literalr  r   FNzExpected word in array literalz!Expected ) to close array literal)ro  rh  r
   rl  r  r   r   r  r  r   r	  rw   r_   rO  r  )r   r\   r  r   r  s        r   r  zParser._parse_array_literalN  s    ;;== 	DIIKK3..8(7888	"--///{{}} J!!"2"ABBB !=5IIIIyy{{c!! ??5$//D|99;;#%%!!"2"ABBB !AtxPPPPOOD!!!)	", ;;== 	PDIIKK3...=>>>@dhOOOO$+udh77*9:::X$$r   c                H   |                                  s|                                 dk    rdS | j        }| j        dz   | j        k    s2| j        | j        dz            dk    s| j        | j        dz            dk    rdS |                                  |                                  |                                  | j        }d}d}|                                  sp|dk    ri|                                 }|dk    r|                                  |                                  sX|                                 dk    r@|                                  |                                  s|                                 dk    @|                                  s|                                  n|d	k    r|                                  |                                  s|                                 d
k    r<| j        dz   | j        k     r)|                                  |                                  nA|                                 d	k    r|                                  n(|                                  |                                  n|d
k    r<| j        dz   | j        k     r)|                                  |                                  np|dk    r|dz  }|                                  nP|dk    r.|dk    r| j        }|dz  }|dk    rnL|                                  n|dk    rd}|                                  |                                  s|dk    i|dk    r.|                                  rt          d|          || _        dS |dk    rt          | j        ||          }nt          | j        || j                  }|                                  t          | j        || j                  }	 |                     |          }n# t          $ r || _        Y dS w xY wt          |          |fS )zParse a $((...)) arithmetic expansion with parsed internals.

        Returns (node, text) where node is ArithmeticExpansion and text is raw text.
        Returns (None, "") if this is not arithmetic expansion.
        rf   r  rg   re   r  rH   r   r  rE   rD   r   unexpected EOF looking for `))'r  )ro  rh  r
   rR  rO  rl  r!   r_   _parse_arith_exprr   r  )	r   r\   r3  r3  first_close_posr#   r  r  exprs	            r   r  z"Parser._parse_arithmetic_expansion|  s    ;;== 	DIIKK3..8 HqLDK''{48a<(C//{48a<(C//8!++-- &	EAII		ACxx++-- #DIIKK3,>,>LLNNN ++-- #DIIKK3,>,>{{}} #LLNNNc++-- 'yy{{d**tx!|dk/I/I++ ++-- ' dtx!|dk99c
cA::&*hO
A::A::&(OM ++-- &	EAIIN A::{{}} U&'HeTTTTDH8b   m_MMGG mTXFFG$+udh77	))'22DD 	 	 	DH88	 #4(($..s   %O; ;PPr  r  c                z   | j         }| j        }| j        }| j        }|                     t
          j                   || _         d| _        t          |          | _        |                                  | 	                                rd}n| 
                                }|| _        ||| _         || _        || _        |S )z5Parse an arithmetic expression string into AST nodes.r   N)r  r  r  rT  r  r   r   r   _arith_skip_ws_arith_at_end_arith_parse_comma)r   r  saved_arith_srcsaved_arith_possaved_arith_lensaved_parser_statery   s          r   r$  zParser._parse_arith_expr  s     ///!/(2333& "7|| 	/FF,,..F 0&-DO-DO-DOr   c                "    | j         | j        k    S r   )r  r  r   s    r   r)  zParser._arith_at_end  s    $/11r   c                J    | j         |z   }|| j        k    rdS | j        |         S r  )r  r  r  r  s      r   _arith_peekzParser._arith_peek  s-    o&$/!!2s##r   c                v    |                                  rdS | j        | j                 }| xj        dz  c_        |S )Nru   re   )r)  r  r  rk  s     r   _arith_advancezParser._arith_advance  s>     	2ODO,1r   c                H   |                                  s| j        | j                 }t          |          r| xj        dz  c_        nE|dk    r=| j        dz   | j        k     r*| j        | j        dz            dk    r| xj        dz  c_        nd S |                                  d S d S )Nre   rD   rO   rg   )r)  r  r  rP   r  rk  s     r   r(  zParser._arith_skip_ws  s    $$&& 	0Aa   
1$T		Oa'$/99ODOa$78D@@ 1$ $$&& 	 	 	 	 	r   rQ   c                8    t          | j        | j        |          S )z9Check if the next characters match s (without consuming).)rc   r  r  r   rQ   s     r   _arith_matchzParser._arith_match  s    tCCCr   c                n    |                      |          r| xj        t          |          z  c_        dS dS )z4If next chars match s, consume them and return True.TF)r7  r  r   r6  s     r   _arith_consumezParser._arith_consume  s8    Q 	OOs1vv%OO4ur   c                    |                                  }	 |                                  |                     d          r9|                                  |                                  }t          ||          }nnd|S )z,Parse comma expressions (lowest precedence).Tr,  )_arith_parse_assignr(  r9  r  r  s      r   r*  zParser._arith_parse_comma&  s    ''))	!!!""3'' ##%%%0022!$..	 r   c                t   |                                  }|                                  g d}|D ]}|                     |          rq|dk    r|                     d          dk    r nQ|                     |           |                                  |                                 }t          |||          c S |S )z1Parse assignment expressions (right associative).)<<=>>=z+=z-=z*=z/=z%=z&=z^=z|=r  r  re   )_arith_parse_ternaryr(  r7  r1  r9  r;  r  )r   r  
assign_opsr  r  s        r   r;  zParser._arith_parse_assign3  s    ((**XXX
 	4 	4B  $$ 499!1!1!!4!4!;!;E##B'''##%%%0022"2tU333334 r   c                (   |                                  }|                                  |                     d          r|                                  |                     d          rd}n|                                 }|                                  |                     d          rX|                                  |                                 s|                                 dk    rd}n|                                 }nd}t          |||          S |S )z.Parse ternary conditional (right associative).rF   r  Nr   )	_arith_parse_logical_orr(  r9  r7  r;  r)  r1  r?  r  )r   r  r  r  s       r   r?  zParser._arith_parse_ternaryD  s   ++--s## 	9!!!  %% 52244!!!""3''  ##%%%%%'' ;4+;+;+=+=+D+D#HH#88::HHgx888r   opsparsefnCallable[[], Node]c                    |            }	 |                                   d}|D ]]}|                     |          rF|                     |           |                                   t          || |                      }d} n^|snz|S )z<Parse left-associative binary operators using match/consume.TF)r(  r7  r9  r  )r   rC  rD  r  matchedr  s         r   _arith_parse_left_assoczParser._arith_parse_left_assoc]  s    wyy	!!!G  $$R(( ''+++'')))(T7799==D"GE  	 r   c                :    |                      dg| j                  S )zParse logical or (||).r  )rH  _arith_parse_logical_andr   s    r   rB  zParser._arith_parse_logical_orn  s    ++TFD4QRRRr   c                :    |                      dg| j                  S )zParse logical and (&&).r  )rH  _arith_parse_bitwise_orr   s    r   rJ  zParser._arith_parse_logical_andr  s    ++TFD4PQQQr   c                   |                                  }	 |                                  |                                 dk    r|                     d          dk    rg|                     d          dk    rN|                                  |                                  |                                  }t	          d||          }nn|S )zParse bitwise or (|).Tr  re   r  )_arith_parse_bitwise_xorr(  r1  r3  r  r  s      r   rL  zParser._arith_parse_bitwise_orv  s    ,,..	!!!!!S((  ##s**t/?/?/B/Bc/I/I##%%%##%%%5577$S$66	 r   c                Z   |                                  }	 |                                  |                                 dk    rg|                     d          dk    rN|                                  |                                  |                                  }t	          d||          }nn|S )zParse bitwise xor (^).Tr  re   r  )_arith_parse_bitwise_andr(  r1  r3  r  r  s      r   rN  zParser._arith_parse_bitwise_xor  s    ,,..		!!!!!S((T-=-=a-@-@C-G-G##%%%##%%%5577$S$66		 r   c                   |                                  }	 |                                  |                                 dk    r|                     d          dk    rg|                     d          dk    rN|                                  |                                  |                                  }t	          d||          }nn|S )zParse bitwise and (&).Tr  re   r  )_arith_parse_equalityr(  r1  r3  r  r  s      r   rP  zParser._arith_parse_bitwise_and  s    ))++	!!!!!S((  ##s**t/?/?/B/Bc/I/I##%%%##%%%2244$S$66	 r   c                <    |                      ddg| j                  S )zParse equality (== !=).r^  r]  )rH  _arith_parse_comparisonr   s    r   rR  zParser._arith_parse_equality  s    ++T4L$:VWWWr   c                R   |                                  }	 |                                  |                     d          rP|                     d           |                                  |                                  }t	          d||          }n|                     d          rP|                     d           |                                  |                                  }t	          d||          }n1|                                 dk    r|                     d          dk    rg|                     d          dk    rN|                                  |                                  |                                  }t	          d||          }n|                                 dk    r|                     d          dk    rg|                     d          dk    rN|                                  |                                  |                                  }t	          d||          }nn|S )zParse comparison (< > <= >=).Tz<=z>=r  re   r  r  )_arith_parse_shiftr(  r7  r9  r  r1  r3  r  s      r   rT  zParser._arith_parse_comparison  s   &&((	!!!  && ##D)))##%%%//11$T477""4(( ##D)))##%%%//11$T477!!##s**  ##s**t/?/?/B/Bc/I/I##%%%##%%%//11$S$66!!##s**  ##s**t/?/?/B/Bc/I/I##%%%##%%%//11$S$667	8 r   c                F   |                                  }	 |                                  |                     d          rn|                     d          rn|                     d          rO|                     d           |                                  |                                  }t	          d||          }ne|                     d          rO|                     d           |                                  |                                  }t	          d||          }nn|S )zParse shift (<< >>).Tr=  r>  r  r  )_arith_parse_additiver(  r7  r9  r  r  s      r   rV  zParser._arith_parse_shift  s+   ))++	!!!  ''   ''   && ##D)))##%%%2244$T477""4(( ##D)))##%%%2244$T477#	$ r   c                .   |                                  }	 |                                  |                                 }|                     d          }|dk    rZ|dk    rT|dk    rN|                                  |                                  |                                  }t	          d||          }na|dk    rZ|dk    rT|dk    rN|                                  |                                  |                                  }t	          d||          }nn|S )z%Parse addition and subtraction (+ -).Tre   r  r  r  )_arith_parse_multiplicativer(  r1  r3  r  r   r  r#   c2r  s        r   rX  zParser._arith_parse_additive  s   //11	!!!  ""A!!!$$BCxxR3YY299##%%%##%%%88::$S$66crSyyR3YY##%%%##%%%88::$S$66	  r   c                   |                                  }	 |                                  |                                 }|                     d          }|dk    rZ|dk    rT|dk    rN|                                  |                                  |                                  }t	          d||          }n|dk    rT|dk    rN|                                  |                                  |                                  }t	          d||          }n[|dk    rT|dk    rN|                                  |                                  |                                  }t	          d||          }nnT|S )z/Parse multiplication, division, modulo (* / %).Tre   r  r  r!  r(  )_arith_parse_exponentiationr(  r1  r3  r  r[  s        r   rZ  z"Parser._arith_parse_multiplicative  sp   //11	!!!  ""A!!!$$BCxxR3YY299##%%%##%%%88::$S$66cbCii##%%%##%%%88::$S$66cbCii##%%%##%%%88::$S$66)	* r   c                   |                                  }|                                  |                     d          rN|                     d           |                                  |                                 }t          d||          S |S )z.Parse exponentiation (**) - right associative.z**)_arith_parse_unaryr(  r7  r9  r^  r  r  s      r   r^  z"Parser._arith_parse_exponentiation   s    &&((T"" 	4%%%!!!4466E tU333r   c                   |                                   |                     d          rL|                     d           |                                   |                                 }t	          |          S |                     d          rL|                     d           |                                   |                                 }t          |          S |                                 }|dk    rL|                                  |                                   |                                 }t          d|          S |dk    rL|                                  |                                   |                                 }t          d|          S |dk    re|                     d          dk    rL|                                  |                                   |                                 }t          d|          S |dk    re|                     d          dk    rL|                                  |                                   |                                 }t          d|          S | 	                                S )z&Parse unary operators (! ~ + - ++ --).++--rE  ~r  re   r  )
r(  r7  r9  r`  r  r  r1  r3  r  _arith_parse_postfix)r   r  r#   s      r   r`  zParser._arith_parse_unary   sU   T"" 	)%%%!!!--//G(((T"" 	)%%%!!!--//G(((88!!!!!!--//GW---88!!!!!!--//GW---88((++s22!!!!!!--//GW---88((++s22!!!!!!--//GW---((***r   c                   |                                  }	 |                                  |                     d          r%|                     d           t	          |          }n|                     d          r%|                     d           t          |          }n|                                 dk    r|j        dk    r|                                  |                                  | 	                                }|                                  |                     d          st          d| j                  t          |j        |          }nnn@|S )	z#Parse postfix operators (++ -- []).Trb  rc  r  r  r  zExpected ']' in array subscriptr  )_arith_parse_primaryr(  r7  r9  r  r  r1  r.  r3  r*  r   r  r  rA  )r   r  r  s      r   re  zParser._arith_parse_postfixC   s[   ((**	!!!  && ##D)))$T**""4(( ##D)))$T**!!##s**9%%'')))''))) 3355E'')))..s33 a()JPTP_````)$)U;;DD+	, r   c                   |                                   |                                 }|dk    r}|                                  |                                   |                                 }|                                   |                     d          st          d| j                  |S |dk    rA|                     d          dk    r(|                                  |                                 S |dk    r|                                 S |dk    r|                                 S |d	k    r| 	                                S |d
k    r| 
                                S |dk    ra|                                  |                                 rt          d| j                  |                                 }t          |          S |                                 s|dv rt                      S |                                 S )zCParse primary expressions (numbers, variables, parens, expansions).r  r   z%Expected ')' in arithmetic expressionr  r  re   rf   r  rE   r  rD   z,Unexpected end after backslash in arithmeticz)]:,;?|&<>=!+-*/%^~#{})r(  r1  r3  r*  r9  r   r  _arith_parse_expansion_arith_parse_single_quote_arith_parse_double_quote_arith_parse_backtickr)  r  rM  _arith_parse_number_or_var)r   r#   r&  escaped_chars       r   rg  zParser._arith_parse_primary^   s    88!!!!!!**,,D!!!&&s++ _ !Hdo^^^^K 88((++s22!!!..000 88..000 8811333 8811333 88--/// 99!!!!!##  B     ..00L|,,,
  	 1(@#@#@<< ..000r   c                   |                      d          st          d| j                  |                                 }|dk    r|                                 S |dk    r|                                 S g }|                                 s|                                 }|                                s|dk    r(|                    | 	                                           n@t          |          s|dk    r*|s(|                    | 	                                           nn|                                 |st          d| j                  t          d	                    |                    S )
zParse $var, ${...}, or $(...).rf   zExpected '$'r  r  r  r  r  zExpected variable name after $ru   )r9  r   r  r1  _arith_parse_cmdsub_arith_parse_braced_paramr)  r  rw   r3  r  r?  rx   )r   r#   r9  r  s       r   ri  zParser._arith_parse_expansion   ss   ""3'' 	B^AAAA 88++--- 8811333 
$$&& 		!!##Bzz|| rSyy!!$"5"5"7"78888,R00 B#IIzI!!$"5"5"7"7888 $$&& 		  	T=4?SSSSbggj11222r   c                   |                                   |                                 dk    r@|                                   d}| j        }|                                 s|dk    r|                                 }|dk    r|dz  }|                                   nT|dk    r:|dk    r|                     d          dk    rnH|dz  }|                                   n|                                   |                                 s|dk    t	          | j        || j                  }|                                   |                                   |                     |          }t          |          S d}| j        }|                                 s|dk    r|                                 }|dk    r|dz  }|                                   n;|dk    r!|dz  }|dk    rnC|                                   n|                                   |                                 s|dk    t	          | j        || j                  }|                                   t          || j	                  }|
                                }t          |          S )z4Parse $(...) command substitution inside arithmetic.r  re   r   r   r  )r3  r1  r  r)  r_   r  r$  r  rO  rW  rP  r  )r   r3  r3  r  r  
inner_exprr]  r[  s           r   rp  zParser._arith_parse_cmdsub   s    	 $$!!!E OM((** *uqyy%%''99QJE''))))3YYzzd&6&6q&9&9S&@&@QJE''))))''))) ((** *uqyy !-QQG!!!!!!//88J&z222 $$&& 	&5199!!##BSyy
##%%%%s
A::##%%%%##%%% $$&& 	&5199 T_mT_MM GT];;;
##%%"3'''r   c                (   |                                   |                                 dk    r|                                   g }|                                 sk|                                 dk    rS|                    |                                             |                                 s|                                 dk    S|                     d           t          d                    |                    S |                                 dk    r|                                   g }|                                 sk|                                 dk    rS|                    |                                             |                                 s|                                 dk    S|                     d           t          d                    |                    S g }|                                 s|                                 }|dk    r6|                                   t          d                    |                    S t          |          rn;|                    |                                             |                                 d                    |          }g }d}|                                 s|dk    r|                                 }|dk    r-|dz  }|                    |                                             na|dk    r4|dz  }|dk    rni|                    |                                             n'|                    |                                             |                                 s|dk    |                     d           d                    |          }|
                    d          r-t          |dt          |d	t          |                              S |
                    d
          r-t          |d
t          |d	t          |                              S |
                    d          r-t          |dt          |d	t          |                              S |
                    d          r-t          |dt          |d	t          |                              S |
                    d          r-t          |dt          |dt          |                              S |
                    d          r-t          |dt          |d	t          |                              S |
                    d          r-t          |dt          |dt          |                              S |
                    d          r-t          |dt          |d	t          |                              S |
                    d          r-t          |dt          |dt          |                              S |
                    d          r-t          |dt          |d	t          |                              S |
                    d          r-t          |dt          |dt          |                              S t          |d|          S )z3Parse ${...} parameter expansion inside arithmetic.rE  r  ru   r  re   r   r  z:-rg   z:=z:+z:?r  r'  r)  r(  r*  r!  )r3  r1  r)  rw   r9  rK  rx   rJ  r?  r  rb   r_   r   )r   r9  r  rA  op_charsr3  op_strs          r   rq  z Parser._arith_parse_braced_param   s$    $$!!!J((** 9t/?/?/A/AS/H/H!!$"5"5"7"7888 ((** 9t/?/?/A/AS/H/H$$$ !4!4555 $$!!!J((** 9t/?/?/A/AS/H/H!!$"5"5"7"7888 ((** 9t/?/?/A/AS/H/H$$$rwwz22333 
$$&& 	5!!##BSyy##%%%%bggj&9&9:::%b)) d1133444 $$&& 	5 wwz"" $$&& 	75199!!##BSyy
 3 3 5 56666s
A:: 3 3 5 56666 3 3 5 5666 $$&& 	75199 	C   "" T"" 	R!$jCKK.P.PQQQT"" 	R!$jCKK.P.PQQQT"" 	R!$jCKK.P.PQQQT"" 	R!$jCKK.P.PQQQS!! 	Q!$Z3v;;-O-OPPPT"" 	R!$jCKK.P.PQQQS!! 	Q!$Z3v;;-O-OPPPT"" 	R!$jCKK.P.PQQQS!! 	Q!$Z3v;;-O-OPPPT"" 	R!$jCKK.P.PQQQS!! 	Q!$Z3v;;-O-OPPPdB///r   c                   |                                   | j        }|                                 sX|                                 dk    r@|                                   |                                 s|                                 dk    @t	          | j        || j                  }|                     d          st          d| j                  t          |          S )zCParse '...' inside arithmetic - returns content as a number/string.r  z'Unterminated single quote in arithmeticr  	r3  r  r)  r1  r_   r  r9  r   rH  )r   r3  r  s      r   rj  z Parser._arith_parse_single_quote8!  s    $$&& 	"4+;+;+=+=+D+D!!! $$&& 	"4+;+;+=+=+D+DT_mT_MM""3'' 	]FDO\\\\7###r   c                h   |                                   | j        }|                                 s|                                 dk    r|                                 }|dk    r=|                                 s)|                                   |                                   n|                                   |                                 s|                                 dk    t	          | j        || j                  }|                     d          st          d| j                  t          |          S )z7Parse "..." inside arithmetic - may contain expansions.rE   rD   z'Unterminated double quote in arithmeticr  rx  )r   r3  r#   r  s       r   rk  z Parser._arith_parse_double_quoteC!  s&   $$&& 	&4+;+;+=+=+D+D  ""ADyy!3!3!5!5y##%%%##%%%%##%%% $$&& 	&4+;+;+=+=+D+D T_mT_MM""3'' 	]FDO\\\\7###r   c                   |                                   | j        }|                                 s|                                 dk    r|                                 }|dk    r=|                                 s)|                                   |                                   n|                                   |                                 s|                                 dk    t	          | j        || j                  }|                     d          st          d| j                  t          || j	                  }|
                                }t          |          S )z3Parse `...` command substitution inside arithmetic.r  rD   z#Unterminated backtick in arithmeticr  r  )r3  r  r)  r1  r_   r  r9  r   rO  rW  rP  r  )r   r3  r#   r  r]  r[  s         r   rl  zParser._arith_parse_backtickS!  sK   $$&& 	&4+;+;+=+=+D+D  ""ADyy!3!3!5!5y##%%%##%%%%##%%% $$&& 	&4+;+;+=+=+D+D T_mT_MM""3'' 	YBXXXXGT];;;
##%%"3'''r   c                <   |                                   g }|                                 }|                                r|                                 sq|                                 }|                                s|dk    s|dk    r(|                    |                                            nn|                                 qd                    |          }|                                 sJ|                                 dk    r2|                                 }t          t          |          |g          S t          |          S |                                s|dk    r|                                 sk|                                 }|                                s|dk    r(|                    |                                            nn|                                 kt          d                    |                    S t          d|z   dz   | j                  )z Parse a number or variable name.r  r  ru   rf   zUnexpected character 'z' in arithmetic expressionr  )r(  r1  r7  r)  r  rw   r3  rx   ri  r  rH  r8  rQ  r   r  )r   r  r#   r  r`   	expansions         r   rm  z!Parser._arith_parse_number_or_varf!  s    99;; 	'((** %%''::<< B#IIsLL!4!4!6!67777 ((**  WWU^^F%%'' ED,<,<,>,>#,E,E 7799	"K$7$7#CDDDv&&& 99;; 	,!s((((** %%''::<< 299LL!4!4!6!67777 ((**  BGGENN+++$q(+GGT_
 
 
 	
r   c                    |                                  s|                                 dk    rdS | j        }| j        dz   | j        k    s| j        | j        dz            dk    rdS |                                  |                                  | j        | j        _        | j                            ddt          j	                  }| j        j        | _        t          | j        || j                  }t          |          |fS )zParse a deprecated $[expr] arithmetic expansion.

        Returns (node, text) where node is ArithDeprecated and text is raw text.
        rf   r  re   r  r  )ro  rh  r
   rR  rO  rl  r  r  r  r  r_   r  )r   r\   r  r  s       r   r  z#Parser._parse_deprecated_arithmetic!  s    
 ;;== 	DIIKK3..8 8a<4;&&$+dhl*Cs*J*J8 (+11#s<L<RSS;?$+udh77w''--r   c                    |                                   | j                            |          }|                                  |S )z>Parse a parameter expansion starting at $. Delegates to Lexer.)r  r  rB  r  )r   r  ry   s      r   r  zParser._parse_param_expansion!  s@    229==r   Redirect | HereDoc | Nonec                   |                                   |                                 rdS | j        }d}d}|                                 dk    r| j        }|                                  g }d}|                                 sRt          |                                           s0|                                 }|dk    r|sn|dk    r*d}|                    |                                            n|d	k    r*d}|                    |                                            n||                                s|d
k    r(|                    |                                            n:|r7t          |          s(|                    |                                            nn6|                                 s"t          |                                           0d	                    |          }d}	|r
|d         
                                s|d         d
k    rd|v sd	|v r|                    d          }
|                    d	          }|
dk    r~|t          |          dz
  k    rh||
dz   k    r_|d|
         }|rS|d         
                                s|d         d
k    r-d}	|dd         D ] }|                                s
|d
k    sd}	 n!n-d}	|dd         D ] }|                                s
|d
k    sd}	 n!|                                 s1|                                 dk    r|	r|                                  |}n|| _        |dk    r|                                 r|                                                                 rg }|                                 s|                                                                 ra|                    |                                            |                                 s&|                                                                 at          d	                    |                    }|                                 }|dk    r| j        dz   | j        k     r| j        | j        dz            dk    r|dk    s|dk    r	|| _        dS |                                  |                                  |                                 s/|                                 dk    r|                                  d}nd}|                                   |                                 }|t'          d|z   | j                  t)          ||          S |t          |          s	|| _        dS |dk    r5| j        dz   | j        k     r"| j        | j        dz            dk    r	|| _        dS |                                 }d}|                                 s|                                 }|dk    r|dk    r|                                  d}n|dk    r|dk    r|                                  |                                 s0|                                 dk    r|                                  d}nW|                                 s2|                                 dk    r|                                  d}d}nd}n|dk    r|dk    r|                                  d}n|dk    r|dk    r|                                  d}n|dk    r^|dk    rX|dk    rR|dk    rL| j        dz   | j        k    s"t+          | j        | j        dz                      s|                                  d}nc|dk    r]|dk    rW|dk    rQ|dk    rK| j        dz   | j        k    s"t+          | j        | j        dz                      s|                                  d}|dk    r|                     ||          S |dk    rd|z   dz   |z   }n|dk    rt/          |          |z   }|                                 s!|                                 dk    r|                                  |                                   |                                 st|                                 dk    r\| j        dz   | j        k     rFt          | j        | j        dz                      s$|                                  t1          d          }nd}nd}|R|                                 s|                                                                 s|                                 dk    r| j        }g }|                                 s|                                                                 ra|                    |                                            |                                 s&|                                                                 a|rd	                    |          }nd}|                                 s/|                                 dk    r||                                 z  }|dk    r|                                 s|t          |                                           s[|| _        |                                 }|%t1          d|j        z             }|j        |_        nGt'          d|z   | j                  t1          d|z             }n|                                 }|$t1          d|j        z             }|j        |_        nt'          d|z   | j                  n|                                   |dv r|                                 s|                                 dk    rn| j        dz   | j        k     rFt          | j        | j        dz                      s$|                                  t1          d          }n)|                                 }n|                                 }|t'          d|z   | j                  t)          ||          S ) z(Parse a redirection operator and target.NrH   ru   r  Fr  r  Tr  r  r   re   r  r  r~  r  zExpected target for redirect r  r  r  r  r}  r  r  r  r  r  r  r  r  )r  r  )r  ro  r
   rh  rl  r  rw   r  r  rx   r8  r  r  r   r7  r   rR  rO  r	  r   r  r  _parse_heredocr	   r  r   r   )r   r\   r  varfdr  varname_chars
in_bracketr  varnameis_valid_varfdr  r  r  r#   fd_charsr  r  r  r  
word_startr  
inner_words                         r   r  zParser.parse_redirect!  sq   ;;== 	4 99;;#HELLNNNMJkkmm ,=diikk,J,J YY[[99Z93YY!%J!((88883YY!&J!((8888ZZ\\ R3YY!((8888 R(8(8 !((8888 kkmm ,=diikk,J,J   ggm,,G"N &1:%%'' &71:+<+<g~~&||C00 'c 2 22::%3w<<!3C*C*CPTWXPXHXHX#*5D5>D# .a):): .d1gnn15)-abb !. !.A,-IIKK %.1889>(-)-!( & &A$%IIKK &18816 %;;== !TYY[[C%7%7N%7 ! B;;499;;;499;;+>+>+@+@;Hkkmm 0		(;(;(=(= 0/// kkmm 0		(;(;(=(= 0RWWX&&''BYY[[ 99A33DHqL8QUX8X8XRxx5B;; !tLLNNNLLNNN;;== TYY[[C%7%7  """__&&F~ !@2!E48TTTTB''':.r22:DH4 881t{22t{48a<7PTW7W7WDH4 \\^^ 
{{}} #	iikkGSyyW^^sw#~~{{}} ););LLNNNBB 499;;#+=+=LLNNNB!%JJBBsw#~~sw#~~ rerkkbCiiGsNN8a<4;..6GTXT\_`T`Ha6b6b.LLNNNBrerkkbCiiGsNN8a<4;..6GTXT\_`T`Ha6b6b.LLNNNB ::&&r:666 B;;us"R'BB2XXR2B {{}} >	+!3!3LLNNN  """;;== 	TYY[[C%7%78a<$+--l4;txZ[|C\6]6]-LLNNN!$ZZFF "FF~{{}} ]$))++*=*=*?*? ]499;;RUCUCU!%J!H"kkmm 8		0C0C0E0E 8 777 #kkmm 8		0C0C0E0E 8 '$&GGH$5$5		$&	;;== 4TYY[[C-?-?!T\\^^3	 !C'''lSWS\S\S^S^F_F_'#-%)__%6%6
%1%)#
0@*@%A%AF+5+;FLL",-Lr-QW[W_"`"`"``!%cIo!6!6 "&!2!2J!-!%cJ,<&<!=!='1'7()H2)MSWS[\\\\A D   """ \!!$++--!DIIKK3<N<N8a<$+--l4;txZ[|C\6]6]-LLNNN!$ZZFF!__..FF**><rAtxPPPPF###r   r  c                   |                                   d}g }	 |                                 sdt          |                                           sB|                                 }|dk    rd}|                                  |                                 sk|                                 dk    rS|                    |                                            |                                 s|                                 dk    S|                                 s|                                  n3|dk    rd}|                                  |                                 sz|                                 dk    rb|                                 }|dk    rd| _        |                    |           |                                 s|                                 dk    b|                                 s|                                  n_|dk    r|                                  |                                 sY|                                 }|dk    r|                                  nd}|                    |                                            
n|dk    r| j        dz   | j        k     r| j	        | j        dz            dk    rd}|                                  |                                  |                                 sd|                                 dk    rK|                                 }|dk    r| j        dz   | j        k     r|                                  |                                 }t          |          }|d	k    r7|                    t          |                     |                                  n}|dk    r(|                    |                                            nO|                    |                                            n'|                    |                                            |                                 s|                                 dk    K|                                 s|                                  nt          | j	        | j        d
          r|                    |                                            |                    |                                            d}|                                 sr|d	k    rl|                                 }|dk    r|dz  }n|dk    r|dz  }|                    |                                            |                                 s|d	k    ln|dk    r| j        dz   | j        k     r| j	        | j        dz            dk    rd	}	| j        dz
  }
|
d	k    r2| j	        |
         dk    r!|	dz  }	|
dz  }
|
d	k    r| j	        |
         dk    !|
d	k    r| j	        |
         dk    r|	dz  }	|	dz  dk    r)|                    |                                            n|                    |                                            |                    |                                            d	}|                                 s|                                 }|dk    r|dz  }nv|dk    rp|                    |                                            |d	k    rn}|dz  }|d	k    r6|                                 s"t          |                                           rn<|                    |                                            |                                 ѐn|dk    r| j        dz   | j        k     r| j	        | j        dz            dk    rjd	}	| j        dz
  }
|
d	k    r2| j	        |
         dk    r!|	dz  }	|
dz  }
|
d	k    r| j	        |
         dk    !|
d	k    r| j	        |
         dk    r|	dz  }	|	dz  dk    r)|                    |                                            n|                    |                                            |                    |                                            d}|                                 sr|d	k    rl|                                 }|dk    r|dz  }n|dk    r|dz  }|                    |                                            |                                 s|d	k    lnD|dk    r|                    |                                            |                                 s|                                 dk    r|                                 }|dk    r+|                    |                                            |                                 s|                                 dk    r|                                 dk    rk|                    |                                            |                                 s0|                                 dk    r|                                 dk    k|                                 s?|                                 dk    r'|                    |                                            n|dk    r||                    |                                            |                                 s|                                 dk    r|                                 dk    r|                                 dk    r:| j        dz   | j        k     r'|                    |                                            |                    |                                            |                                 s0|                                 dk    r|                                 dk    |                                 s?|                                 dk    r'|                    |                                            n|dk    rb| j        dz   | j        k     rO|                    |                                            |                    |                                            n'|                    |                                            |                                 s|                                 dk    |                                 s'|                    |                                            n'|                    |                                            |                                 s"t          |                                           B|                                 s|                                 dv r| j        dz   | j        k     r| j	        | j        dz            dk    r|                    |                                            |                    |                                            d}|                                 sr|d	k    rl|                                 }|dk    r|dz  }n|dk    r|dz  }|                    |                                            |                                 s|d	k    l	 d                    |          |fS )zParse heredoc delimiter, handling quoting (can be mixed like 'EOF'"2").

        Returns (delimiter, quoted) where delimiter is the raw delimiter string
        and quoted is True if any part was quoted (suppresses expansion).
        FTrE   r  rO   rD   rf   re   r   r  r  r   r  rg   r  r  r  r  r  ru   )r  ro  r  rh  rl  rw   r  r
   rR  rO  rK   r  ro   rx   )r   r  r  r  r#   r  r  esc_valr3  rX  rk   s              r   _parse_heredoc_delimiterzParser._parse_heredoc_delimiter"  s    	%'t	kkmm ^;L,E,E ^;YY[[99!FLLNNN"kkmm ?		s0B0B'..t||~~>>> #kkmm ?		s0B0B;;== '3YY!FLLNNN"kkmm 2		s0B0B LLNN99@DD='..q111	 #kkmm 2		s0B0B
  ;;== '4ZZLLNNN;;== C"&))++"d?? LLNNNN &*F+224<<>>BBB3YY48a<$+#=#=$+dhYZlB[_bBbBb!FLLNNNLLNNN"kkmm C		s0B0B IIKK99A)C)C LLNNN"&))++C&6s&;&;G&!|| / 6 6s7|| D D D $!$ / 6 6t||~~ F F F F !0 6 6t||~~ F F F F+224<<>>BBB! #kkmm C		s0B0B"  ;;== '(dhEE h;#**4<<>>:::#**4<<>>:::E"kkmm ?		 IIKK88!QJEE#XX!QJE'..t||~~>>> #kkmm ?		 3YY48a<$+#=#=$+dhYZlB[_bBbBb#$L1Aq&&T[^s%:%:$)Q q&&T[^s%:%: Avv$+a.D"8"8$)#a'1,, (..t||~~>>>> (..t||~~>>>'..t||~~>>> !"&++-- C $		A Cxx %
!"c / 6 6t||~~ F F F#(A::$) %
 $)A::dkkmm:UYU^U^U`U`HaHa:$) (+224<<>>BBB! #'++-- C" 3YY48a<$+#=#=$+dhYZlB[_bBbBb#$L1Aq&&T[^s%:%:$)Q q&&T[^s%:%: Avv$+a.D"8"8$)#a'1,, (..t||~~>>>> (..t||~~>>>'..t||~~>>> !"&++-- CEAII $		A Cxx %
!"c %
+224<<>>BBB #'++-- CEAII 3YY $**4<<>>:::"kkmm C		s0B0B IIKK88+224<<>>BBB&*kkmm G		s8J8Jtyy{{^aOaOa / 6 6t||~~ F F F '+kkmm G		s8J8Jtyy{{^aOaOa#';;== GTYY[[C5G5G / 6 6t||~~ F F F#XX+224<<>>BBB&*kkmm G		s8J8Jtyy{{^aOaOa#'99;;$#6#648a<$+;U;U$3$:$:4<<>>$J$J$J / 6 6t||~~ F F F '+kkmm G		s8J8Jtyy{{^aOaOa $(;;== GTYY[[C5G5G / 6 6t||~~ F F F$YY48a<$++E+E+224<<>>BBB+224<<>>BBBB+224<<>>BBB- #kkmm C		s0B0B.  ;;== ?'..t||~~>>>#**4<<>>:::} kkmm ^;L,E,E ^;D KKMMIIKK4''HqL4;..K1-44  &&t||~~666&&t||~~666++-- ;EAII		ACxx
c
#**4<<>>::: ++-- ;EAII ww''//r   r  tuple[str, int]c                *   | j         }| j         }|| j        k     r2| j        |         dk    r!|dz  }|| j        k     r| j        |         dk    !t          | j        ||          }|s|| j        k     rt	          |          }|dz  dk    rnt          |dt          |          dz
            }|dz  }|}|| j        k     r2| j        |         dk    r!|dz  }|| j        k     r| j        |         dk    !|t          | j        ||          z   }|| j        k     ||fS )a  Read a heredoc line, handling backslash-newline continuation for unquoted heredocs.

        Returns (line_content, line_end_pos) where line_content is the logical line
        (with continuations joined) and line_end_pos is the position after the final newline.
        rO   re   rg   r   )r
   rR  rO  r_   rp  r   )r   r  r*  r+  r   r,  r-  s          r   _read_heredoc_linezParser._read_heredoc_lineO#  sD    X
8$$X)>$)F)FMH $$X)>$)F)F$+z8<< 
	QT[((9$???a''!$3t99q=99A"*,,X1F$1N1NMH ,,X1F$1N1NjoxPPP T[(( X~r   r   rm   r  tuple[bool, str]c                    |r|                     d          n|}t          |          }t          |          }||k    |fS )zCheck if line matches the heredoc delimiter.

        Returns (matches, check_line) where check_line is the line after tab stripping.
        rN   )r  rs  )r   r   rm   r  r  normalized_checknormalized_delims          r   _line_matches_delimiterzParser._line_matches_delimiterg#  sL     +5>T[[&&&$
7
CC7	BB#33Z??r   c                t   | j         D ]'}g }| j        }| j        | j        k     r| j        }|                     |j                  \  }}|                     ||j        |j                  \  }}|r|| j        k     r|dz   n|| _        nt          |          }t          |j                  }	| j	        dk    rU|
                    |	          r@t          |          t          |          z
  }
||
z   t          |j                  z   | _        n
|| j        k    r[|
                    |	          rF| j        r?t          |          t          |          z
  }
||
z   t          |j                  z   | _        n|j        r|                    d          }|| j        k     r#|                    |dz              |dz   | _        nId}|j        st          |          dz  dk    rd}|                    ||rdndz              | j        | _        | j        | j        k     d                    |          |_        )g | _         d	S )
zGather content for all pending heredocs after command line ends.

        Called after a newline is consumed. Reads content for each pending heredoc
        in order, advancing self.pos past all heredoc content.
        re   r   rN   rO   Trg   Fru   N)rV  r
   rR  r  r  r  rm   r  rs  rY  rb   r   r  r  rw   rp  rx   r  )r   r  content_linesr*  r   r+  matchesr  r  r  r.  add_newlines               r   r  zParser._gather_heredoc_bodiess#  sa    - +	5 +	5G')MJ(T[((!X
!%!8!8!H!Hh&*&B&B'+W-?' '#  /7$+/E/Ex!||8DH#?
#K#K #?@Q#R#R  ?c)).>.I.IJZ.[.[)$'IIJ$?M)M9C@Q<R<RRDH ++(334DEE ,, , %(IIJ$?M)M9C@Q<R<RRDH% -;;t,,Ddk))!((555'!|DHH #'K"> ,.I$.O.ORS.SWX.X.X&+!((1L")MNNN#{DHO (T[((P !ggm44GOO!#r   r  r  c                   | j         }|                     t          j                   |                                 \  }}| j        D ];}|j        |k    r.|j        |k    r#|                     t          j                   |c S <t          |d|||d          }||_        | j        
                    |           |                     t          j                   |S )zParse a here document <<DELIM ... DELIM.

        Parses the delimiter only. Content is gathered later by _gather_heredoc_bodies
        after the command line is complete.
        ru   F)r
   r  r   r   r  rV  r  rm   r  r  rw   )r   r  r  r1  rm   r  existingr  s           r   r  zParser._parse_heredoc#  s     H	(4555 99;;	6. 	  	 H"i//H4F)4S4S!!"2">???)RVRGG&%%g...*6777r   Command | Nonec                h   g }g }	 |                                   |                                 rnt          |          dk    r!|                                 }|dk    s|dk    rn|                                 }||                    |           d}|D ]}|                     |          sd} nt          |          dk    o|d         j        t          v }| 	                    | p|ot          |          dk    d|          }|n|                    |           |s|sdS t          ||          S )z<Parse a simple command (sequence of words and redirections).Tr   r  rt  NF)r  r  r  )r  r  r   r  r  rw   r  r   ASSIGNMENT_BUILTINSr	  rI  )	r   rK  r  r  r  all_assignmentsrO  r  r   s	            r   parse_commandzParser.parse_command#  s   	)	  """ ..00 
 5zzQ7799s??h$&6&6 **,,H#  *** #O  //22 &+OE !$E

Q X58>EX3X??%*!W/V3y>>UVCV!&"3 #  D
 |LLS)	V  	Y 	4ui(((r   Subshell | Nonec                   |                                   |                                 s|                                 dk    rdS |                                  |                     t
          j                   |                                 }|5|                     t
          j                   t          d| j
                  |                                   |                                 s|                                 dk    r5|                     t
          j                   t          d| j
                  |                                  |                     t
          j                   t          ||                                           S )zParse a subshell ( list ).r  NzExpected command in subshellr  r   zExpected ) to close subshell)r  ro  rh  rl  r  r   r   rP  r  r   r
   r  r  r   r  s     r   parse_subshellzParser.parse_subshell#  sD   ;;== 	DIIKK3..4(5666  <.;<<<;JJJJ;;== 	KDIIKK3...;<<<;JJJJ*7888d5577888r   ArithmeticCommand | Nonec                0   |                                   |                                 sD|                                 dk    s,| j        dz   | j        k    s| j        | j        dz            dk    rdS | j        }|                                  |                                  | j        }d}|                                 s|dk    r|                                 }|dk    r|                                  |                                 sX|                                 dk    r@|                                  |                                 s|                                 dk    @|                                 s|                                  n|dk    r|                                  |                                 s|                                 dk    r<| j        dz   | j        k     r)|                                  |                                  nA|                                 dk    r|                                  n(|                                  |                                 n|dk    r<| j        dz   | j        k     r)|                                  |                                  n|dk    r|dz  }|                                  nv|dk    r\|dk    r-| j        dz   | j        k     r| j        | j        dz            dk    rnX|dz  }|dk    r	|| _        dS |                                  n|                                  |                                 s|dk    |                                 rt          d	|
          |dk    r	|| _        dS t          | j        || j                  }|	                    dd          }|                                  |                                  | 
                    |          }t          ||                                 |          S )zParse an arithmetic command (( expression )) with parsed internals.

        Returns None if this is not an arithmetic command (e.g., nested subshells
        like '( ( x ) )' that close with ') )' instead of '))').
        r  re   Nr   r  rE   rD   r   r#  r  r  ru   )r3  )r  ro  rh  r
   rR  rO  rl  r!   r_   r  r$  r@  r  )r   r  r3  r3  r#   r  r&  s          r   parse_arithmetic_commandzParser.parse_arithmetic_command$  s    	 KKMM	yy{{c!!x!|t{**{48a<(C//4H	 ++-- (	EAII		ACxx++-- #DIIKK3,>,>LLNNN ++-- #DIIKK3,>,>{{}} #LLNNNc++-- 'yy{{d**tx!|dk/I/I++ ++-- ' dtx!|dk99c
cA::$(Q,"<"<TXXY\AZ^aAaAa
A::(DH4Q ++-- (	EAIIT ;;== 	U"#D)TTTTA:: DH4T[-BB//&"-- %%g.. t'>'>'@'@gVVVVr   r8  rS  ConditionalExpr | Nonec                   |                                   |                                 sD|                                 dk    s,| j        dz   | j        k    s| j        | j        dz            dk    rdS | j        dz   }|| j        k     rOt          | j        |                   s5| j        |         dk    r"|dz   | j        k     r| j        |dz            dk    sdS |                                  |                                  |                     t          j
                   t          | _        |                                 }|                                 sjt          |                                           rI|                                  |                                 s!t          |                                           I|                                 sD|                                 dk    s,| j        dz   | j        k    s| j        | j        dz            dk    rA|                     t          j
                   t           | _        t#          d| j        	          |                                  |                                  |                     t          j
                   t           | _        t%          ||                                           S )
z0Parse a conditional expression [[ expression ]].r  re   Nrg   rD   rO   r  z+Expected ]] to close conditional expressionr  )r  ro  rh  r
   rR  rO  rP   rl  r  r   r   r  r\  _parse_cond_orrZ   r  r[  r   r  r  )r   r  r  s      r   parse_conditional_exprzParser.parse_conditional_expr$  se    KKMM	yy{{c!!x!|t{**{48a<(C//48a<dk!!4;x011 " H%--qL4;..K1-55 4(5666* ""$$ ++-- 	$=diikk$J$J 	LLNNN ++-- 	$=diikk$J$J 	
 KKMM	Zyy{{c!!x!|t{**{48a<(C//.;<<<!0DJPTPXYYYY*7888,tT%<%<%>%>???r   c                   |                                  st          |                                           r|                                  n|                                 dk    rU| j        dz   | j        k     rB| j        | j        dz            dk    r)|                                  |                                  n/|                                 dk    r|                                  ndS |                                  dS dS )zGSkip whitespace inside [[ ]], including backslash-newline continuation.rD   re   rO   N)ro  rZ   rh  rl  r
   rR  rO  r   s    r   _cond_skip_whitespacezParser._cond_skip_whitespace$  s    ++-- 	(55 		t##HqL4;..K1-55$$ ++-- 	 	 	 	 	r   c                    |                                  pC|                                 dk    o+| j        dz   | j        k     o| j        | j        dz            dk    S )z*Check if we're at ]] (end of conditional).r  re   )ro  rh  r
   rR  rO  r   s    r   _cond_at_endzParser._cond_at_end$  sR    {{}} 
IIKK3b48a<$+#=b$+dhYZlB[_bBb	
r   c                   |                                   |                                 }|                                   |                                 s|                                 dk    rx| j        dz   | j        k     re| j        | j        dz            dk    rL|                                  |                                  |                                 }t          ||          S |S )z<Parse: or_expr = and_expr (|| or_expr)?  (right-associative)r  re   )
r  _parse_cond_andr  rh  r
   rR  rO  rl  r  r  r  s      r   r  zParser._parse_cond_or$  s    ""$$$##%%""$$$!!##		'		s""1t{**DHqL)S00LLNNNLLNNN''))E$&&&r   c                   |                                   |                                 }|                                   |                                 s|                                 dk    rx| j        dz   | j        k     re| j        | j        dz            dk    rL|                                  |                                  |                                 }t          ||          S |S )z:Parse: and_expr = term (&& and_expr)?  (right-associative)r  re   )
r  _parse_cond_termr  rh  r
   rR  rO  rl  r  r  r  s      r   r  zParser._parse_cond_and$  s    ""$$$$$&&""$$$!!##		(		s""1t{**DHqL)S00LLNNNLLNNN((**E4'''r   c                   |                                   |                                 rt          d| j                  |                                 dk    rm| j        dz   | j        k     r#t          | j        | j        dz                      sn7|                                  | 	                                }t          |          S |                                 dk    r|                                  |                                 }|                                   |                                 s|                                 dk    rt          d| j                  |                                  t          |          S |                                 }|t          d	| j                  |                                   |j        t           v rI|                                 }|t          d
|j        z   | j                  t#          |j        |          S |                                 s|                                 dk    r|                                 dk    r~|                                 dk    ret%          |                                           r| j        dz   | j        k     r| j        | j        dz            dk    sh|                                 }|                                   |                                 }|t          d
|z   | j                  t'          |||          S | j        }|                                 }|r|j        t(          v r~|                                   |j        dk    r|                                 }n|                                 }|t          d
|j        z   | j                  t'          |j        ||          S || _        t#          d|          S )zOParse: term = '!' term | '(' or_expr ')' | unary_test | binary_test | bare_wordz(Unexpected end of conditional expressionr  rE  re   r  r   z$Expected ) in conditional expressionNz'Expected word in conditional expressionzExpected operand after r  r  r_  rR  )r  r  r   r
   rh  rR  rZ   rO  rl  r  r  r  ro  r  _parse_cond_wordr   COND_UNARY_OPSr  r  r  COND_BINARY_OPS_parse_cond_regex_word)	r   r  r\  word1unary_operandr  word2r  op_words	            r   r  zParser._parse_cond_term$  s   ""$$$ 	WGTXVVVV 99;;#x!|dk))2KDHqL)3 3) //11w''' 99;;#LLNNN''))E&&((({{}} W		s 2 2 !GTXVVVVLLNNNU### %%''=FDHUUUU""$$$ ;.(( 1133M$ !:U[!HdhWWWWU[-888   "" 	%IIKK3499;;##5#5$))++:L:L !-- 41t{**t{48a</HC/O/O\\^^**,,,--//=$%>%CRRRR!"eU333I++--G %7=O;;**,,,=D(( 7799EE 1133E=$%>%NTXT\]]]]!'->>> % u%%%r   c                   |                                   |                                 rdS |                                 }t          |          rdS |dk    r.| j        dz   | j        k     r| j        | j        dz            dk    rdS |dk    r.| j        dz   | j        k     r| j        | j        dz            dk    rdS |                     t                    S )zUParse a word inside [[ ]], handling expansions but stopping at conditional operators.Nr  re   r  )	r  r  rh  r  r
   rR  rO  r
  r  rk  s     r   r  zParser._parse_cond_wordK%  s    ""$$$ 	4IIKKQ<< 	4881t{22t{48a<7PTW7W7W4881t{22t{48a<7PTW7W7W4((777r   c                "   |                                   |                                 rdS |                     t          j                   |                     t                    }|                     t          j                   t          | _	        |S )z\Parse a regex pattern word in [[ ]], where ( ) are regex grouping, not conditional grouping.N)
r  r  r  r   r   r
  r  r  r  r\  r  s     r   r  zParser._parse_cond_regex_wordZ%  s{    ""$$$ 	4(3444**>::*5666*r   BraceGroup | Nonec                   |                                   |                     d          sdS |                                  |                                 }|(t	          d|                                 j                  |                                   |                     d          s(t	          d|                                 j                  t          ||                                           S )zParse a brace group { list }.r  NzExpected command in brace groupr  r  zExpected } to close brace group)	r  r  r  rP  r   r  r
   r  r  r  s     r   r  zParser.parse_brace_groupf%  s    %%c** 	4))+++  <>DDXDXDZDZD^____%%c** 	`>DDXDXDZDZD^____$ 7 7 9 9:::r   	If | Nonec                X   |                                   |                     d          sdS |                     dh          }|(t          d|                                 j                  |                                  |                     d          s(t          d|                                 j                  |                     h d          }|(t          d|                                 j                  |                                  d}|                     d	          r|                     d	           |                     dh          }|(t          d
|                                 j                  |                                  |                     d          s(t          d|                                 j                  |                     h d          }|(t          d|                                 j                  |                                  d}|                     d	          r|                                 }nj|                     d          rU|                     d           |                     dh          }|(t          d|                                 j                  t          |||          }nj|                     d          rU|                     d           |                     dh          }|(t          d|                                 j                  |                                  |                     d          s(t          d|                                 j                  t          |||| 
                                          S )zQParse an if statement: if list; then list [elif list; then list]* [else list] fi.rb  Nrc  zExpected condition after 'if'r  z"Expected 'then' after if condition>   rf  re  rd  Expected commands after 'then're  Expected condition after 'elif'$Expected 'then' after elif conditionrd  rf  Expected commands after 'else'z#Expected 'fi' to close if statement)r  r  r  r   r  r
   r  r  _parse_elif_chainr  r  )r   r  r  r  elif_conditionelif_then_body
inner_elses          r   parse_ifzParser.parse_ifw%  s   %%d++ 	4 ))6(33	<$BVBVBXBXB\]]]] 	))+++%%f-- 	cAtG[G[G]G]Gabbbb ))*@*@*@AA	=4CWCWCYCYC]^^^^ 	))+++	((00 )	c""6*** "22F8<<N% !BH\H\H^H^Hbcccc--///))&11  :@T@T@V@V@Z    "223I3I3IJJN% !AtG[G[G]G]Gabbbb --///J,,V44 
 "3355

..v66 &&v...!22D6::
%$8d>R>R>T>T>X    >>:FFII**622 	c""6***--tf55I  !AtG[G[G]G]Gabbbb 	))+++%%d++ 	dBH\H\H^H^Hbcccc)Y	43J3J3L3LMMMr   r  c                F   |                      d           |                     dh          }|(t          d|                                 j                  |                                  |                      d          s(t          d|                                 j                  |                     h d          }|(t          d|                                 j                  |                                  d}|                     d          r|                                 }nj|                     d	          rU|                      d	           |                     d
h          }|(t          d|                                 j                  t          |||          S )z/Parse elif chain (after seeing 'elif' keyword).re  rc  Nr  r  r  >   rf  re  rd  r  rd  rf  r  )	r  r  r   r  r
   r  r  r  r  )r   r  r  r  s       r   r  zParser._parse_elif_chain%  s   v&&&))6(33	>DDXDXDZDZD^____))+++%%f-- 	eCI]I]I_I_Icdddd))*@*@*@AA	=4CWCWCYCYC]^^^^))+++	((00 	c..00II**622 	c""6***--tf55I  !AtG[G[G]G]Gabbbb)Y	222r   While | Nonec                   |                                   |                     d          sdS |                     dh          }|(t          d|                                 j                  |                                  |                     d          s(t          d|                                 j                  |                     dh          }|(t          d|                                 j                  |                                  |                     d          s(t          d	|                                 j                  t          |||                                           S )
z.Parse a while loop: while list; do list; done.rj  Nrl  z Expected condition after 'while'r  z#Expected 'do' after while conditionrm  r  z#Expected 'done' to close while loop)	r  r  r  r   r  r
   r  r  r  r   r  r  s      r   parse_whilezParser.parse_while%  h   %%g.. 	4 ))4&11	?TEYEYE[E[E_```` 	))+++%%d++ 	dBH\H\H^H^Hbcccc $$fX..<;AUAUAWAWA[\\\\ 	))+++%%f-- 	dBH\H\H^H^HbccccYd&=&=&?&?@@@r   Until | Nonec                   |                                   |                     d          sdS |                     dh          }|(t          d|                                 j                  |                                  |                     d          s(t          d|                                 j                  |                     dh          }|(t          d|                                 j                  |                                  |                     d          s(t          d	|                                 j                  t          |||                                           S )
z/Parse an until loop: until list; do list; done.rk  Nrl  z Expected condition after 'until'r  z#Expected 'do' after until conditionrm  r  z#Expected 'done' to close until loop)	r  r  r  r   r  r
   r  r  r  r  s      r   parse_untilzParser.parse_until%  r  r   For | ForArith | Nonec                Z	   |                                   |                     d          sdS |                                   |                                 dk    r@| j        dz   | j        k     r-| j        | j        dz            dk    r|                                 S |                                 dk    rF|                                 }|(t          d| 	                                j                  |j
        }nS|                                 }|(t          d| 	                                j                  |                     |           |                                   |                                 dk    r|                                  |                                  d}|                     d	          rs|                     d	           |                                   t!          |                                           }|                                 dk    r|                                  |                                  g }	 |                                   |                                 rnt!          |                                           r/d
}|                                 dk    r|                                  nm|                     d          r+|rnUt          d| 	                                j                  |                                 }|n|                    |           |                                  |                                 dk    rg|                                 }|(t          d| 	                                j                  t)          |||j        |                                           S |                     d          s(t          d| 	                                j                  |                     dh          }|(t          d| 	                                j                  |                                  |                     d          s(t          d| 	                                j                  t)          ||||                                           S )zKParse a for loop: for name [in words]; do list; done or C-style for ((;;)).ri  Nr  re   rf   z"Expected variable name after 'for'r  r  rn  Trl  z#Expected ';' or newline before 'do'r  z Expected brace group in for loopzExpected 'do' in for looprm  r  z!Expected 'done' to close for loop)r  r  rh  r
   rR  rO  _parse_for_arithr	  r   r  r   r   r  rl  r  r  r|  ro  rw   r  r  r  r  r  )r   var_wordvar_namerK  saw_delimiterr   brace_groupr  s           r   	parse_forzParser.parse_for&  sw   %%e,, 	4 99;;#$(Q,"<"<TXXY\AZ^aAaAa((*** 99;;#((H 8d>R>R>T>T>X     ~HH~~''H 8d>R>R>T>T>X    h''' 99;;#LLNNN))+++ ((.. "	#""4(((  """ 5TYY[[AAMyy{{c!!--/// E#$$&&&;;== +DIIKK88 $(Myy{{c))0066 $ $=4CWCWCYCYC]    ((<T"""-#2 	))+++ 99;;#0022K" !CI]I]I_I_Icddddx(8$:Q:Q:S:STTT %%d++ 	Z8d>R>R>T>T>XYYYY $$fX..<;AUAUAWAWA[\\\\ 	))+++%%f-- 	b@dFZFZF\F\F`aaaa8UD$*A*A*C*CDDDr   r  c                   |                                   |                                   g }g }d}|                                 s|                                 }|dk    r.|dz  }|                    |                                             nw|dk    r|dk    r.|dz  }|                    |                                             n=| j        dz   | j        k     r}| j        | j        dz            dk    rd|                    d                    |                              d                     |                                   |                                   n|                    |                                             n|dk    rX|dk    rR|                    d                    |                              d                     g }|                                   n'|                    |                                             |                                 t          |          dk    rt          d	| j        
          |d         }|d         }|d         }|                                  |                                 s,|                                 dk    r|                                   |                                  |                     d          }t          |||||                                           S )z@Parse C-style for loop: for ((init; cond; incr)); do list; done.r   r  re   r   ru   r  r  r-  z(Expected three expressions in for ((;;))r  rg   zfor loop)rl  ro  rh  rw   r
   rR  rO  rx   r  r   r   r  r  r  r  r  )	r   r   r  r0  r  r  r  r  r  s	            r   r  zParser._parse_for_arithw&  s    	 ++-- 	/BSyyq t||~~....s??1$KNN4<<>>2222 x!|dk11dk$(Q,6OSV6V6VRWWW%5%5%<%<U%C%CDDDt||~~6666s{a//RWWW--44U;;<<<t||~~...3 ++-- 	/6 u::??GTXVVVVQxQxQx {{}} 	!3!3LLNNN))+++$$Z00dD$0G0G0I0IJJJr   Select | Nonec                b   |                                   |                     d          sdS |                                   |                                 }|(t          d|                                 j                  |                     |           |                                   |                                 dk    r|                                  | 	                                 d}| 
                    d          r|                     d           | 	                                 g }	 |                                   |                                 rnt          |                                           r-|                                 dk    r|                                  nC| 
                    d          rn-|                                 }|n|                    |           | 	                                 |                     d          }t!          ||||                                           S )	z@Parse a select statement: select name [in words]; do list; done.rp  Nz%Expected variable name after 'select'r  r  rn  Trl  )r  r  r   r   r  r
   r  rh  rl  r  r  ro  r  r	  rw   r  r  r  )r   r  rK  r   r  s        r   parse_selectzParser.parse_select&  s   %%h// 	4 >>##7T=Q=Q=S=S=W    	(### 99;;#LLNNN))+++ ((.. 	#""4(((--/// E#$$&&&;;== .tyy{{;; yy{{c))0066 ((<T"""#( 	))+++$$X..htT-D-D-F-FGGGr   c                ^    |                                  }||                                  |S dS )z<Consume and return case pattern terminator (;;, ;&, or ;;&).Nr  )r  r  )r   r  s     r   _consume_case_terminatorzParser._consume_case_terminator&  s5    --//  """Ktr   Case | Nonec                   |                      d          sdS |                     t          j                   |                                  |                                 }|(t          d|                                 j                  | 	                                 | 
                    d          s(t          d|                                 j                  | 	                                 g }|                     t          j                   	 | 	                                 |                     d          r| j        }|                                  |                                 st          |                                           st!          |                                           sj|                                  |                                 sBt          |                                           s!t!          |                                           j|                                  d	}|                                 s|                                 d
k    rx| j        d
k    rd	}nj|                                  |                                  |                                 s.|                                 }|dk    rd}nt'          |          sd}|| _        |s
nS| 	                                 |                                 s@|                                 dk    r(|                                  | 	                                 g }d}|                                 s|                                 }|d
k    rJ|dk    r.|                    |                                            |dz  }n5|                                  n4|dk    r| j        dz   | j        k     rC| j        | j        dz            dk    r*|                                  |                                  n|                    |                                            |                                 s'|                    |                                            n_t/          | j        | j        d          r2|                    |                                            |                    |                                            |                                 s|                                 dk    r|                    |                                            d}	|                                 sr|	dk    rl|                                 }
|
dk    r|	dz  }	n|
d
k    r|	dz  }	|                    |                                            |                                 s|	dk    ln|dz  }n|dk    r4|dk    r.|                    |                                            |dz  }n| j        rt3          |          r| j        dz   | j        k     rn| j        | j        dz            dk    rU|                    |                                            |                    |                                            |dz  }n@|dk    rd	}| j        dz   }d}d	}|| j        k     rt5          | j        |                   r|dz  }|| j        k     r:| j        |         dk    r)| j                            d|dz             dk    r|dz  }d}|| j        k     rR| j        |         }|dk    r	|dk    rd}n6|dk    r|dz  }n|d
k    r|dk    rn|dk    r|dk    rn|dz  }|| j        k     R|r|                    |                                            |                                 sHt5          |                                           r'|                    |                                            |rS|                                 s?|                                 dk    r'|                    |                                            |                                 sk|                                 dk    rS|                    |                                            |                                 s|                                 dk    S|                                 s'|                    |                                            n|                    |                                            n|dk    r|                    |                                            |                                 sk|                                 dk    rS|                    |                                            |                                 s|                                 dk    S|                                 s'|                    |                                            n|dk    r4|                    |                                            |                                 s|                                 dk    r|                                 dk    r:| j        dz   | j        k     r'|                    |                                            |                    |                                            |                                 s|                                 dk    |                                 s'|                    |                                            nyt9          |          rC|dk    r(|                    |                                            n<|                                  n'|                    |                                            |                                 d                    |          }|s(t          d|                                 j                  |                                  d}|                                 du}|s| 	                                 |                                 sW|                     d          sB|                                 du}|s*|                     dh          }|                                  |                                  }| 	                                 |                    tC          |||                     | "                    t          j                   | 	                                 | 
                    d          sG| "                    t          j                   t          d|                                 j                  | "                    t          j                   tG          ||| $                                          S )zBParse a case statement: case word in pattern) commands;; ... esac.rg  NzExpected word after 'case'r  rn  zExpected 'in' after case wordTrh  Fr   r  r  r   re   rD   rO   r  rg   r  r  rH   r  r  rE   ru   z"Expected pattern in case statementz'Expected 'esac' to close case statement)%r  r  r   r   r  r	  r   r  r
   r  r  r   r  ro  r  rh  ri  rl  rY  r  rw   rR  rO  ro   rW  r  r  r  rP   rx   r  r  r  r  r  r  r  )r   r   r  r  
is_patternr  pattern_charsr,  r  r0  r#   is_char_classr  
scan_depthhas_first_bracket_literalr  r  r  is_empty_bodyis_at_terminatorr;  s                        r   
parse_casezParser.parse_case&  s      (( 	4(5666   <9t?S?S?U?U?YZZZZ))+++ %%d++ 	^<$BVBVBXBXB\]]]]))+++ ')(4555L	D--/// ,,V44 ! $$&&& #(55# &diikk22#
 LLNNN	 #(55# &diikk22# $$&&&"
{{}} 2););#--%*

,,...  ${{}} 2&*iikkG&#~~-1

%?%H%H 2-1
 !  --///;;== 4TYY[[C%7%711333
 MMkkmm {9YY[[99$q((%,,T\\^^<<<%* 4ZZx!|dk11dk$(Q,6OSW6W6W &,,T\\^^<<<#{{}} A)00@@@(dhEE e9!((888!((888;;== +TYY[[C-?-?%,,T\\^^<<<&'"&++-- AK!OO $		A Cxx +q 0!"c +q 0)00@@@ #'++-- AK!OO &*3YY=1#4#4!((888!Q&MMMO9*2..O9 1t{22DHqL1S88 "((888!((888!Q&MM3YY %*M#x!|H!"J05-$+--2CDKPXDY2Z2Z- A$+--$+h2G32N2N;++CA>>"DD$MH8<5"T[00![299q,0M!3YY&!OJJ3YY:??!3YY:??! A #T[00 % =%,,T\\^^<<<#{{}} A1B499;;1O1O A)00@@@4 AT[[]] Atyy{{^aOaOa)00@@@"&++-- ADIIKK34F4F)00@@@ #'++-- ADIIKK34F4F#{{}} A)00@@@ &,,T\\^^<<<<3YY!((888"kkmm =		s0B0B%,,T\\^^<<< #kkmm =		s0B0B;;== =%,,T\\^^<<<3YY!((888"kkmm =		s0B0B99;;$..48a<$+3M3M)00@@@%,,T\\^^<<< #kkmm =		s0B0B  ;;== =%,,T\\^^<<<#B'' 9$q((%,,T\\^^<<<<!((888w kkmm {9z ggm,,G  8d>R>R>T>T>X      """D ::<<DHM  /11333{{}} /T-J-J6-R-R /'+'E'E'G'Gt'S$+ /#44fX>>,,... 6688J--///OOKzBBCCCYL	D\ 	*6777))+++%%f-- 	.;<<<9t?S?S?U?U?Y    	*7888D(D$;$;$=$=>>>r   Coproc | Nonec                ^   |                                   |                     d          sdS |                                   d}d}|                                 s|                                 }|dk    r&|                                 }|t          ||          S |dk    rx| j        dz   | j        k     r?| j        | j        dz            dk    r&| 	                                }|t          ||          S | 
                                }|t          ||          S |                                 }|/|t          v r&|                                 }|t          ||          S | j        }|                                 }|r|                                 st          |                                           st!          |                                           sj|                                  |                                 sBt          |                                           s!t!          |                                           j|                                   d}|                                 s|                                 }|                                 }t%          |          r|dk    r)|}|                                 }|t          ||          S n|dk    rj|}| j        dz   | j        k     r.| j        | j        dz            dk    r| 	                                }n| 
                                }|t          ||          S n3|1|t          v r(|}|                                 }|t          ||          S || _        |                                 }|t          ||          S t)          d| j                  )zParse a coproc statement.

        bash-oracle behavior:
        - For compound commands (brace group, if, while, etc.), extract NAME if present
        - For simple commands, don't extract NAME (treat everything as the command)
        rq  Nr  r  re   zExpected command after coprocr  )r  r  ro  rh  r  r  r
   rR  rO  r  r  r  COMPOUND_KEYWORDSparse_compound_commandr   r  ri  rl  r  r  r   )r   rA  r  r  	next_wordr  potential_names          r   parse_coproczParser.parse_coproc'  s    	%%h// 	4 {{}} 	B99))++DdD)))99x!|dk))dk$(Q,.G3.N.N4466#!$---&&((DdD))) 0022	 Y2C%C%C..00DdD))) X
)) $	" KKMM*6tyy{{*C*CLUVZV_V_VaVaLbLb  KKMM*6tyy{{*C*CLUVZV_V_VaVaLbLb   """ B;;== !YY[[4466I#N33 299)D1133D'%dD111 (3YY)Dx!|dk11dk$(Q,6OSV6V6V#<<>>#2244'%dD111 (*y<M/M/M)D6688D'%dD111 "DH !!##$%%%8dhGGGGr   Function | Nonec                X	   |                                   |                                 rdS | j        }|                     d          rA|                     d           |                                   |                                 }|	|| _        dS |                     |           |                                   |                                 sl|                                 dk    rT| j        dz   | j        k     rA| j	        | j        dz            dk    r(| 
                                 | 
                                 |                                  |                                 }|t          d| j                  t          ||          S |                                 }|	|t          v rdS t!          |          rdS |                                   | j        }|                                 st#          |                                           st%          |                                           st'          |                                           s| 
                                 |                                 sct#          |                                           sBt%          |                                           s!t'          |                                           t)          | j	        || j                  }|s	|| _        dS d}d}|t+          |          k     rEt-          ||d	          r|dz  }|d
z  }/||         dk    r|dz  }|dz  }|t+          |          k     E|dk    r	|| _        dS | j        }|                                   | j        |k    }|s%|r#|t+          |          dz
           dv r	|| _        dS |                                 s|                                 dk    r	|| _        dS | 
                                 |                                   |                                 s|                                 dk    r	|| _        dS | 
                                 |                                  |                                 }|t          d| j                  t          ||          S )zParse a function definition.

        Forms:
            name() compound_command           # POSIX form
            function name compound_command    # bash form without parens
            function name() compound_command  # bash form with parens
        Nro  r  re   r   zExpected function bodyr  r   rF  rg   r  z*?@+!$)r  ro  r
   r  r  r   r  rh  rR  rO  rl  r  _parse_compound_commandr   r!  ru  r  r  ri  r  r_   r   ro   )	r   r  rA  r  r@  r1  rz   pos_after_namehas_whitespaces	            r   parse_functionzParser.parse_function4(  s    	;;== 	4H	 ((44 	("":...  """ >>##D|$td###  """ ;;== #TYY[[C%7%78a<$+--$+dhl2Ks2R2RLLNNNLLNNN --/// //11D| !9txHHHHD$''' ~~<4>114 "$'' 	4 	X
 	 --	 diikk**	 diikk**		 LLNNN 	 --	 diikk**	 diikk**		 $+z48<< 	 DH4 #d))mm"4D11 q QAw#~~q FA #d))mm ?? DH4 N2 	$ 	4D		A+>(+J+J DH4;;== 	DIIKK3.. DH4;;== 	DIIKK3.. DH4))+++ ++--<548DDDDd###r   c                   |                                  }|r|S |                                 s\|                                 dk    rD| j        dz   | j        k     r1| j        | j        dz            dk    r|                                 }||S |                                 }|r|S |                                 }|r|S | 	                                }|r|S | 
                                }|r|S |                                 }|r|S |                                 }|r|S |                                 }|r|S |                                 }|r|S dS )z7Parse any compound command (for function bodies, etc.).r  re   N)r  ro  rh  r
   rR  rO  r  r  r  r  r  r  r  r  r  r  s     r   r  zParser._parse_compound_command(  s{    '')) 	M 			s""1t{**DHqL)S002244F!$$&& 	M,,.. 	M 	M!!## 	M!!## 	M!! 	M"" 	M""$$ 	Mtr   
stop_wordsset[str]c                \   |                                  rdS |                                 dk    rdS |                                 dk    r1| j        dz   }|| j        k    st	          | j        |                   rdS |                                 }|||v rdS |                                 dS dS )z<Check if we're at a terminator for parse_list_until context.Tr   r  re   NF)ro  rh  r
   rR  r~  rO  r  r  )r   r  r  r  s       r   _at_list_until_terminatorz Parser._at_list_until_terminator(  s    ;;== 	499;;#499;;#x!|H4;&&*>t{8?T*U*U&t//11H
$:$:4))++74ur   c                   |                                   |                                 }|||v rdS |                                 }|dS |g}	 |                                  |                                 }||                                 s|                                 dk    r|                                  |                                  | j	        dk    r#| j	        | j
        k    r| j	        | _
        d| _	        |                                   |                     |          rn|                                 }|dv rnid}nnd|n`|dk    rN|                                   |                     |          rn/|                    t          |                     n|dk    rM|                    t          |                     |                                   |                     |          rnn]|dv r7|                    t          |                     |                                   n"|                    t          |                     |                     |          rnF|                                 }|t          d	|z   | j
        
          |                    |           Zt!          |          dk    r|d         S t#          |          S )z6Parse a list that stops before certain reserved words.NTrO   rH   r  r  r  r  r  r  Expected command after r  re   r   )r  r  parse_pipeliner  parse_list_operatorro  rh  rl  r  r  r
   r  _peek_list_operatorrw   r  r   r   rd  )r   r  r  rU  r   r  next_ops          r   r  zParser.parse_list_until(  s    	))+++//11H
$:$:4&&((4
7	#  """))++Bz{{}} )<)<LLNNN//111/255$:RUYU]:]:]#'#;3505577755jAA "6688G*,,BBz Syy1133311*== Xb\\****sXb\\***1133311*== |##Xb\\***113333 Xb\\*** --j99 **,,H !:R!?TXNNNNLL"""o7	#r u::??8OE{{r   c                D   |                                   |                                 rdS |                                 }|dk    rD| j        dz   | j        k     r1| j        | j        dz            dk    r|                                 }||S |dk    r|                                 S |dk    r|                                 }||S |dk    rD| j        dz   | j        k     r1| j        | j        dz            dk    r| 	                                }||S | 
                                }|U| j        rN|                                 }|8t          |          dk    r%|d         dk    r|dd         }|t          v s|dv r|}|d	v r,t          d
| d|                                 j                  |dk    r|                                 S |dk    r|                                 S |dk    r|                                 S |dk    r|                                 S |dk    r|                                 S |dk    r|                                 S |dk    r|                                 S |dk    r|                                 S |                                 }||S |                                 S )zOParse a compound command (subshell, brace group, if, loops, or simple command).Nr  re   r  r  r   r  r  )rf  rc  re  rd  rm  rh  rl  rn  zUnexpected reserved word 'r  r  rb  rj  rk  ri  rp  rg  ro  rq  )r  ro  rh  r
   rR  rO  r  r  r  r  r  r  r   r   ru  r   r  r  r  r  r  r  r  r  r  r  )r   r  ry   r  r   r  funcs          r   r  zParser.parse_compound_command>)  s   ;;== 	4YY[[ 99A33DHqL8QUX8X8X2244F! 99&&((( 99++--F! 99A33DHqL8QUX8X8X0022F! //11  4>>##DCIIMMd1gnn#ABBx>11\ F 6 6  ,H QQQ8X888d>R>R>T>T>X   
 t==??" w##%%% w##%%% u>>### x$$&&& v??$$$ z!!&&((( x$$&&& ""$$K !!###r   c                d
   |                                   d}d}|                     d          r|                     d           d}|                                   |                                 s|                                 dk    r| j        }|                                  |                                 sl|                                 dk    rT|                                  |                                 s!t          |                                           rd}n|| _        n|| _        |                                   |                                 st          | j	        | j        d          rs| j        dz   | j
        k    s"t          | j	        | j        dz                      r>|                                  |                                  d}|                                   |                     d          r|                     d           |                                   |                                 s|                                 dk    r| j        }|                                  |                                 sl|                                 dk    rT|                                  |                                 s!t          |                                           rd}n|| _        n|| _        |                     d          |                                   |                                 s|                                 d	k    rs| j        d
z   | j
        k    s"t          | j	        | j        d
z                      r>|                                 s*|                                  d}|                                   n|                                 s|                                 d	k    r| j        d
z   | j
        k    s"t          | j	        | j        d
z                      r|                                 su|                                  |                                   |                                 }|(|j        dk    r|j        |j        S t#          g           S t%          |          S |                                 }|dk    rt)          ||          }nf|dk    rt%          |          }nP|dk    r t)          ||          }t%          |          }n*|dk    r t)          ||          }t%          |          }n|dS |S )zOParse a pipeline (commands separated by |), with optional time/negation prefix.NFrr  r  r  Trc  rg   rE  re   time_negationr  negation_time)r  r  r  ro  rh  r
   rl  r  rc   rO  rR  rP   r  r  r  r.  rU  rI  r  _parse_simple_pipeliner  )r   prefix_order
time_posixr  r\  ry   s         r   r  zParser.parse_pipeline)  s    
 ((00 B	'""6***!L  """;;== 
%TYY[[C%7%7{{}} %););LLNNN{{}} )TYY[[(A(A )%)

#($DH  """;;== +_T[$(D%Q%Q +8a<4;...TXXY\AZ2[2[.LLNNNLLNNN!%J((***//77 )&&v...$$&&&{{}} 
));); HELLNNN;;== )TYY[[C-?-?;;== -L,E,E -)-JJ',DHH#( //77 )   """;;== +TYY[[C%7%7HqLDK//3HUYU]`aUaIb3c3c/;;== 0LLNNN#2L((***  	'499;;##5#51++/DT[QUQY\]Q]E^/_/_+7799 ,$$&&& ++--$z)A)A~1$~-&r{{*& ,,.. 6!!&*--FFZ''f%%FF_,,&*--Ff%%FF_,,&*--Ff%%FF^4r   c                n   |                                  }|dS |g}	 |                                  |                                 \  }}|dk    rn|t          j        k    r|t          j        k    rn|                                  |t          j        k    }|                                  |r!|                    t                                 |                                  }|t          d| j                  |                    |           t          |          dk    r|d         S t          |          S )zNParse a simple pipeline (commands separated by | or |&) without time/negation.NTr   zExpected command after |r  re   )r  r  r  r}   r   r   r  r  rw   r  r   r
   r   rR  )r   r[  rS  
token_typer   is_pipe_boths         r   r  zParser._parse_simple_pipeline*  s9   ))++;45	!  """ $ 7 7 9 9JQY^++
i>P0P0P  """%);;L--///  ,

+++--//C{ !;JJJJOOC   )	!, x==AA;!!!r   c                   |                                   |                                 \  }}|dk    rdS |t          j        k    r|                                  dS |t          j        k    r|                                  dS |t          j        k    r|                                  dS |t          j        k    r|                                  dS dS )z%Parse a list operator (&&, ||, ;, &).r   Nr  r  r  r  )r  r  r}   r   r  r   r   r   )r   r  r  s      r   r  zParser.parse_list_operator&*  s    //11
A??4***  """4((  """4''  """3&&  """3tr   c                J    | j         }|                                 }|| _         |S )z-Peek at next list operator without consuming.)r
   r  )r   r  r  s      r   r  zParser._peek_list_operator:*  s&    H	%%''	r   newline_as_separatorc                   |r|                                   n|                                  |                                 }|dS |g}|                     t          j                  r>|                                 r*t          |          dk    r|d         nt          |          S 	 |                                  | 	                                }|| 
                                s|                                 dk    r|sn|                                  |                                  | j        dk    r#| j        | j        k    r| j        | _        d| _        |                                   | 
                                s|                                 rn|                                 }|dv rnd}nn|n|                    t'          |                     |dv r|                                   n<|d	k    r|                                  | 
                                s|                                 rnr|                                 dk    rC|r?|                                   | 
                                s|                                 rnnnn|d
k    r|                                  | 
                                s|                                 rn|                                 dk    rA|r>|                                   | 
                                s|                                 rn|nnz|                                 }|t)          d|z   | j                  |                    |           |                     t          j                  r|                                 rnt          |          dk    r|d         S t          |          S )zParse a command list (pipelines separated by &&, ||, ;, &).

        Args:
            newline_as_separator: If True, treat newlines as implicit semicolons.
                If False, stop at newlines (for top-level parsing).
        Nre   r   TrO   rH   r  r   r  r  r  r  )r  r  r  r  r   r   r  r   rd  r  ro  rh  rl  r  r  r
   r  r  rw   r  r   )r   r  rU  r   r  r  s         r   rP  zParser.parse_listA*  s      	#--////  """&&((4
 >>*788 	@T=O=O=Q=Q 	@"5zzQ588DKK?C	  """))++Bz{{}} )<)</ LLNNN//111/255$:RUYU]:]:]#'#;35055777{{}} (I(I(K(K "6688G*,,BBzLL"&&& \!!113333s$$&&&;;== D$E$E$G$G 99;;$&&+ 99;;;;;== "D,M,M,O,O "!"  ' s$$&&&;;== D$E$E$G$G 99;;$&&+ 99;;;;;== "D,M,M,O,O "!"  **,,H !:R!?TXNNNNLL""" ~~.;<< ASASAUAU GC	J u::??8OE{{r   c                   |                                  s|                                 dk    rdS | j        }|                                  sX|                                 dk    r@|                                  |                                  s|                                 dk    @t	          | j        || j                  }t          |          S )z#Parse a comment (# to end of line).r  NrO   )ro  rh  r
   rl  r_   rO  r  )r   r\   r  s      r   parse_commentzParser.parse_comment*  s    ;;== 	DIIKK3..4++-- 	DIIKK4$7$7LLNNN ++-- 	DIIKK4$7$7$+udh77t}}r   c                   | j                                         }|st                      gS g }	 |                                  |                                 sX|                                 dk    r@|                                  |                                 s|                                 dk    @|                                 rn|                                 }|sn|                                 sH|                     d          }||	                    |           |                                  d}|                                 s|                                 dk    rd}|                                  | 
                                 | j        dk    r#| j        | j        k    r| j        | _        d| _        |                                  |                                 s|                                 dk    |s*|                                 st          d| j                  |                                 H|st                      gS | j        r| j         r| j         t          | j                   d	z
           d
k    rt          | j                   dk    r=| j         t          | j                   dz
  t          | j                   d	z
           dk    s*|                     |          s|                     |           |S )zParse the entire input.TrO   F)r  NrH   zSyntax errorr  re   rD   r-  r  )rO  r  r  r  ro  rh  rl  r  rP  rw   r  r  r
   r   r  r   _last_word_on_own_line(_strip_trailing_backslash_from_last_word)r   rO  resultsr  ry   found_newlines         r   parsezParser.parse*  s   ""$$ 	GG9		  """kkmm 		t(;(; kkmm 		t(;(;{{}} ((**G 		 ++-- 	?__%_@@F!v&&&  """ "Mkkmm '		t(;(; $++---+r11d6NQUQY6Y6Y#7DH/1D,$$&&& kkmm '		t(;(; ! ? ? TX>>>>+ ++-- 	?.  	GG9 -	G	G C,,q01T99DK  A%%KDK 0 01 4s4;7G7G!7K KLPVVV
 ..w77 G==gFFFr   nodesc                (    t          |          dk    S )zRCheck if the last word is on its own line (after a newline with no other content).rg   r  )r   r  s     r   r  zParser._last_word_on_own_line*  s     5zzQr   c                   |sdS |t          |          dz
           }|                     |          }|r|j                            d          rpt	          |j        dt          |j                  dz
            |_        |j        s;t          |t                    r(|j        r#|j                                         dS dS dS dS dS dS )z7Strip trailing backslash from the last word in the AST.Nre   rD   r   )	r   _find_last_wordr   rN  r_   r  rI  rK  r!  )r   r  	last_node	last_words       r   r  z/Parser._strip_trailing_backslash_from_last_word*  s     	F#e**q.)	((33	 	&11$77 	&(!S=Q=QTU=UVVIO? &z)W'E'E &)/ &##%%%%%		& 	& 	& 	&& & & & & &r   r  c                   t          |t                    r|S t          |t                    r|j        r>|j        t	          |j                  dz
           }|j                            d          r|S |j        r>|j        t	          |j                  dz
           }t          |t                    r|j	        S |j        r"|j        t	          |j                  dz
           S t          |t                    r<|j        r5|                     |j        t	          |j                  dz
                     S t          |t                    r<|j        r5|                     |j        t	          |j                  dz
                     S dS )z3Recursively find the last Word in a node structure.re   rD   N)r  r  rI  rK  r   r   rN  r  r  r  rR  rS  r   rd  r   )r   r  r"  last_redirects       r   r   zParser._find_last_word +  se   dD!! 	KdG$$ 	7 z % Js4:':;	?++D11 %$$~ 0 $s4>/B/BQ/F GmX66 0(//z 7z#dj//A"566dH%% 	S} S++DM#dm:L:Lq:P,QRRRdD!! 	Mz M++DJs4:7J,KLLLtr   NFF)rO  r	   rH  r$   rP  r$   )r  r   r   r  )r  r   r   r$   )r   r  )r  r  r   r  )r  r   r   r  r~  r)  r|  r*  )r   r  rw  )r   r	   r   r$   )r  r	   r   r$   )r  r   r   r	   rx  )r   r   )r  r	   r   r  r   rz  )T)
r  r  r   rq   r\   r   r  r$   r   r  rv  )r  r  r   rq   r  r$   r   r$   )r9  r   r  r$   r  r$   r   r   r{  )r  r$   r  r$   r  r$   r   r   r}  r  )r   r  r   r$   )r  r	   r   r  r:  r   rQ   r	   r   r$   )r   r  )rC  r  rD  rE  r   r  r  )r   r  )r   r  )r  r$   r   r  )r   r	   rm   r	   r  r$   r   r  )r  r   r  r$   r   r  )r   r  )r   r  )r   r  )r   r  )r   r   )r   r  )r   r  )r   r  )r   r  )r   r  )r   r  )r   r  )r   r  )r   r  )r   r  )r   r  )r   r  )r  r  r   r$   )r  r  r   r  )r  r$   r   r  )r   rq   )r  rq   r   r$   )r  rq   r   r  )r  r  r   r   )r   r   r   r   r   r  r  r  r  r  r  r%  r  r  r  r  r  r  r  r  r  r  r  r  ro  rh  rl  r  ru  r  r  r  r  r  r  r  r   r  r  r  r  r
  r	  r  ra  r  r  r  r  r  r$  r)  r1  r3  r(  r7  r9  r*  r;  r?  rH  rB  rJ  rL  rN  rP  rR  rT  rV  rX  rZ  r^  r`  re  rg  ri  rp  rq  rj  rk  rl  rm  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  rP  r  r  r  r  r   r"   r   r   rO  rO  <  s
       ,,!! !! !! !! !!F7 7 7 78 8 8 80 0 0 0
 
 
 
0 0 0 0
 
 
 
8 8 8 8.A A A A2# # # #   8   8      
 
 
 
0
 
 
 
           
   
 
 
 
' ' ' '% % % %          ? ? ? ?0 0 0 0   $   0   0	 	 	 		0 	0 	0 	0` ` ` `*   @# # # #L MNT T T T T ae% % % % %2 FK, , , , ,^ RWC C C C C "'!&"'	    8'. '. '. '.R: : : ::- - - -R. R. R. R.hE E E EN,% ,% ,% ,%\P/ P/ P/ P/J   62 2 2 2$ $ $ $ $      D D D D         "   2   "S S S SR R R R   "      "X X X X   B   .   *   4	 	 	 	$+ $+ $+ $+L   661 61 61 61p3 3 3 3>2( 2( 2( 2(hM0 M0 M0 M0^	$ 	$ 	$ 	$$ $ $ $ ( ( ( (&"
 "
 "
 "
H. . . .2    a$ a$ a$ a$F@0 @0 @0 @0D   0
@ 
@ 
@ 
@2$ 2$ 2$ 2$h   *3) 3) 3) 3)j9 9 9 9,TW TW TW TWn  N:  O$2@ 2@ 2@ 2@h   $
 
 
 
   "   "N& N& N& N&`8 8 8 8
 
 
 
; ; ; ;"HN HN HN HNT3 3 3 3:A A A A6A A A A6aE aE aE aEF6K 6K 6K 6Kp4H 4H 4H 4Hl   o? o? o? o?bTH TH TH THlw$ w$ w$ w$r2 2 2 2h   $I I I IV`$ `$ `$ `$Db b b bH "  "  "  "D   (   \ \ \ \ \|   B B B BH   & & & &     r   rO  rP  c                L    t          | d|          }|                                S )a`  
    Parse bash source code and return a list of AST nodes.

    Args:
        source: The bash source code to parse.
        extglob: Enable extended glob patterns (@, ?, *, +, ! followed by parentheses).

    Returns:
        A list of AST nodes representing the parsed code.

    Raises:
        ParseError: If the source code cannot be parsed.
    F)rO  r  )rO  rP  r.  s      r   r  r  +  s#     FE7++F<<>>r   Nry  )r#   r	   r   r   )rQ   r	   r   rR   )rQ   r	   r\   r   r]   r   r   r	   )rQ   r	   r
   r   r`   r	   r   r$   )rQ   r	   r
   r   r   r   )rQ   r	   r
   r   rm   r	   r   r$   )rp   rq   r\   r   r]   r   r   rq   )rQ   r	   r@   r   r   r	   )r  r	   r   r	   )r  r	   r  r   r   r	   rG  )rQ   r	   r\   r   r   r  )rQ   r	   r\   r   r3  r   r   r$   )rQ   r	   r\   r   r3  r   r   r  )r  r  r   r	   )r  r  r   r$   )r   FFF)r  r  r  r   r  r$   r  r$   r  r$   r   r	   r%  )rA   r	  r2  r$   r  r$   r   r	   )rA   r  r   r	   )r   r	   r\   r   r3  r   r   r$   )r   r	   r\   r   r   r   )rQ   r	   r\   r   r   r   )r   r	   r\   r   r   r$   )rO  r	   r\   r   r/  r0  r   r1  )rQ   r	   r
   r   r6  r   r   r$   )rQ   r	   r   r   )rm   r	   r   r	   r:  )rQ   r	   r\   r   r  r	   r  r	   r  r   r   r   )rQ   r	   r\   r   r  r   r   r   )rQ   r	   r  r   r   r   )r  r  r   r$   )r   r	   r&  r   r   r$   r&  )rA  r	   r   r$   rv  )rO  r	   rP  r$   r   rq   )r   
__future__r   collections.abcr   typingr   rR  r   r!   r-   r0   rI   rK   rP   rX   rZ   r_   rc   rl   ro   rs   r{   r}   r   r   r   r  r  r  r,  rB  rN  r  r  r  r  rI  rR  rd  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r
  r  r  r  r  r!  r?  rJ  rK  r  r  r@  rH  rM  rQ  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  rV  r  r  r  r  r  rQ  r  r  r  r  r  r  r  r  r  r  r"  r5  r  ru  r  r  r  r  ri  rn  rp  rs  r  r  r  r  r6  r=  r>  r|  r~  r  r  r  r%  r  r  r  r  r/  rM  r  r  r  r  r  rL  r  r  r  r  r  r[  r  r  rO  r  r"   r   r   <module>r+     s*    # " " " " " $ $ $ $ $ $      . . . . . . . ."	 	 	 	 	z 	 	 	Y Y Y Y! ! ! ! 
								
		  % % % %
. . . .# # # #
! ! ! !   
% % % %
   .
> 
> 
> 
>   
   < < < < < < < <~? ? ? ? ? ? ? ?<       &              &# # # # # # # #,'4 '4 '4 '4 '4 '4 '4 '4T# # # # # # # #L% % % % % % % %P} } } } } } } }@2+ + + +\   " " " " " " " "m" m" m" m" m"4 m" m" m"`/) ) ) ) )d ) ) )2= = = = =t = = =@~ ~ ~ ~ ~4 ~ ~ ~B7 7 7 7 7t 7 7 7(    t       D       d   Q> Q> Q> Q> Q>t Q> Q> Q>h#0 #0 #0 #0 #0d #0 #0 #0L7 7 7 7 7t 7 7 7 7 7 7 7 7 7 7 7        B7 7 7 7 7D 7 7 7(7 7 7 7 7D 7 7 7(: : : : :$ : : :z   $B $B $B $B $Bt $B $B $BN1
 1
 1
 1
 1
T 1
 1
 1
h7 7 7 7 74 7 7 74
 
 
 
    	 	 	 	+ + + +\Q Q Q Q Q$ Q Q QhL L L L Lt L L L1 1 1 1 1T 1 1 14/ / / / /$ / / /4 4 4 4 4D 4 4 449 9 9 9 9$ 9 9 9"; ; ; ; ;$ ; ; ;( ( ( ( ( ( ( (\
/ 
/ 
/ 
/ 
/$ 
/ 
/ 
/       
+ 
+ 
+ 
+ 
+t 
+ 
+ 
+
 
 
 
 
D 
 
 
&M M M M M4 M M M
; 
; 
; 
; 
;4 
; 
; 
;
< 
< 
< 
< 
<D 
< 
< 
<
; 
; 
; 
; 
;4 
; 
; 
;
< 
< 
< 
< 
<D 
< 
< 
<
 
 
 
 
$ 
 
 
&
 
 
 
 
4 
 
 
2R R R R R R R RO O O O OT O O O
. 
. 
. 
. 
.$ 
. 
. 
.6 6 6 6 6d 6 6 68 8 8 8 8$ 8 8 8 , , , , , , , ,, , , , ,4 , , ,S S S S S$ S S S< < < < <t < < < 8 8 8 8 84 8 8 8.    d   >R R R R R R R R$
 
 
 
 
 
 
 
:U U U U Ud U U UT T T T TT T T T& & & & &d & & &
: 
: 
: 
: 
: 
: 
: 
: 	& J)KL' ' ' ' 'D ' ' '&H H H H HT H H H(   *   $ #C C C C CN KP@ @ @ @ @F1 1 1 1
. . . .b
 
 
 
& & & &! ! ! !H   :       FJ J J JZ3 3 3 3l| | | |~9 9 9 9x   2  &  :  $ FEE  dcc               K K K K\   : : : :
D D D D          \ \ \ \
! ! ! !! ! ! !   " 9# 9# 9# 9# 9#x9 9 9 9 9$ $ $ $ $N   (0 0 0 0   $8 8 8 8- - - -e e e e   ! ! ! !                     $ $ $ $! ! ! !- - - -       
	 	 	 	 \C \C \C \C \C \C \C \C~F      r   