Commit 38d5a3f3 authored by POTTIER Francois's avatar POTTIER Francois
Browse files

New functions in MenhirLib.ErrorReports.

parent 01cbe5f4
......@@ -34,9 +34,6 @@ let update buffer x =
| Two (_, x1), x2 ->
Two (x1, x2)
(* [show f buffer] prints the contents of the buffer. The function [f] is
used to print an element. *)
let show f buffer : string =
match !buffer with
| Zero ->
......@@ -50,9 +47,6 @@ let show f buffer : string =
(* In the most likely case, we have read two tokens. *)
Printf.sprintf "after '%s' and before '%s'" (f valid) (f invalid)
(* [last buffer] returns the last element of the buffer (that is, the invalid
token). *)
let last buffer =
match !buffer with
| Zero ->
......@@ -63,8 +57,6 @@ let last buffer =
| Two (_, invalid) ->
invalid
(* [wrap buffer lexer] *)
open Lexing
let wrap lexer =
......@@ -75,4 +67,67 @@ let wrap lexer =
update buffer (lexbuf.lex_start_p, lexbuf.lex_curr_p);
token
let wrap_supplier supplier =
let buffer = ref Zero in
buffer,
fun () ->
let (_token, pos1, pos2) as triple = supplier() in
update buffer (pos1, pos2);
triple
(* -------------------------------------------------------------------------- *)
let extract text (pos1, pos2) : string =
let ofs1 = pos1.pos_cnum
and ofs2 = pos2.pos_cnum in
let len = ofs2 - ofs1 in
try
String.sub text ofs1 len
with Invalid_argument _ ->
(* In principle, this should not happen, but if it does, let's make this
a non-fatal error. *)
"???"
let sanitize text =
String.map (fun c ->
if Char.code c < 32 then ' ' else c
) text
(* If we were willing to depend on [Str], we could implement [compress] as
follows:
let compress text =
Str.global_replace (Str.regexp "[ \t\n\r]+") " " text
*)
let rec compress n b i j skipping =
if j < n then
let c, j = Bytes.get b j, j + 1 in
match c with
| ' ' | '\t' | '\n' | '\r' ->
let i = if not skipping then (Bytes.set b i ' '; i + 1) else i in
let skipping = true in
compress n b i j skipping
| _ ->
let i = Bytes.set b i c; i + 1 in
let skipping = false in
compress n b i j skipping
else
Bytes.sub_string b 0 i
let compress text =
let b = Bytes.of_string text in
let n = Bytes.length b in
compress n b 0 0 false
let shorten k text =
let n = String.length text in
if n <= 2 * k + 3 then
text
else
String.sub text 0 k ^
"..." ^
String.sub text (n - k) k
(* -------------------------------------------------------------------------- *)
......@@ -23,12 +23,20 @@ type 'a buffer
which internally relies on [lexer] and updates [buffer] on the fly whenever
a token is demanded. *)
(* The type of the buffer is [(position * position) buffer], which means that
it stores two pairs of positions, which are the start and end positions of
the last two tokens. *)
open Lexing
val wrap:
(lexbuf -> 'token) ->
(position * position) buffer * (lexbuf -> 'token)
val wrap_supplier:
(unit -> 'token * position * position) ->
(position * position) buffer * (unit -> 'token * position * position)
(* [show f buffer] prints the contents of the buffer, producing a string that
is typically of the form "after '%s' and before '%s'". The function [f] is
used to print an element. The buffer MUST be nonempty. *)
......@@ -41,3 +49,24 @@ val show: ('a -> string) -> 'a buffer -> string
val last: 'a buffer -> 'a
(* -------------------------------------------------------------------------- *)
(* [extract text (pos1, pos2)] extracts the sub-string of [text] delimited
by the positions [pos1] and [pos2]. *)
val extract: string -> position * position -> string
(* [sanitize text] eliminates any special characters from the text [text].
A special character is a character whose ASCII code is less than 32.
Every special character is replaced with a single space character. *)
val sanitize: string -> string
(* [compress text] replaces every run of at least one whitespace character
with exactly one space character. *)
val compress: string -> string
(* [shorten k text] limits the length of [text] to [2k+3] characters. If the
text is too long, a fragment in the middle is replaced with an ellipsis. *)
val shorten: int -> string -> string
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment