Search code examples
ocamlocamllex

How to use lexer generated by ocamllex


I have a trivial lexer taken from a tutorial (http://plus.kaist.ac.kr/~shoh/ocaml/ocamllex-ocamlyacc/ocamllex-tutorial/sec-ocamllex-some-simple-examples.html)

{ }
rule translate = parse
  | "c"         { print_string (Sys.getcwd ()); translate lexbuf }
  | _ as c      { print_char c; translate lexbuf }
  | eof         { exit 0 }

After generating the lexer OCaml and creating an executable,

ocamllex testlexer.mll && ocamlc -o testlexer testlexer.ml

I attempt to pass content in via stdin echo c | ./testlexer and via a file ./testlexer input, but neither works.

I also don't see any logic in the generated testlexer.ml for reading from stdin or a file, is it meant to be included as a module in another program or consumed by another code generation tool like ocamlyacc?


Solution

  • You need a main function (in essence). You can adapt it from the other examples on that page.

    Here's a full example that I wrote up:

    { }
    rule translate = parse
      | "c"         { print_string (Sys.getcwd ()); translate lexbuf }
      | _ as c      { print_char c; translate lexbuf }
      | eof         { exit 0 }
    
    {
      let main () =
        let lexbuf = Lexing.from_channel stdin in translate lexbuf
    
      let () = main ()
    }
    

    It seems to work as intended:

    $ ocamllex l.mll
    4 states, 257 transitions, table size 1052 bytes
    $ ocamlc -o l l.ml
    $ echo c/itworks | ./l
    /home/jeffsco/tryll2/itworks
    

    Update

    Sorry, I forgot to answer your other questions. Yes, without the main function, the original code can be a module in a larger program. It could be a program that users ocamlyacc, or not.