2011-02-03 14 views
2

私は外部ツールのコマンドラインインターフェイスのパーサを作成しています。私はScalaのパーサーコンビネータライブラリを使用しています。これの一部として、フォーマットEEE MMM d HH:mm:ss yyyy Zの標準日付を解析する必要があります。標準パターンのCharSequenceから日付を解析します。

Scalaのパーサーコンビネータは「ストリームベース」であり、StringsではなくCharSequenceで機能します。そのため、両方ともStringで動作するため、java.text.DateTimeFormatまたはDateTimeFormat(JodaTimeのいずれか)を使用するのが難しくなります。

現在のところ、このような独自の正規表現パーサーを作成して日付を解析することはできませんが、JodaTimeで行った作業をパーサーに組み込むことになります。私は本当にホイールを再構築したくありません。私はJodaTimeのソースコードを見てきました。なぜCharSequencesだけでなくStringを使用する必要があるのか​​よく分かりません。私はいくつかの側面を欠いていますか?

答えて

0

これが今の私のソリューションです:私はジョダ-時間をフォークし、それがString Sの代わりにCharSequenceの上で動作するために小さな変更を加えた

。それはこっちhttps://github.com/hedefalk/joda-time/commit/ef3bdafd89b334fb052ce0dd192613683b3486a4

だそれから私はこのようなDateParserを書くことができます:

trait DateParsers extends RegexParsers { 
    def dateTime(pattern: String): Parser[DateTime] = new Parser[DateTime] { 
    val dateFormat = DateTimeFormat.forPattern(pattern); 

    def jodaParse(text: CharSequence, offset: Int) = { 
     val mutableDateTime = new MutableDateTime 
     val newPos = dateFormat.parseInto(mutableDateTime, text, offset) 
     (mutableDateTime.toDateTime, newPos) 
    } 

    def apply(in: Input) = { 
     val source = in.source 
     val offset = in.offset 
     val start = handleWhiteSpace(source, offset) 
     val (dateTime, endPos) = jodaParse(source, start) 
     if (endPos >= 0) 
     Success(dateTime, in.drop(endPos - offset)) 
     else 
     Failure("Failed to parse date", in.drop(start - offset)) 
    } 
    } 
} 

その後、私のような生成規則には、この特性を使用することができます。

private[this] def dateRow = "date:" ~> dateTime("EEE MMM d HH:mm:ss yyyy Z") 

が、私はこれを過労だろうか?私は今、本当に疲れています...

+0

ああ、私は参照してください。だから本質的には、ネットワークからの次のバイトが来るとすぐdatetime regex lexerが進まなければなりません。フォワードjoda-timeを除いてそれを行う他の方法はないと思われ、regexを使うか、独自のストリームベース/正規表現日時解析ライブラリを作成し、私たちと共有してください。私はまだあなたの答えがここに行く方法だと信じています。 –

+0

ええ、他のストリームベースの日時解析ライブラリは見つかりませんでした。プラスjoda-timeは、とにかく使用するoneandonly date APIです。私はStephen Colebourneに電子メールを送り、CharSequenceを解析することに同意しましたが、後方互換性の問題があるため、何も約束できませんでした。最悪の場合、私は私のフォークを維持する必要があります:) –

+0

そうではありません。私はjoda-timeがすべてのdatetimeのニーズのための最終的なソリューションだとは言いません。私は、joda-timeのパターンが必要なフォーマットを表現できない状況に直面しました.SimpleDateFormat(ISO 8601とRFC 3339にはさまざまなバリエーションがあります)に戻ってしまいました。 –

1

これを取得しました。さて、フォークよりも簡単な解決策があります。ここをクリック:

trait DateParsers extends RegexParsers { 
    def dateTime(pattern: String): Parser[DateTime] = new Parser[DateTime] { 
    val dateFormat = DateTimeFormat.forPattern(pattern); 

    def jodaParse(text: CharSequence, offset: Int) = { 
     val mutableDateTime = new MutableDateTime 
     val maxInput = text.source.subSequence(offset, dateFormat.estimateParsedLength + offset).toString 
     val newPos = dateFormat.parseInto(mutableDateTime, maxInput, 0) 
     (mutableDateTime.toDateTime, newPos + offset) 
    } 

    def apply(in: Input) = { 
     val source = in.source 
     val offset = in.offset 
     val start = handleWhiteSpace(source, offset) 
     val (dateTime, endPos) = jodaParse(source, start) 
     if (endPos >= 0) 
     Success(dateTime, in.drop(endPos - offset)) 
     else 
     Failure("Failed to parse date", in.drop(start - offset)) 
    } 
    } 
} 
+0

申し訳ありませんが、確かに!しかし、入力はまだ 'Reader [Elem]'で、 'CharSequence'を返す' source'メソッドがあります。私はこれを使用して、外部の解析フレームワークにStringを渡すことができる方法を見ていません。私にとっては、これは不可能なもののように思えます。なぜなら、コンビネータはストリームで作業するからです。基本的には、日付文字列にはいくつの文字があるかわからないので、ストリームでも動作する日付パーサーが必要であり、消費したストリームの量に関する情報を返します。 –

+0

最終的な結合パーサーの入力を意味します。作成しようとしているパーザの出力は、日付でなければなりません。 –

+0

@hedefalkこれは 'scala.util.parsing.input.Reader'です。必要なものをサブクラス化することができます。たとえば、トークンを返すためにレクサーを使用し、トークンを使用して処理することができます。明らかではないので、あなたがしようとしていることのいくつかのコードを投稿してください。 –

0

私はあなたが何を求めているのか分かりません。 RegexParser.parse()inパラメータがCharSequenceになる理由を尋ねていますか?あなたがそうのような単純な変換機能を書くことができますReader、かかる他のオーバーロードされたRegexParser.parse()がある場合:日付形式については

def stringToReader(str: String): Reader = new StringReader(str) 

が、私はパーサトークンとして定義することが完全に罰金を見つけます。

これが役に立ちます。

+0

私自身の答えが私の質問を少しはっきりさせましたか?私が達成しようとしているのは、他のパーサーの生産ルールで使用でき、日付を生成するパーサーです。私自身の答えはこれを示していますが、CharSequenceを受け入れるためにjoda-timeを変更しなければなりませんでした。 –

+0

私の質問はScalaのパーサーコンビネータに関するものではありませんが、文字列に作用する "EE MMM d HH:mm:ss yyyy Z"のようなパターンから日付を解析する方法があれば、コンビネータパーサ。 –

関連する問題