rparsec での繰り返しと選択

2007/12/16 11:10am

rparsec では文法要素の繰り返しを指定する方法が複数用意されている。

繰り返し

まずは「RParsec の many と many_ の違い」でも解説した manymany_ があり、これで m 回以上の繰り返しを指定できる(正規表現でいう *, +, {n,})。

repeat, repeat_ は m 回以上、最大 n 回の繰り返しを指定できる(正規表現でいえば {m,n})。また、some, some_ では最大 n 回の繰り返しを指定できる(正規表現でいえば {0,n}。実際のところ、some は min 引数に 0 を指定して、repeat を呼び出しているにすぎない)。

なお、メソッド名の最後にあるアンダースコアの有無については、「RParsec の many と many_ の違い」で解説したとおりで、アンダースコアのつかないメソッドはすべての結果を配列で返し、アンダースコアのつくメソッドは最後の結果のみを返す。

選択

正規表現でいうところの選択も用意されている。このためのメソッドは | なので、見た目は正規表現と似通っている。

たとえば、以下のコードは、

number | word

数値、または一般的な識別子を解釈するためのパーサになる。

また、文法要素のグループ化は簡単で、通常の Ruby プログラムと同じく括弧で囲めばよい。たとえば、空白区切りの数値、または識別子を解釈するためのパーサは以下のように書ける。

parser = ((number | word) << whitespace.many_).many
parser.parse("123 abc 56.7") => ["123", "abc", "56.7"]

Parser#delimited を使って、もっと直感的に書くこともできる。

parser = (number | word).delimited(whitespaces)
parser.parse("123 abc 56.7") => ["123", "abc", "56.7"]