SSブログ

Camlp4 のストリームパーサ [OCaml]

Camlp4 に用意されているストリームパーサを使うと前回 [1] 作った Tcl インタプリタの以下のような部分がもっとすっきり書きなおせる。例えば、

comment (interp, strm, state) =
    match (Stream.peek strm) with
    | Some '\n' -> Stream.junk strm; eval (interp, strm, state)
    | Some '\\' -> Stream.junk strm; ignore (backslash strm); comment (interp, strm, state)
    | Some _    -> Stream.junk strm; comment (interp, strm, state)
    | None      -> eval (interp, strm, state)

これが以下のようになる。ソースの先頭で #load "camlp4.cma";; とする。

comment (interp, strm, state) = (parser
      [< ''\n' >] -> eval (interp, strm, state)
    | [< ''\\' >] -> ignore (backslash strm); comment (interp, strm, state)
    | [< '_ >]    -> comment (interp, strm, state)
    | [< >]       -> eval (interp, strm, state)
    ) strm

これだと Stream.junk とか書かなくてよいし、また書く場合と書かない場合に注意しなくてよいのでかなりよい。なるほど、これは便利だ。

実際このコードを camlp4o -I . pr_o.cmo otcl2.ml > a などとすると、以下のようなコードに変換されているのが分かる。

comment (interp, strm, state) =
  (fun (strm__ : _ Stream.t) ->
     match Stream.peek strm__ with
       Some '\n' -> Stream.junk strm__; eval (interp, strm, state)
     | Some '\\' ->
         Stream.junk strm__;
         begin ignore (backslash strm); comment (interp, strm, state) end
     | Some _ -> Stream.junk strm__; comment (interp, strm, state)
     | _ -> eval (interp, strm, state))
    strm

元々のコードとかなりぴったり一致する。あとこのコードを見て分かったのは Genlex のソースも元々は Camlp4 のストリームパーサを使ったものから変換しているっぽい。strm__ という変数名とかが一致するし。なんかぐるっと遠回りしてたどり着いた感じだ。

[1] http://blog.so-net.ne.jp/rainyday/2006-09-25


nice!(0)  コメント(0)  トラックバック(0) 
共通テーマ:パソコン・インターネット

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

ひらメソッド+GNU GLOBALCodeReadingWiki ブログトップ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。