Parsec コードを書くときは、解析したい文法を最初にBNF形式で書き出すと便利です。なぜなら、Parsec で書かれたパーサーは最終的に文法に非常によく似たものになるからです。
それを試してみましょう:
line ::= garbage '#' field ',' field ',' field '%' garbage
上記のプロダクションでは、 という名前のプロダクションを想定しgarbage
ています。その実際の定義は、実際にドロップしたいテキストによって異なります。同様に、 という名前のプロダクションを想定していfield
ます。それでは、この生成物をパーセク コードとして書き出しましょう。
line = do
garbage
char '#'
field1 <- field
char ','
field2 <- field
char ','
field3 <- field
char '%'
garbage
return (field1, field2, field3)
このコードは、BNF とまったく同じように読み取ります。本質的な違いは、一部のサブプロダクションの結果に名前が付けられているため、これらの結果から構築された値 (この場合はタプル) を返すことができることです。
ガベージの概念が何であるかはわかりませんが、例のために、空白を意味すると仮定しましょう。garbage
次に、次のように定義できます。
garbage = many space
(あるいは、 parsec が と呼ばれる 0 個以上のスペースを解析するためのコンビネータを既に持っている場合もありますspaces
)。ガベージが区切り文字以外の何かである可能性がある場合、次の#
ように言うことができます
garbage = many (noneOf "#")
この行は、最初の「#」までのすべての入力をむしゃむしゃ食べます。いずれにせよgarbage
、名前を値にバインドしていないため、結果として生成される値は破棄されます。