Parsec 文字や文字列の繰り返し

文字列のマッチングを考えるとき、文字や文字集合の繰り返しを検出したいことはよくある。Parsec の繰り返しに関するコンビネータには、many, many1, skipMany, skipMany1 がある。例えば、letter パーサは数字以外のキャラクタにマッチするので。次のパーサ word は、キャラクタが連続する文字列にマッチする。

word = many letter

Hugs のプロンプトで実験した結果は次のようになる。

Hugs> :l Text.ParserCombinators.Parsec
Text.ParserCombinators.Parsec> parseTest word "abcdef123" where word = many letter
"abcdef"

many と many1 があるが、many は 0 回以上の繰り返しにマッチし、many1 は 1 以上の繰り返しにマッチするという違いがある。

Text.ParserCombinators.Parsec> parseTest (do {char 'a'; many (char 'b')}) "abcdef"
"b"

Text.ParserCombinators.Parsec> parseTest (do {char 'a'; many (char 'b')}) "acdef"
""

Text.ParserCombinators.Parsec> parseTest (do {char 'a'; many1 (char 'b')}) "abcdef"
"b"

Text.ParserCombinators.Parsec> parseTest (do {char 'a'; many1 (char 'b')}) "acdef"
parse error at (line 1, column 2):
unexpected "c"
expecting "b"

また、skipMany, skipMany1 というのがある。many と many1 と同じマッチングをするが、入力の文字列を消費するだけで、結果は返さない。

Text.ParserCombinators.Parsec> parseTest (skipMany (char 'a')) "aaaabc"
()

実験では、繰り返しの要素が letter, char 'a' などの一文字だったが、"hello" などの文字列に対しても、many などは使うことができる。

繰り返しのコンビネータが揃ったので、パターンマッチの道具立てがだんだんできてきた。道具が揃ったら、Parsec を使いこなすための知識は、これらの道具を使ってパーサ関数をどう記述するかということになる。Parsec で何ができるかというのが少し分かり始めた。
[PR]
by tnomura9 | 2009-09-30 06:10 | Haskell | Comments(0)
<< Parsec セパレータ Parsec パターンの再帰的定義 >>