3

私はScala でパーサー コンビネーターを使用して SemVer ( http://semver.org ) パーサーを作成しようとしています。

これは私の現在のコードです:

case class SemVer(major: Int, minor: Int, patch: Int, prerelease: Option[List[String]], metadata: Option[List[String]]) {
  override def toString = s"$major.$minor.$patch" + prerelease.map("-" + _.mkString(".")).getOrElse("") + metadata.map("+" + _.mkString("."))
}

class VersionParser extends RegexParsers {
  def number: Parser[Int] = """(0|[1-9]\d*)""".r ^^ (_.toInt)
  def separator: Parser[String] = """\.""".r
  def prereleaseSeparator: Parser[String] = """-""".r
  def metadataSeparator: Parser[String] = """\+""".r
  def identifier: Parser[String] = """([0-9A-Za-z-])+""".r ^^ (_.toString)

  def prereleaseIdentifiers: Parser[List[String]] = (number | identifier) ~ rep(separator ~> (number | identifier)) ^^ {
    case first ~ rest => List(first.toString) ++ rest.map(_.toString)
  }

  def metadataIdentifiers: Parser[List[String]] = identifier ~ rep(separator ~> identifier) ^^ {
    case first ~ rest => List(first.toString) ++ rest.map(_.toString)
  }
}

プレリリース セクションの識別子を解析する方法を知りたいのですが、数値識別子の先行ゼロが許可されておらず、現在のパーサーを使用して先行ゼロ (たとえば "01.2.3") を解析しようとすると、単純にリストになるためです。要素 0 を含みます。

より一般的には、文字列が SemVer 仕様に準拠していないことをどのように検出し、その結果、障害状態を強制する必要がありますか?

4

2 に答える 2

1

いくつか遊んで検索した後、parseメソッドではなくメソッドを呼び出していたことが問題であることがわかりましたparseAllparse基本的にはできる限り解析し、解析できなくなったら終了するため、部分的に正しい文字列を受け入れることは可能です。を使用parseAllすると、すべての入力が強制的に解析され、解析が停止した後に入力が残っている場合は失敗します。これはまさに私が探していたものです。

于 2015-02-12T06:53:20.557 に答える