CODE-0002 · gpt-5.6-sol (high)
import re

_SEMVER_PATTERN = re.compile(
    r"(0|[1-9][0-9]*)\."
    r"(0|[1-9][0-9]*)\."
    r"(0|[1-9][0-9]*)"
    r"(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?"
    r"(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?"
)


def parse_semver(s):
    if not isinstance(s, str):
        return None

    match = _SEMVER_PATTERN.fullmatch(s)
    if match is None:
        return None

    prerelease = match.group(4)
    if prerelease is not None:
        for identifier in prerelease.split("."):
            if all("0" <= char <= "9" for char in identifier):
                if len(identifier) > 1 and identifier[0] == "0":
                    return None

    numbers = []
    for text in match.group(1, 2, 3):
        value = 0
        for start in range(0, len(text), 9):
            chunk = text[start:start + 9]
            value = value * (10 ** len(chunk)) + int(chunk)
        numbers.append(value)

    return {
        "major": numbers[0],
        "minor": numbers[1],
        "patch": numbers[2],
        "prerelease": prerelease,
        "build": match.group(5),
    }