2016-03-19 32 views
0

Ben Ayrıştırıcı [java.util.Date]farklı tip

benim yaptığım o iki aşamada, ilk dönmek için combinator ayrıştırıcıları kullanarak verileri ayrıştırmak çalışıyorum başka Ayrıştırıcı oluşturmak için andthen kullanarak Ayrıştırıcı birleştiren

: Ben bir simpleYear ayrıştırıcı kullanarak bir yıl ayrıştırmak, o zaman ben andthen içine bu basit ayrıştırıcı sonucu takmaya çalıştı, ben o zaman bu andthen bir ParseResult [Tarih] çıktısı olarak sahip olmak için bu girişi kullanabilecek

Ne yazık ki ilanının satırında derleyici aşağıdaki hatayı alıyorum:

/

object DateParser extends RegexParsers { 
     val formatter: SimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd") 
     def year = """\d{4}""".r 
     def month: Parser[String] = 
     def day = """[0-2]\d""".r | """3[01]""".r 
     def month = """0\d""".r | """1[0-2]""".r 
     def simpleDate: Parser[String] = 
      (year ~ "-" ~ month ~ "-" ~ day) ^^ 
       { case y ~ "-" ~ m ~ "-" ~ d => y + "-" + m + "-" + d } 

     def date: Parser[Date] = simpleDate andThen { 
      case Success(s, in) => 
       val x: ParseResult[Date] = try { 
        Success(formatter.parse(s), in) 
       } catch { 
        case pe: ParseException => Failure("date format invalid", in) 
       } 
       x 
      case f: Failure => f 
     } 
} 

scala derleyici belki denemede bir Ayrıştırıcı [Tarih] (içine bir örtük dönüştürme kendisi tarih türünden yapamaz gibi görünüyor: Burada

 type mismatch; found : 
parser.DateParser.Input ⇒ parser.DateParser.ParseResult[java.util.Date] (which 
    expands to) 
    scala.util.parsing.input.Reader[Char] ⇒ parser.DateParser.ParseResult[java.util. required: parser.DateParser.Parser[java.util.Date] 

kodudur yakalamak?)

Yapmak istediklerimi yapmanın başka bir yolu var mı?

cevap

1

Parser[T], Input => ParseResult[T] işlevinin bir alt sınıfıdır ve kullanmakta olduğunuz andThen yönteminin işlevi işlevden gelir. Buna ParseResult[String] => ParseResult[Date] işlevine geçiyorsunuz, bu nedenle Parser[Date] türüyle eşleşmeyen Input => ParseResult[Date] geri dönüyorsunuz ve bu yüzden bu hatayı alıyorsunuz.

Ancak, Parser[T] almak için Input => ParseResult[T] türünde bir işlevi yönteminde basitçe sarabilirsiniz. Yani böyle date tanımlayabiliriz: söz konusu

def date: Parser[Date] = Parser(simpleDate andThen { 
    // Cleaned up `Success` case a bit 
    case Success(s, in) => 
    try Success(formatter.parse(s), in) 
    catch { 
     case pe: ParseException => Failure("date format invalid", in) 
    } 
    // It's better to use `NoSuccess` instead of `Failure`, 
    // to cover the `Error` case as well. 
    case f: NoSuccess => f 
}) 

, en iyi/en temiz yöntem değil. onu bir şekilde değiştirmek için ayrıştırıcı sonucunu bir işlevi çağırmak istiyorum gibi, (into ve >> için flatMap eşdeğer ^^ için map eşdeğer) Parser 'ın yöntemleri map ve flatMap veya bunlara denk kullanabilirsiniz. Bunlar, Try veya Future gibi diğer Scala sınıflarının map ve flatMap ile aynı fikre sahiptir.

Bu durumda, hata olasılığını hesaba katmanız gerekir, bu nedenle flatMap'u kullanmanız gerekir. flatMap kullanılarak date bir tanımı aşağıdaki gibi görünebilir:

def date: Parser[Date] = simpleDate >> (s => 
    try success(formatter.parse(s)) 
    catch { case pe: ParseException => failure("date format invalid") }) 

Ayrıca, isteyebilirsiniz olmayan hoşgörülü olmaya formatter ayarlamak için (zaten kendiniz yapmamıştı varsa): formatter.setLenient(false). Aksi takdirde 2 Mart olarak 2000-02-31 ayrıştırma gibi şeyler yapacak! senin büyük cevap

+0

sayesinde ve ayrıca tüm diğer ipuçları. Sana Input => ParseResult [Tarih] üzerindeki Ayrıştırıcı yöntemini uygulamak ve bir Ayrıştırıcı [Tarih] geri almak kullanabilirsiniz gelip nasıl merak ediyorum? api'yi kontrol ettim: http://www.scala-lang.org/api/2.10.3/index.html#scala.util.parsing.combinator.Parsers$Parser Ancak, görünür olarak yasal olarak listelenmiyor. It @Simonlbc – Simonlbc

+1

Parsers' http://www.scala-lang.org/api/2.10.3/index 'de bir yöntem.html # scala.util.parsing.combinator.Parsers "Parsers" ı genişleten "RegexParsers" ı genişletiyorsunuz, böylece onu arayabilirsiniz. – Kolmar