Scala 2.8.1
我使用解析器/组合器实现了一个非常简单的外部DSL,用于QA编写验收测试。
最近我添加了循环遍历一组表达式的能力
sealed trait Expr
...
//insert other case classes extending 'Expr' here
...
case class Repetition(times: Int, expressions: List[Expr]) extends Expr
class TestFixtureParser(....) extends RegexParsers {
val repeatParser: Parser[Expr] = (l("repeat") ~> number) ~ (l("{") ~> expressions <~ l("}")) ^^ {
case (times: Int) ~ (exprs: List[Expr]) => {
Repetition(times, exprs)
}
}
private val expressions: Parser[List[Expr]] = (repeatParser |
/*insert other Parser[Expr]s '|' together here */ | verifyParser ).*
}
构建时,我会在模式匹配时收到警告warning: non variable type-argument ... is unchecked since it is eliminated by erasure
。我也试过使用以下内容进行提取。
//Doesn't build with error
/*
error: missing parameter type for expanded function ((x0$2) => x0$2 match {
case $tilde((times @ _), (exprs @ _)) => Repetition(times, exprs)
})
r: ~[Int, List[Expr]] => {
*/
val repeatParser: Parser[Expr] = (l("repeat") ~> number) ~ (l("{") ~> expressions <~ l("}")) ^^ {
r: ~[Int, List[Expr]] => {
case times ~ exprs =>
Repetition(times, exprs)
}
}
//Actually this does build without warning.
//I am unfortunately using intelliJ and it doesn't like it
val repeatParser: Parser[Expr] = (l("repeat") ~> number) ~ (l("{") ~> expressions <~ l("}")) ^^ {
repetitions: ~[Int, List[Expr]] => {
val ~(times, exprs) = repetitions
Repetition(times, exprs)
}
}
//Builds but same warning
val repeatParser: Parser[Expr] = (l("repeat") ~> number) ~ (l("{") ~> expressions <~ l("}")) ^^ {
repetitions => {
val ~(times: Int, exprs: List[Expr]) = repetitions
Repetition(times, exprs)
}
}
有没有人建议在没有此警告的情况下以优雅的方式提取exprs
?它确实起作用。我应该忽略它吗?我不想养成忽视警告的习惯。
编辑:回答。这实际上是我首先尝试但后来我添加了类型因为intelliJ scala插件无法推断它们。
val repeatParser: Parser[Expr] = (l("repeat") ~> number) ~ (l("{") ~> expressions <~ l("}")) ^^ {
case times ~ exprs =>
Repetition(times, exprs)
}
答案 0 :(得分:5)
我认为你的语法不适合第一个“不构建”的例子(看起来你正在返回一个部分函数而不是应用它,这不是你想要的)。尝试 写作:
val repeatParser: Parser[Expr] = (l("repeat") ~> number) ~ (l("{") ~> expressions <~ l("}")) ^^ {
case times ~ exprs =>
Repetition(times, exprs)
}
我担心我无法对此进行测试,因为我没有其余的代码 取决于,但这种结构通常有效。
答案 1 :(得分:2)
接受的答案是最好的,但是如果不起作用,这里有替代方案:
r: ~[t1, t2] => {
case times ~ exprs =>
Repetition(times, exprs)
}
以上,t1
和t2
推断,它们可能只是推断为Any
。然而,无论它们被推断出来,它都是你用这种语法做的最好的。
val ~(times: Int, exprs: List[t]) = repetitions
这里,因为您要提取值,所以您可以实际检查类型。您没有测试是否有~[Int,List[Int]]
- 您正在测试提取的值是否具有类型Int
和List[t]
。请注意,您收到的警告来自List
的类型参数。