【问题标题】:How to parse two different types in one parser in Scala?如何在 Scala 的一个解析器中解析两种不同的类型?
【发布时间】:2015-07-11 22:18:38
【问题描述】:

我编写了以下部分代码来解析表达式中的 RDD 类型和浮点数。解析一个由 float 和 RDD 组成的算术表达式,例如:“firstRDD + 2”:

def term2: Parser[List[Either[Float, RDD[(Int,Array[Float])]]]] = rep(factor2)
def factor2: Parser[Either[Float, RDD[(Int,Array[Float])]]] = pathxml | num  
def pathxml: Parser[RDD[(Int,Array[Float])]] = pathIdent ^^ {s => pathToRDD(s) } //pathToRDD is a function that gets the path in string and create an RDD from the file inside that path and pathIdent parse to see whether the input string is a path or not
def num: Parser[Float] = floatingPointNumber ^^ (_.toFloat)

现在我收到此错误:

  [error] type mismatch;
  [error]  found   : ParseExp.this.Parser[Float]
  [error]  required: ParseExp.this.Parser[Either[Float,org.apache.spark.rdd.RDD[(Int, Array[Float])]]]
  [error]   def factor2: Parser[Either[Float, RDD[(Int,Array[Float])]]] = pathxml | num 
  [error]                                                                           ^

除了使用“Either”之外,我不知道该怎么做,也不知道如何解决这种类型不匹配! 请注意,如果我使用“Any”,则无法解析 RDD。

【问题讨论】:

标签: scala parsing rdd type-mismatch


【解决方案1】:

它想要一个Either 而不是Float,所以你给它一个Either。 但我们不能简单地从输出中创造价值,因为 解析器使用函数,而不是值。

def num: Parser[Either[Float, RDD[(Int,Array[Float])]]] = floatingPointNumber ^^ (n => Left(n).toFloat)

并希望它有效。如果没有,请走很长的路:

def num: Parser[Either[Float, RDD[(Int,Array[Float])]]] = floatingPointNumber ^^ (n =>
  val res: Either[Float, RDD[(Int,Array[Float])]] = n.toFloat
  res
)

或者 scalaz 路由(你必须重写代码才能使用\/ 而不是Either:

import scalaz._
import Scalaz._

def term2: Parser[List[\/[Float, RDD[(Int,Array[Float])]]]] = rep(factor2)
def factor2: Parser[\/[Float, RDD[(Int,Array[Float])]]] = pathxml | num
def pathxml: Parser[RDD[(Int,Array[Float])]] = pathIdent ^^ {s => pathToRDD(s) } //pathToRDD is a function that gets the path in string and create an RDD from the file inside that path and pathIdent parse to see whether the input string is a path or not
def num: Parser[\/[Float, RDD[(Int,Array[Float])]]] = floatingPointNumber ^^ (n => n.left[RDD[(Int,Array[Float])]].toFloat)

leftright 来自 scalaz 几乎可以满足您的期望 - 他们创造了一个左或右的价值。您传递给的类型参数 left 或 right 用于构造完整类型,因为值 只提供左或右类型,但完整的任何一种类型都需要 另一侧的类型(右/左)也是如此,所以其他类型 也需要通过。

另一方面,我认为您稍后会收到类似的错误消息 路径xml。以类似的方式修复它,除了使用Right 而不是Left

【讨论】:

  • 感谢您的帮助。我正在使用 Scala 组合器解析器。 ".left[..]" 在这里做什么?因为 num 的类型是 Float,而 pathexml 是 RDD。
  • .left 来自scalaz,我最近用过,所以这就是我本能使用的。来自 stdlib 的 Either 有点混乱。我重新排序了代码 sn-ps。
  • 知道了,一开始需要什么特定的导入吗?我收到“.left”的错误说:左值不是 ParseExp.this.Parser[Float] 的成员
  • 试试第二个 sn-p 是否有效(重新加载页面,我重新编写了东西)。
  • 参见github.com/scalaz/scalaz - 但它也不起作用,因为解析器 api 需要函数,而不是值。让我想想。
猜你喜欢
  • 2019-09-07
  • 2018-02-28
  • 2019-04-25
  • 1970-01-01
  • 2020-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多