(* Example ocamllex file *) { (* Header section *) open Lexing exception LexError of string type token = INT of int | STRING of string | EOF;; let incr_lineno lexbuf = let pos = lexbuf.lex_curr_p in lexbuf.lex_curr_p <- { pos with pos_lnum = pos.pos_lnum + 1; pos_bol = pos.pos_cnum; } } (* definition section *) let cr='\013' let nl='\010' let eol=(cr nl|nl|cr) let ws=('\012'|'\t'|' ') let digit=['0'-'9'] (* rules section *) rule lexer = parse | eol { incr_lineno lexbuf; lexer lexbuf } | ws+ { lexer lexbuf } | digit+ as n { INT(int_of_string(n)) } | '"' { STRING(string (Buffer.create 100) lexbuf) } | eof { EOF } | _ { raise (LexError ("lex error, unknown token: " ^ (Lexing.lexeme lexbuf))) } (* rule to parse string literals (which can include escaped double quotes) *) and string buf = parse (* use buf to build up result *) | [^'"' '\n' '\\']+ as s { Buffer.add_string buf @@ s ; string buf lexbuf } | '\\' '"' { Buffer.add_char buf '"' ; string buf lexbuf } | '\\' { Buffer.add_char buf '\\' ; string buf lexbuf } | '"' { Buffer.contents buf } (* return *) | _ { raise (LexError ("lex error, unknown token: " ^ (Lexing.lexeme lexbuf))) } { (* Trailer secton *) (* some code showing how to use the lexer *) let lb = Lexing.from_string "342 \"hello world\"" in let rec f ts = let t = lexer lb in let r = ts @ [ t ] in if t = EOF then r else f r in f [] }