src/Parser/SubtypeParser.php
protected function parseCurrentCharacter(): ?string
    {
        switch ($this->getCurrentState()) {
            case self::STATE_UNKNOWN:
                $this->setCurrentState(self::STATE_IN_TYPE);
                break;

            case self::STATE_IN_TYPE:
                if ($this->isCurrentCharacterTypeSubtypeSeparator()) {
                    $this->setCurrentState(self::STATE_IN_SUBTYPE);
                }

                $this->incrementCurrentCharacterPointer();

                break;

            case self::STATE_IN_SUBTYPE:
                if ($this->isCurrentCharacterInvalid()) {
                    $this->setCurrentState(self::STATE_INVALID_INTERNAL_CHARACTER);
                } elseif ($this->isCurrentCharacterTypeParameterSeparator()) {
                    $this->setCurrentState(self::STATE_LEFT_SUBTYPE);
                } else {
                    $this->appendOutputString();
                    $this->incrementCurrentCharacterPointer();
                }

                break;

            case self::STATE_LEFT_SUBTYPE:
                $this->stop();
                break;

            case self::STATE_INVALID_INTERNAL_CHARACTER:
                if ($this->shouldAttemptToFixInvalidInternalCharacter()) {
                    $this->hasAttemptedToFixAttributeInvalidInternalCharacter = true;

                    $fixer = new TypeFixer();
                    $fixer->setInputString($this->getInputString());
                    $fixer->setPosition($this->getCurrentCharacterPointer());
                    $fixedType = $fixer->fix();

                    return $this->parse($fixedType);
                }

                throw new SubtypeParserException(
                    'Invalid internal character after at position '.$this->getCurrentCharacterPointer(),
                    SubtypeParserException::INTERNAL_INVALID_CHARACTER_CODE,
                    $this->getCurrentCharacterPointer()
                );
        }

        return null;
    }
protected function parseCurrentCharacter(): ?string
    {
        switch ($this->getCurrentState()) {
            case self::STATE_UNKNOWN:
                $this->setCurrentState(self::STATE_IN_TYPE);
                break;

            case self::STATE_IN_TYPE:
                if ($this->isCurrentCharacterTypeSubtypeSeparator()) {
                    $this->setCurrentState(self::STATE_IN_SUBTYPE);
                }

                $this->incrementCurrentCharacterPointer();

                break;

            case self::STATE_IN_SUBTYPE:
                if ($this->isCurrentCharacterInvalid()) {
                    $this->setCurrentState(self::STATE_INVALID_INTERNAL_CHARACTER);
                } elseif ($this->isCurrentCharacterTypeParameterSeparator()) {
                    $this->setCurrentState(self::STATE_LEFT_SUBTYPE);
                } else {
                    $this->appendOutputString();
                    $this->incrementCurrentCharacterPointer();
                }

                break;

            case self::STATE_LEFT_SUBTYPE:
                $this->stop();
                break;

            case self::STATE_INVALID_INTERNAL_CHARACTER:
                if ($this->shouldAttemptToFixInvalidInternalCharacter()) {
                    $this->hasAttemptedToFixAttributeInvalidInternalCharacter = true;

                    $fixer = new TypeFixer();
                    $fixer->setInputString($this->getInputString());
                    $fixer->setPosition($this->getCurrentCharacterPointer());
                    $fixedType = $fixer->fix();

                    return $this->parse($fixedType);
                }

                throw new SubtypeParserException(
                    'Invalid internal character after at position '.$this->getCurrentCharacterPointer(),
                    SubtypeParserException::INTERNAL_INVALID_CHARACTER_CODE,
                    $this->getCurrentCharacterPointer()
                );
        }

        return null;
    }
@return string

@throws SubtypeParserException