Скала 2.8.1
Я реализовал очень простой внешний DSL, используя парсер/комбинатор для контроля качества, чтобы написать приемочные тесты.
Недавно я добавил возможность зацикливаться на наборе выражений, например так
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)
}