任意の電子メール メッセージを入力し、同等の XML エンコーディングを出力できるように取り組んでいます。
メールヘッダーの 1 つである「From ヘッダー」から始めます。
From ヘッダーの例を次に示します。
From: John Doe <john@doe.org>
この XML に変換したい:
<From>
<Mailbox>
<DisplayName>John Doe</DisplayName>
<Address>john@doe.org</Address>
</Mailbox>
</From>
字句解析器 "Alex" ( http://www.haskell.org/alex/doc/html/ ) を使用して、From ヘッダーを分解 (トークン化) したいと考えています。
パーサー「Happy」( http://www.haskell.org/happy/ ) を使用してトークンを処理し、解析ツリーを生成したいと考えています。
次に、シリアライザーを使用して解析ツリーをたどり、XML を出力したいと考えています。
From ヘッダーの形式は、Internet Message Format (IMF) の RFC 5322 ( https://www.rfc-editor.org/rfc/rfc5322 ) で指定されています。
From ヘッダーと必要な XML 出力の例をいくつか次に示します。
表示名のないヘッダーから:
From: <john@doe.org>
必要な XML 出力:
<From>
<Mailbox>
<Address>john@doe.org</Address>
</Mailbox>
</From>
表示名がなく、アドレスが山かっこで囲まれていないヘッダーから:
From: john@doe.org
必要な XML 出力:
<From>
<Mailbox>
<Address>john@doe.org</Address>
</Mailbox>
</From>
それぞれがコンマで区切られた複数のメールボックスを持つヘッダーから:
From: <john@doe.org>, "Simon St. John" <simon@stjohn.org>, sally@smith.org
必要な XML 出力:
<From>
<Mailbox>
<Address>john@doe.org</Address>
</Mailbox>
<Mailbox>
<DisplayName>Simon St. John</DisplayName>
<Address>simon@stjohn.org</Address>
</Mailbox>
<Mailbox>
<Address>sally@smith.org</Address>
</Mailbox>
</From>
RFC 5322 によると、コメントの構文は ( … ) です。以下は、コメントを含む From ヘッダーです。
From: (this is a comment) "John Doe" <john@doe.org>
字句解析中にすべてのコメントを削除したい。
目的の XML 出力は次のとおりです。
<From>
<Mailbox>
<DisplayName>John Doe</DisplayName>
<Address>john@doe.org</Address>
</Mailbox>
</From>
RFC によると、From ヘッダー全体に「折りたたみ空白」が散らばっている可能性があります。以下は、1 行目に From: トークン、2 行目に表示名、3 行目にアドレスを含む From ヘッダーです。
From:
"John Doe"
<john@doe.org>
XML 出力は、折り畳みの空白の影響を受けません。
<From>
<Mailbox>
<DisplayName>John Doe</DisplayName>
<Address>john@doe.org</Address>
</Mailbox>
</From>
RFC によると、アドレスの @ 文字の後には、次のように角かっこで囲まれた文字列を指定できます。
From: "John Doe" <john@[website]>
そのようなメールを見たことがないことを認めなければなりません。それにもかかわらず、RFC はそれが許可されていると述べているので、レクサーとパーサーがそのような入力を処理することは確かに必要です。目的の出力は次のとおりです。
<From>
<Mailbox>
<DisplayName>John Doe</DisplayName>
<Address>john@[website]</Address>
</Mailbox>
</From>
エラー処理
Fromヘッダーが正しくない場合にエラーを生成したい。誤った From ヘッダーと目的の出力の例をいくつか示します。
アドレスの後に表示名が誤って配置されています。
From: <john@doe.org> "John Doe"
出力には、エラーが発見された場所が示されているはずです。
serialize: parse error at line 1 and column 22. Error occurred at "John Doe"
この From ヘッダーには、表示名の前に誤った「23」があります。
From: 23 "John Doe" <john@doe.org>
繰り返しますが、出力にはエラーが発見された場所が示されているはずです。
serialize: parse error at line 1 and column 10. Error occurred at "John Doe"
レクサー、パーサー、シリアライザーの実装方法を教えてください。