Commit 5e9fbf29 authored by POTTIER Francois's avatar POTTIER Francois

New module [MenhirLib.ErrorReports],

with code to keep track of the last two tokens.
parent 17b07559
(* -------------------------------------------------------------------------- *)
(* A two-place buffer stores zero, one, or two elements. *)
type 'a content =
| Zero
| One of 'a
| Two of 'a * (* most recent: *) 'a
type 'a buffer =
'a content ref
(* [update buffer x] pushes [x] into [buffer], causing the buffer to slide. *)
let update buffer x =
buffer :=
match !buffer, x with
| Zero, _ ->
One x
| One x1, x2
| 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 ->
(* The buffer cannot be empty. If we have read no tokens,
we cannot have detected a syntax error. *)
assert false
| One invalid ->
(* It is unlikely, but possible, that we have read just one token. *)
Printf.sprintf "before '%s'" (f invalid)
| Two (valid, invalid) ->
(* 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 ->
(* The buffer cannot be empty. If we have read no tokens,
we cannot have detected a syntax error. *)
assert false
| One invalid
| Two (_, invalid) ->
invalid
(* [wrap buffer lexer] *)
open Lexing
let wrap lexer =
let buffer = ref Zero in
buffer,
fun lexbuf ->
let token = lexer lexbuf in
update buffer (lexbuf.lex_start_p, lexbuf.lex_curr_p);
token
(* -------------------------------------------------------------------------- *)
(* -------------------------------------------------------------------------- *)
(* The following functions help keep track of the start and end positions of
the last two tokens in a two-place buffer. This is used to nicely display
where a syntax error took place. *)
type 'a buffer
(* [wrap lexer] returns a pair of a new (initially empty) buffer and a lexer
which internally relies on [lexer] and updates [buffer] on the fly whenever
a token is demanded. *)
open Lexing
val wrap:
(lexbuf -> 'token) ->
(position * position) buffer * (lexbuf -> 'token)
(* [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. *)
val show: ('a -> string) -> 'a buffer -> string
(* [last buffer] returns the last element of the buffer. The buffer MUST be
nonempty. *)
val last: 'a buffer -> 'a
(* -------------------------------------------------------------------------- *)
......@@ -6,6 +6,7 @@ Convert
IncrementalEngine
EngineTypes
Engine
ErrorReports
Printers
InfiniteArray
PackedIntArray
......
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