private function parseArrayIndexExpression()
    {
        static $matchNext = [
            T::T_NUMBER   => true,
            T::T_COLON    => true,
            T::T_RBRACKET => true
        ];

        $pos = 0;
        $parts = [null, null, null];
        $expected = $matchNext;

        do {
            if ($this->token['type'] == T::T_COLON) {
                $pos++;
                $expected = $matchNext;
            } elseif ($this->token['type'] == T::T_NUMBER) {
                $parts[$pos] = $this->token['value'];
                $expected = [T::T_COLON => true, T::T_RBRACKET => true];
            }
            $this->next($expected);
        } while ($this->token['type'] != T::T_RBRACKET);

        // Consume the closing bracket
        $this->next();

        if ($pos === 0) {
            // No colons were found so this is a simple index extraction
            return ['type' => 'index', 'value' => $parts[0]];
        }

        if ($pos > 2) {
            throw $this->syntax('Invalid array slice syntax: too many colons');
        }

        // Sliced array from start (e.g., [2:])
        return [
            'type'     => 'projection',
            'from'     => 'array',
            'children' => [
                ['type' => 'slice', 'value' => $parts],
                $this->parseProjection(self::$bp[T::T_STAR])
            ]
        ];
    }
private function parseArrayIndexExpression()
    {
        static $matchNext = [
            T::T_NUMBER   => true,
            T::T_COLON    => true,
            T::T_RBRACKET => true
        ];

        $pos = 0;
        $parts = [null, null, null];
        $expected = $matchNext;

        do {
            if ($this->token['type'] == T::T_COLON) {
                $pos++;
                $expected = $matchNext;
            } elseif ($this->token['type'] == T::T_NUMBER) {
                $parts[$pos] = $this->token['value'];
                $expected = [T::T_COLON => true, T::T_RBRACKET => true];
            }
            $this->next($expected);
        } while ($this->token['type'] != T::T_RBRACKET);

        
        $this->next();

        if ($pos === 0) {
            
            return ['type' => 'index', 'value' => $parts[0]];
        }

        if ($pos > 2) {
            throw $this->syntax('Invalid array slice syntax: too many colons');
        }

        
        return [
            'type'     => 'projection',
            'from'     => 'array',
            'children' => [
                ['type' => 'slice', 'value' => $parts],
                $this->parseProjection(self::$bp[T::T_STAR])
            ]
        ];
    }
private function parseArrayIndexExpression ( ) { static $ matchNext = [ T :: T_NUMBER => true , T :: T_COLON => true , T :: T_RBRACKET => true ] ; $ pos = 0 ; $ parts = [ null , null , null ] ; $ expected = $ matchNext ; do { if ( $ this -> token [ 'type' ] == T :: T_COLON ) { $ pos ++ ; $ expected = $ matchNext ; } elseif ( $ this -> token [ 'type' ] == T :: T_NUMBER ) { $ parts [ $ pos ] = $ this -> token [ 'value' ] ; $ expected = [ T :: T_COLON => true , T :: T_RBRACKET => true ] ; } $ this -> next ( $ expected ) ; } while ( $ this -> token [ 'type' ] != T :: T_RBRACKET ) ; // Consume the closing bracket $ this -> next ( ) ; if ( $ pos === 0 ) { // No colons were found so this is a simple index extraction return [ 'type' => 'index' , 'value' => $ parts [ 0 ] ] ; } if ( $ pos > 2 ) { throw $ this -> syntax ( 'Invalid array slice syntax: too many colons' ) ; } // Sliced array from start (e.g., [2:]) return [ 'type' => 'projection' , 'from' => 'array' , 'children' => [ [ 'type' => 'slice' , 'value' => $ parts ] , $ this -> parseProjection ( self :: $ bp [ T :: T_STAR ] ) ] ] ; }
Parses an array index expression (e.g., [0], [1:2:3]
Parses an array index expression ( e . g . [ 0 ] [ 1 : 2 : 3 ]