protected function parseInput(string $native, int &$pos): Range
    {
        switch ($char = $this->nextChar($native, $pos)) {
            case '(':
            case '[':
                $pos++;
                $lowerInclusive = '[' === $char;
                break;

            case 'e':
            case 'E':
                if (preg_match('/empty/Ai', $native, $m, 0, $pos)) {
                    $pos += 5;
                    return call_user_func([$this->resultClass, 'createEmpty']);
                }
                // fall-through is intentional
            default:
                throw TypeConversionException::parsingFailed($this, '[ or (', $native, $pos);
        }

        $lower = $this->readRangeBound($native, $pos);
        $this->expectChar($native, $pos, ',');
        $upper = $this->readRangeBound($native, $pos);

        if (']' === $native[$pos]) {
            $upperInclusive = true;
            $pos++;

        } elseif (')' === $native[$pos]) {
            $upperInclusive = false;
            $pos++;

        } else {
            throw TypeConversionException::parsingFailed($this, '] or )', $native, $pos);
        }

        return new $this->resultClass(
            $this->subtypeConverter->input($lower),
            $this->subtypeConverter->input($upper),
            $lowerInclusive,
            $upperInclusive
        );
    }