ocamllexでlexerを書くとき、あるシンボルに出会ったら複数のトークンを返したいという時があります。
そういうときは、lexerをこんな風にラップするclosureを書きます。
let cached_tokens = ref [] let cache_token token = cached_tokens := token :: !cached_tokens let gen_cached_lexer normal_lexer = fun lexbuf -> match !cached_tokens with | h :: rest -> cached_tokens := rest; h | _ -> normal_lexer lexbuf let lexbuf = Lexing.from_channel stdin let cached_lexer = gen_cached_lexer MyLexer.main MyParser.input cached_lexer lexbuf
実際に一度のアクションで複数シンボルを返したいとき、例えば先にSTRING "hahaha"を返して、次にHOGEを返したいときは、
cache_token HOGE; (* 次に返すトークンをキャッシュ *) STRING "hahaha" (* 先に返すトークン *)
とすれば、一端 STRING "hahaha"が返りますが、次のパースでHOGEが返ります。