Camlinternal...Lib.LexerUtil(3)
π NAME
CamlinternalMenhirLib.LexerUtil β okay so bestie, there is literally no description here. That's it. That's the whole name section. The manpage said "no description" and honestly? Iconic of it. π
π¦ Module
It's the module CamlinternalMenhirLib.LexerUtil, and this page is part of the OCaml library docs. Keep that in your back pocket, iykyk.
β¨ Documentation
So the module is literally:
Module LexerUtil
: sig end
Yes queen, that's the vibe. Now let's get into the actual functions, because this is where things get good. π«Ά
πΈ val init : string -> Lexing.lexbuf -> Lexing.lexbuf
init filename lexbuf sets up β initializes β the lexing buffer lexbuf so that whenever you read positions from it later, those positions point at the file filename. And then it hands lexbuf right back to you. Slay, returning it is the whole point. β¨
π val read : string -> string * Lexing.lexbuf
read filename reads the entire contents of the file filename β the whole thing, no crumbs left β and gives you back a pair: that content as a string, plus a lexing buffer that's already been initialized based on that string. Two-for-one, we love to see it. π
β val newline : Lexing.lexbuf -> unit
newline lexbuf bumps up the line counter that lives inside lexbuf. The catch: your lexer has to call it itself every single time it consumes a newline character. Do that and you keep a correct current line number inside lexbuf. Also, plot twist: it's literally synonymous with Lexing.new_line lexbuf. Same thing, different name. No cap. π₯
π val range : Lexing.position * Lexing.position -> string
range (startpos, endpos) β you give it a start position and an end position, and it prints out a textual description of that range. Details, bestie:
- The description is exactly one line long and ends with a newline character.
- It mentions the file name, the line number, and a range of characters on that line.
- β οΈ The line number is only correct if
newlinehas been used properly, as described above. Skip that and your line numbers are giving lies. π
π val tabulate : ('a -> bool) -> (unit -> 'a) -> unit -> 'a
tabulate is_eof lexer tabulates the lexer lexer. Which means: it runs that lexer right away, all the way through until it hits an EOF token, stores all the tokens in an array in memory, and then returns a brand-new lexer that reads tokens from that array whenever you invoke it. Pre-gaming your tokens, basically. π
The rules though β read them, fr fr:
- The function
lexeris not allowed to raise an exception. - It must produce a finite stream of tokens: after a finite number of invocations, it has to return a token that
is_eofidentifies as an EOF token.
Both the original lexer lexer and the new lexer that tabulate is_eof lexer returns are functions of type unit -> 'a β where that 'a is most likely going to be instantiated with a triple of a token and two positions, per the revised lexer API described over in the module CamlinternalMenhirLib.Convert. Go check that one out, it's the main character of this whole saga. π
One thing to keep in mind: lexer raising an exception is a hard no, and an infinite token stream is a hard no β the whole tabulate trick depends on the stream ending. π§
Alright bestie, that's the whole page! This lil' doc drop came from OCamldoc, dated 2026-06-22 β so if you're reading this in the future, hi, hope your lexer is behaving. π¦ Go forth and tokenize responsibly. π β¨
π¦ where this page comes from
- arch rolling: ocaml 5.5.0-1 Β· LGPL2.1 AND custom: QPL-1.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms