【问题标题】:Parsing error when trying to parse comma-delimited key-value pairs with values containing list separated by commas尝试使用包含逗号分隔的列表的值解析逗号分隔的键值对时出现解析错误
【发布时间】:2020-09-22 14:21:18
【问题描述】:

我有这门课:

import scala.util.parsing.combinator.JavaTokenParsers

class RequestMappingParser extends JavaTokenParsers {
  def key: Parser[String] = "value" | "method" | "consumes" | "params"
  def singleValue: Parser[String] = """[^),]*""".r
  def multipleValues: Parser[String] = "{" ~ repsep(ident, ",") ~ "}" ^^ {
    case "{" ~ lst ~ "}" => lst.mkString(", ")
  }
  def value: Parser[String] = multipleValues | singleValue
  def keyValue: Parser[(String, String)] = (key ~ "=" ~ value).map {
    case k ~ _ ~ v => k -> v
  }
  def commaDelimitedSeq: Parser[Map[String, String]] = repsep(keyValue, ",").map(_.toMap)

  def requestMapping: Parser[MethodRequestMapping] = ("@RequestMapping(" ~ commaDelimitedSeq ~ ")").map {
    case _ ~ map ~ _ =>
      val consumes = if (map.contains("consumes")) Some(map("consumes")) else None
      val value = if (map.contains("value")) Some(map("value")) else None
      val method = if (map.contains("method")) Some(map("method")) else None
      val params = if (map.contains("params")) Some(map("params")) else None
      new MethodRequestMapping(value = value, method = method, consumes = consumes, params = params)
  }
}

我有这个测试:

  test("@RequestMapping – params") {
    val parser = new RequestMappingParser()
    val requestMappingStr = """@RequestMapping(
                   |  value = "/ex/bars",
                   |  params = { "id", "second" },
                   |  method = GET)""".stripMargin
    val parseResult = parser.parse(parser.requestMapping, requestMappingStr)
    val result = parseResult.get
    assert(result.value.get.equals("\"/ex/bars\""))
    assert(result.method.get.equals("GET"))
    assert(result.params.get.equals("{ \"id\", \"second\" }"))
  }

但测试失败并出现此解析错误:

[3.18] failure: ')' expected but ',' found

  params = { "id", "second" },
                 ^

我使用的是 Scala 2.13。我在这里有什么问题?

【问题讨论】:

  • 你用的是哪个 scala 版本?
  • Scala 版本 2.13

标签: regex scala parsing


【解决方案1】:
import scala.util.parsing.combinator.JavaTokenParsers

class RequestMappingParser extends JavaTokenParsers {
  def key: Parser[String] = "value" | "method" | "consumes" | "params"
  def singleValue: Parser[String] = """[^),]*""".r
  def multipleValues: Parser[String] = "{" ~ repsep(stringLiteral, ",") ~ "}" ^^ {
    case "{" ~ lst ~ "}" => "{ " + lst.mkString(", ") + " }"
  }
  def value: Parser[String] = multipleValues | singleValue
  def keyValue: Parser[(String, String)] = (key ~ "=" ~ value).map {
    case k ~ _ ~ v => k -> v
  }
  def commaDelimitedSeq: Parser[Map[String, String]] = repsep(keyValue, ",").map(_.toMap)

  def requestMapping: Parser[MethodRequestMapping] = ("@RequestMapping(" ~ commaDelimitedSeq ~ ")").map {
    case _ ~ map ~ _ =>
      val consumes = if (map.contains("consumes")) Some(map("consumes")) else None
      val value = if (map.contains("value")) Some(map("value")) else None
      val method = if (map.contains("method")) Some(map("method")) else None
      val params = if (map.contains("params")) Some(map("params")) else None
      new MethodRequestMapping(value = value, method = method, consumes = consumes, params = params)
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-29
    • 1970-01-01
    相关资源
    最近更新 更多