Commit aed2fb95 authored by POTTIER Francois's avatar POTTIER Francois
Browse files

New module Dump.

parent 01b6df53
......@@ -18,7 +18,7 @@
let () =
if Settings.dump_resolved then
Lr1.dump (Settings.base ^ ".automaton.resolved")
Dump.dump (Settings.base ^ ".automaton.resolved")
(* Let [Interpret] handle the command line options [--interpret],
[--interpret-error], [--compile-errors], [--compare-errors]. *)
......
......@@ -13,10 +13,19 @@
open Grammar
(* -------------------------------------------------------------------------- *)
(* I suppose now is as good a time as any to do this. *)
let () =
if Settings.graph then
DependencyGraph.print_dependency_graph()
(* artificial dependency *)
(* -------------------------------------------------------------------------- *)
(* If [--dump] is present, honor it before performing conflict resolution. *)
let () =
if Settings.dump then
Dump.dump (Settings.base ^ ".automaton")
(* -------------------------------------------------------------------------- *)
(* Explaining shift actions. *)
......
......@@ -11,7 +11,10 @@
(* *)
(******************************************************************************)
(* This module writes conflict explanations to the file <basename>.conflicts.
(* This module writes a description of the automaton, before conflict
resolution, to <basename>.automaton.
It writes conflict explanations to the file <basename>.conflicts.
Then, it performs conflict resolution and introduces extra reductions.
......
(******************************************************************************)
(* *)
(* Menhir *)
(* *)
(* François Pottier, Inria Paris *)
(* Yann Régis-Gianas, PPS, Université Paris Diderot *)
(* *)
(* Copyright Inria. All rights reserved. This file is distributed under the *)
(* terms of the GNU General Public License version 2, as described in the *)
(* file LICENSE. *)
(* *)
(******************************************************************************)
open Printf
open Grammar
let dump_node out node =
(* Print the state number. *)
fprintf out "State %d:\n"
(Lr1.number node);
(* Print the items. *)
fprintf out "%s"
(Lr0.print "" (Lr1.state node));
(* Print the transitions. *)
SymbolMap.iter (fun symbol node ->
fprintf out "-- On %s shift to state %d\n"
(Symbol.print symbol) (Lr1.number node)
) (Lr1.transitions node);
(* Print the reductions. *)
(* One might wish to group all symbols that
lead to reducing a common production. *)
TerminalMap.iter (fun tok prods ->
List.iter (fun prod ->
fprintf out "-- On %s " (Terminal.print tok);
match Production.classify prod with
| Some nt ->
fprintf out "accept %s\n" (Nonterminal.print false nt)
| None ->
fprintf out "reduce production %s\n" (Production.print prod)
) prods
) (Lr1.reductions node);
(* Print the conflicts. *)
if not (TerminalSet.is_empty (Lr1.conflict_tokens node)) then
fprintf out "** Conflict on %s\n"
(TerminalSet.print (Lr1.conflict_tokens node));
(* Print the end-of-stream conflicts. *)
Lr1.has_eos_conflict node |> Option.iter begin fun (prods, toks) ->
(* If this function is invoked before conflict resolution has been
performed, then the list [prods] could have several elements.
We pick one. *)
assert (prods <> []);
let prod = List.hd prods in
fprintf out "** End-of-stream conflict on %s\n"
(TerminalSet.print toks);
fprintf out
"** There is a tension between\n\
** (1) %s\n\
** without even requesting a lookahead token, and\n\
** (2) testing whether the lookahead token is a member of the above set.\n"
(Production.describe prod)
end;
(* Skip a line. *)
fprintf out "\n"
let dump filename =
let out = open_out filename in
Lr1.iter (dump_node out);
close_out out;
Time.tick "Dumping the LR(1) automaton"
(******************************************************************************)
(* *)
(* Menhir *)
(* *)
(* François Pottier, Inria Paris *)
(* Yann Régis-Gianas, PPS, Université Paris Diderot *)
(* *)
(* Copyright Inria. All rights reserved. This file is distributed under the *)
(* terms of the GNU General Public License version 2, as described in the *)
(* file LICENSE. *)
(* *)
(******************************************************************************)
(* [dump filename] writes a description of the LR(1) automaton to the
file [filename]. This function can be invoked either before or after
conflicts have been resolved and extra reductions have been added. *)
val dump: string -> unit
......@@ -607,87 +607,6 @@ let targets f accu symbol =
(* -------------------------------------------------------------------------- *)
(* If requested, dump a verbose description of the automaton. *)
let dump_node out node =
let open Printf in
(* Print the state number. *)
fprintf out "State %d:\n"
(number node);
(* Print the items. *)
fprintf out "%s"
(Lr0.print "" (state node));
(* Print the transitions. *)
SymbolMap.iter (fun symbol node ->
fprintf out "-- On %s shift to state %d\n"
(Symbol.print symbol) (number node)
) (transitions node);
(* Print the reductions. *)
(* One might wish to group all symbols that
lead to reducing a common production. *)
TerminalMap.iter (fun tok prods ->
List.iter (fun prod ->
fprintf out "-- On %s " (Terminal.print tok);
match Production.classify prod with
| Some nt ->
fprintf out "accept %s\n" (Nonterminal.print false nt)
| None ->
fprintf out "reduce production %s\n" (Production.print prod)
) prods
) (reductions node);
(* Print the conflicts. *)
if not (TerminalSet.is_empty (conflict_tokens node)) then
fprintf out "** Conflict on %s\n"
(TerminalSet.print (conflict_tokens node));
(* Print the end-of-stream conflicts. *)
has_eos_conflict node |> Option.iter begin fun (prods, toks) ->
(* If this function is invoked before conflict resolution has been
performed, then the list [prods] could have several elements.
We pick one. *)
assert (prods <> []);
let prod = List.hd prods in
fprintf out "** End-of-stream conflict on %s\n"
(TerminalSet.print toks);
fprintf out
"** There is a tension between\n\
** (1) %s\n\
** without even requesting a lookahead token, and\n\
** (2) testing whether the lookahead token is a member of the above set.\n"
(Production.describe prod)
end;
(* Skip a line. *)
fprintf out "\n"
let dump filename =
let out = open_out filename in
iter (dump_node out);
close_out out;
Time.tick "Dumping the LR(1) automaton"
let () =
if Settings.dump then
dump (Settings.base ^ ".automaton")
(* -------------------------------------------------------------------------- *)
(* Converting a start node into the single item that it contains. *)
let start2item node =
......
......@@ -146,6 +146,11 @@ val targets: ('a -> node list -> node -> 'a) -> 'a -> Symbol.t -> 'a
val conflicts: (TerminalSet.t -> node -> unit) -> unit
(* [conflict_tokens node] returns the set of tokens where [node] has a
conflict. *)
val conflict_tokens: node -> TerminalSet.t
(* [has_eos_conflict node] indicates whether [node] has an end-of-stream
conflict. If so, the list of productions and the lookahead tokens that are
involved are returned.
......@@ -188,15 +193,6 @@ val default_conflict_resolution: unit -> unit
val extra_reductions: unit -> unit
(* ------------------------------------------------------------------------- *)
(* Dumping the automaton. *)
(* This function dumps a description of the automaton to the file whose
name is passed as an argument. It can be called before or after conflict
resolution has taken place. *)
val dump: string -> unit
(* ------------------------------------------------------------------------- *)
(* Information about which productions are reduced and where. *)
......
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