code: private Version parseValidSemVer() {
      NormalVersion normal = parseVersionCore();
      MetadataVersion preRelease = MetadataVersion.NULL;
      MetadataVersion build = MetadataVersion.NULL;
  
      Character next = consumeNextCharacter(CharType.HYPHEN, CharType.PLUS, CharType.EOL);
      if (CharType.HYPHEN.isMatchedBy(next)) {
        preRelease = parsePreRelease();
        next = consumeNextCharacter(CharType.PLUS, CharType.EOL);
        if (CharType.PLUS.isMatchedBy(next)) {
          build = parseBuild();
        }
      } else if (CharType.PLUS.isMatchedBy(next)) {
        build = parseBuild();
      }
      consumeNextCharacter(CharType.EOL);
      return new Version(normal, preRelease, build);
    }
docs: Parses the {@literal <valid semver>} non-terminal.
  
  <pre>
  {@literal
  <valid semver> ::= <version core>
  | <version core> "-" <pre-release>
  | <version core> "+" <build>
  | <version core> "-" <pre-release> "+" <build>
  }
  </pre>
  
  @return a valid version object