【问题标题】:Differentiating ints and floats with Scala Combinator Parsers使用 Scala Combinator Parsers 区分整数和浮点数
【发布时间】:2012-12-18 08:22:41
【问题描述】:

我在让 scala 组合器解析器(特别是通过 JavaTokenParsers 的 RegexParsers)在整数和浮点数之间做出决定时遇到了问题。我必须在这里遗漏一些非常基本的东西,因为我似乎无法在任何地方找到任何提及这个特定问题的内容。我已经在有问题的解析器代码中包含了一个规范(当然,减去了)。

@RunWith(classOf[JUnitRunner])
class SandboxSpec extends FlatSpec with ShouldMatchersForJUnit {

  sealed trait PropertyValue

  case class IntValue(value: Int) extends PropertyValue
  case class RealValue(value: Float) extends PropertyValue

  class Parser extends JavaTokenParsers {
    def propertyLiteral : Parser[PropertyValue] = intValue | realValue

    def realValue  = floatingPointNumber ^^ {
      s => RealValue(s.toFloat)
    }

    def intValue  = wholeNumber ^^ {
      s => IntValue(s.toInt)
    }
  }

  "A java token parser" should "parse a float" in {
    val p = new Parser()

    val result = p.parseAll(p.propertyLiteral, "5.4") match {
      case p.Success(x, _) => x
      case p.NoSuccess(msg, _) => fail(msg)
    }

    result should be(RealValue(5.4f))

  }
}

此操作失败并显示以下错误消息:

string matching regex `\z' expected but `.' found

一个想法,基于这个thread,我在整数之后放置了一个<~ not(not('.')),但这似乎并没有解决问题。

【问题讨论】:

    标签: scala parser-combinators


    【解决方案1】:

    您就快到了 - 您唯一需要更改的是将 not(not('.')) 更改为 not('.')。为什么?

    问题是intValue 总是消耗点之前的部分。如果您现在写x ~ '.',则检查是否有一个点,并将其与点之前的部分一起使用。但是你想在没有点的时候消费,所以你必须写x ~ not('.')

    当你写x ~ not(not('.')) 时,你有一个双重否定,它等同于没有否定。这里唯一的区别是这种双重否定允许您查找下一个输入而不使用它。这是因为在失败时输入不会被消耗以允许以下解析器再次解析它。对于双重失败,您既不会消耗任何东西,也不会实现已经提到的查找。

    【讨论】:

    • 我知道这很简单,只是路过我...谢谢!
    猜你喜欢
    • 1970-01-01
    • 2012-02-11
    • 1970-01-01
    • 1970-01-01
    • 2018-08-04
    • 2017-07-21
    • 2011-01-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多