forked from yurug/menhir-error-recovery
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparseError.ml
52 lines (43 loc) · 1.52 KB
/
parseError.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
(**
This module demonstrates that we can easily generate contextual
error message thanks to the introspection API. Indeed, when a
parsing error occurs, there exist items in the stack whose analysis
is not completed. Therefore, the non terminals of their productions
are probably the syntactically classes that are being recognized
when the error occurred.
*)
open Parser.MenhirInterpreter
open PureLexer
let rec pop_until pred env =
match top env with
| None -> []
| Some elt ->
match pred elt with
| [] -> begin match pop env with
| None -> assert false
| Some env -> pop_until pred env
end
| l -> l
let keep_predictions predictions (production, focus) =
if focus < List.length (rhs production) then
(lhs production) :: predictions
else
predictions
let element_contains_prediction_items elt =
match elt with
| Element (state, _, _, _) ->
items state
|> List.fold_left keep_predictions []
let find_context = function
| InputNeeded env ->
pop_until element_contains_prediction_items env
| _ ->
assert false (* By the specification of [on_error]. *)
let parse_error pos msg cont =
Error.error "during parsing" pos msg cont
let contextual_error_msg lexer checkpoint continuation =
find_context checkpoint |> fun nonterminals ->
Error.error "parsing" (Lexer.current_position lexer)
(Printf.sprintf "Error while analyzing %s."
(String.concat " or " (List.map Symbol.string_of_symbol nonterminals)))
@@ continuation