読者です 読者をやめる 読者になる 読者になる

みどりねこ日記

よくわからないけど、頑張りますよ。

Kern のプリミティブパーサ

clojure パーサ

Kern にもプリミティブなパーサがあって、これらを組み合わせていくことで大きなパーサを作るというのが関数型らしいパーサの作り方なわけですが。 それらをちょっと見ていきます。 Kern けっこうかわいいわあ。

(use 'blancas.kern.core)

return は常に成功し、与えられた値を返す。

doc.core> (run (return "foo") "xyz")
"foo"
nil

fail は与えられたエラーメッセージとともに失敗する。

doc.core> (:ok (parse (fail "foo") "xyz"))
false
doc.core> (run (fail "this is bad") "xyz")
line 1 column 1
this is bad
nil

satisfy は与えられた述語を入力の最初の文字に適用し、それによって成功か失敗かが決まる。

doc.core> (run (satisfy #(= \x %)) "xyz")
\x
nil

any-char は入力された文字を返す。

doc.core> (run any-char "x")
\x
nil

letter は大文字小文字のどちらも成功する。

doc.core> (run letter "z")
\z
nil

lower, upper はそのまんま。

doc.core> (run lower "a")
\a
nil
doc.core> (run upper "M")
\M
nil

white-space は空白文字を受け付ける。

doc.core> (run white-space "\t")
\tab
nil

space はスペースだけ。 tab もまあそんなかんじ。

doc.core> (run space " ")
\space
nil

digit は \0 から \9 までの数字を受け付ける。 hex-digit はそれに加えて \A から \F まで。 oct-digit は \0 から \7 まで。

doc.core> (run digit "9")
\9
nil

alpha-num は英数字。

doc.core> (run (many alpha-num) "9A")
[\9 \A]
nil

sym* は特定の文字だけ。 sym- は大文字小文字関係なく。ただし結果として得る文字は sym- に渡された文字。

doc.core> (run (sym* \x) "x")
\x
nil

token* は Haskell でいう string パーサ。複数のシーケンスが渡された場合、どれかが成功するまで試され続ける。 token- は大文字小文字関係なく。

doc.core> (run (token* "foo" "bar" "baz") "bazaar")
"baz"
nil

word は token と同じようなものだけれど、許可しない終端を設定できる。 word- は大文字小文字関係なく。

doc.core> (run (word* (one-of* "|-/") "foobar"))
"foobar"
nil
doc.core> (run (word* (one-of* "|-/") "football" "foobar") "foobar*")
"foobar"
nil
doc.core> (run (word* (one-of* "|-/") "foobar") "foobar/")
line 1 column 8
unexpected /
expecting end of foobar
nil

one-of は与えられた文字列のどれかの文字であれば受け付ける。 none-of はその逆。

doc.core> (run (one-of* "xyz") "zap")
\z
nil

new-line* は \n を受け付ける。 eof はもし入力が空なら成功する。

field* は与えられた文字列で区切られる文字列をパースする。

doc.core> (run (field ",;") "California,")
"California"
nil

split-on は空白か与えられた文字列で区切られる文字列を分割する。

doc.core> (run (split-on ",./") "Now, is the time")
["Now" "is the time"]
nil

split は空白で区切られたテキストを分割する。

doc.core> (run split "Now is the time")
["Now" "is" "the" "time"]