Commit 9dd92d06 authored by POTTIER Francois's avatar POTTIER Francois

More auxiliary functions in [Interpret].

parent 38ef45d2
...@@ -340,48 +340,42 @@ let read_messages filename : run list = ...@@ -340,48 +340,42 @@ let read_messages filename : run list =
(* --------------------------------------------------------------------------- *) (* --------------------------------------------------------------------------- *)
(* If [--compile-errors <filename>] is set, compile the error message (* [message_table] converts a list of targeted runs to a table (a mapping) of
descriptions found in file [filename] down to OCaml code, then stop. *) states to located sentences. Optionally, it can detect that two sentences
lead to the same state, and report an error. *)
let () =
Settings.compile_errors |> Option.iter (fun filename ->
(* Read the file. *)
let runs = read_messages filename in
(* Convert every sentence to a state number. We signal an error if a let message_table (detect_redundancy : bool) (runs : targeted_run list)
sentence does not end in an error, as expected. *) : located_sentence Lr1.NodeMap.t =
let runs = target_runs runs in
(* Build a mapping of states to located sentences. This allows us to let table =
detect if two sentences lead to the same state. *) List.fold_left (fun table (sentences_and_states, _message) ->
let (_ : located_sentence Lr1.NodeMap.t) = List.fold_left (fun table (sentence2, s) ->
List.fold_left (fun mapping (sentences_and_states, _message) -> match Lr1.NodeMap.find s table with
List.fold_left (fun mapping (sentence2, s) ->
match Lr1.NodeMap.find s mapping with
| sentence1 -> | sentence1 ->
if detect_redundancy then
Error.signal (fst sentence1 @ fst sentence2) Error.signal (fst sentence1 @ fst sentence2)
(Printf.sprintf (Printf.sprintf
"Redundancy: these sentences both cause an error in state %d." "Redundancy: these sentences both cause an error in state %d."
(Lr1.number s)); (Lr1.number s));
mapping table
| exception Not_found -> | exception Not_found ->
Lr1.NodeMap.add s sentence2 mapping Lr1.NodeMap.add s sentence2 table
) mapping sentences_and_states ) table sentences_and_states
) Lr1.NodeMap.empty runs ) Lr1.NodeMap.empty runs
in in
if Error.errors() then exit 1; if Error.errors() then exit 1;
table
(* In principle, we would like to check whether this set of sentences (* --------------------------------------------------------------------------- *)
is complete (i.e., covers all states where an error can arise), but
this is costly -- it requires running [LRijkstra]. Instead, we will
probably offer a separate facility for comparing two [.messages]
files, one of which can be produced via [--list-errors]. This will
ensure completeness. *)
(* Now, compile this information down to OCaml code. We wish to (* [compile_runs] converts a list of targeted runs to OCaml code that encodes
produce a function that maps a state number to a message. By a mapping of state numbers to error messages. The code is sent to the
convention, we call this function [message]. *) standard output channel. *)
let compile_runs filename (runs : targeted_run list) : unit =
(* We wish to produce a function that maps a state number to a message.
By convention, we call this function [message]. *)
let name = "message" in let name = "message" in
...@@ -414,7 +408,8 @@ let () = ...@@ -414,7 +408,8 @@ let () =
"This file was auto-generated based on \"%s\"." filename); "This file was auto-generated based on \"%s\"." filename);
SIComment (Printf.sprintf SIComment (Printf.sprintf
"Please note that the function [%s] can raise [Not_found]." name); "Please note that the function [%s] can raise [Not_found]." name);
SIValDefs (false, [ messagedef ]) SIValDefs (false,
[ messagedef ]);
] in ] in
(* Write this program to the standard output channel. *) (* Write this program to the standard output channel. *)
...@@ -423,7 +418,38 @@ let () = ...@@ -423,7 +418,38 @@ let () =
let f = stdout let f = stdout
let locate_stretches = None let locate_stretches = None
end) in end) in
P.program program; P.program program
(* --------------------------------------------------------------------------- *)
(* If [--compile-errors <filename>] is set, compile the error message
descriptions found in file [filename] down to OCaml code, then stop. *)
let () =
Settings.compile_errors |> Option.iter (fun filename ->
(* Read the file. *)
let runs = read_messages filename in
(* Convert every sentence to a state number. We signal an error if a
sentence does not end in an error, as expected. *)
let runs = target_runs runs in
(* Build a mapping of states to located sentences. This allows us to
detect if two sentences lead to the same state. *)
let _ = message_table true runs in
(* In principle, we would like to check whether this set of sentences
is complete (i.e., covers all states where an error can arise), but
this is costly -- it requires running [LRijkstra]. Instead, we will
probably offer a separate facility for comparing two [.messages]
files, one of which can be produced via [--list-errors]. This will
ensure completeness. *)
(* Now, compile this information down to OCaml code. We wish to
produce a function that maps a state number to a message. By
convention, we call this function [message]. *)
compile_runs filename runs;
exit 0 exit 0
) )
......
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