Вот моя попытка написать небольшой парсер для положительныхInt
с:Как я могу заставить мой парсер изящно сработать, если будет сделано исключение?
import scala.util.parsing.combinator.RegexParsers
object PositiveIntParser extends RegexParsers {
private def positiveInt: Parser[Int] = """0*[1-9]\d*""".r ^^ { _.toInt }
def apply(input: String): Option[Int] = parseAll(positiveInt, input) match {
case Success(result, _) => Some(result)
case _ => None
}
}
Проблема заключается в том, что, если входная строка слишком длинная, toInt
бросает NumberFormatException
, что делает мой парсер взрывать:
scala> :load PositiveIntParser.scala
Loading PositiveIntParser.scala...
import scala.util.parsing.combinator.RegexParsers
defined object PositiveIntParser
scala> PositiveIntParser("12")
res0: Option[Int] = Some(12)
scala> PositiveIntParser("-12")
res1: Option[Int] = None
scala> PositiveIntParser("123123123123123123")
java.lang.NumberFormatException: For input string: "123123123123123123"
at ...
Вместо этого я хочу, чтобы мой positiveInt
анализатора неудачи изящно (возвращая Failure
), когда toInt
бросает исключение. Как я могу это сделать?
Легкое исправление, которое приходит на ум, состоит в том, чтобы ограничить длину строк, принятых моим регулярным выражением, но это неудовлетворительно.
Я предполагаю, что анализатор комбинатор для этого случая использования уже предусмотрен scala.util.parsing.combinator
библиотеку, но я не смог найти один ...
Спасибо. '^?' - это комбинатор, которого я отсутствовал. В конце я пошел на: 'private def positiveInt: Parser [Int] = { def safeToInt (str: String) = Try (str.toInt) " "" \ d + "" ". R ^^ safeToInt ^? {case scala.util.Success (результат), если результат> 0 => результат} } '. – Jubobs
Вы можете использовать 'Function.unlift' для преобразования функции, возвращающей' Option' в 'PartialFunction'. Например, "" "" 0 * [1-9] \ d * "" ". R ^? Function.unlift {x => Try (x.toInt) .toOption} ' – Kolmar