- Try to do better pretty printing when array elements are individually
[bpt/coccinelle.git] / bundles / menhirLib / menhir-20120123 / src / conflict.ml
diff --git a/bundles/menhirLib/menhir-20120123/src/conflict.ml b/bundles/menhirLib/menhir-20120123/src/conflict.ml
deleted file mode 100644 (file)
index eb64d77..0000000
+++ /dev/null
@@ -1,496 +0,0 @@
-(**************************************************************************)
-(*                                                                        *)
-(*  Menhir                                                                *)
-(*                                                                        *)
-(*  François Pottier, INRIA Rocquencourt                                  *)
-(*  Yann Régis-Gianas, PPS, Université Paris Diderot                      *)
-(*                                                                        *)
-(*  Copyright 2005-2008 Institut National de Recherche en Informatique    *)
-(*  et en Automatique. All rights reserved. This file is distributed      *)
-(*  under the terms of the Q Public License version 1.0, with the change  *)
-(*  described in file LICENSE.                                            *)
-(*                                                                        *)
-(**************************************************************************)
-
-open Grammar
-
-(* -------------------------------------------------------------------------- *)
-(* Our output channel. *)
-
-let out =
-  lazy (open_out (Settings.base ^ ".conflicts"))
-
-(* -------------------------------------------------------------------------- *)
-(* Explaining shift actions. *)
-
-(* The existence of a shift action stems from the existence of a shift
-   item in the LR(0) core that underlies the LR(1) state of interest.
-   That is, lookahead sets are not relevant. The existence of a shift
-   item in the LR(0) core is explained by finding a path from a start
-   item to the shift item in the LR(0) nondeterministic automaton,
-   such that the symbols read along this path form the (previously
-   fixed) symbol string that leads to the conflict state in the LR(1)
-   automaton. There may be several such paths: a shortest one is
-   chosen. There may also be several shift items in the conflict
-   state: an arbitrary one is chosen. I believe it would not be
-   interesting to display traces for several shift items: they would
-   be identical except in their last line (where the desired shift
-   item actually appears). *)
-
-(* Symbolic execution of the nondeterministic LR(0) automaton. *)
-
-(* Configurations are pairs of an LR(0) item and an offset into
-   the input string, which indicates how much has been read so
-   far. *)
-
-type configuration0 =
-    Item.t * int
-
-(* This function builds a derivation out of a (nonempty, reversed) sequence of
-   configurations. The derivation is constructed from bottom to top, that is,
-   beginning at the last configuration and moving back towards to the start
-   configuration. *)
-
-let rec follow derivation offset' = function
-  | [] ->
-      assert (offset' = 0);
-      derivation
-  | (item, offset) :: configs ->
-      let _, _, rhs, pos, _ = Item.def item in
-      let derivation =
-       if offset = offset' then
-         (* This is an epsilon transition. Put a new root node on top of
-            the existing derivation. *)
-         Derivation.build pos rhs derivation None
-       else
-         (* This was a shift transition. Tack symbol in front of the
-            forest. *)
-         Derivation.prepend rhs.(pos) derivation
-      in
-      follow derivation offset configs
-
-(* Symbolic execution begins with a start item (corresponding
-   to one of the automaton's entry nodes), a fixed string of
-   input symbols, to be fully consumed, and a goal item. The
-   objective is to find a path through the automaton that
-   leads from the start configuration [(stop, 0)] to the goal
-   configuration [(stop, n)], where [n] is the length of the
-   input string. The automaton is explored via breadth-first
-   search. A hash table is used to record which configurations
-   have been visited and to build a spanning tree of shortest
-   paths. *)
-
-exception Done
-
-let explain_shift_item
-    (start : Item.t)
-    (input : Symbol.t array)
-    (stop : Item.t)
-    : Derivation.t =
-
-  let n =
-    Array.length input
-  in
-
-  let table : (configuration0, configuration0 option) Hashtbl.t =
-    Hashtbl.create 1023
-  in
-
-  let queue : configuration0 Queue.t =
-    Queue.create()
-  in
-
-  let enqueue ancestor config =
-    try
-      let _ = Hashtbl.find table config in
-      ()
-    with Not_found ->
-      Hashtbl.add table config ancestor;
-      Queue.add config queue
-  in
-
-  enqueue None (start, 0);
-  try
-    Misc.qiter (function (item, offset) as config ->
-
-      (* If the item we're looking at is the goal item and if
-        we have read all of the input symbols, stop. *)
-
-      if (Item.equal item stop) && (offset = n) then
-       raise Done;
-
-      (* Otherwise, explore the transitions out of this item. *)
-
-      let prod, _, rhs, pos, length = Item.def item in
-
-      (* Shift transition, followed only if the symbol matches
-        the symbol found in the input string. *)
-
-      if (pos < length)
-      && (offset < n)
-      && (Symbol.equal rhs.(pos) input.(offset)) then begin
-       let config' = (Item.import (prod, pos+1), offset+1) in
-       enqueue (Some config) config'
-      end;
-
-      (* Epsilon transitions. *)
-
-      if pos < length then
-       match rhs.(pos) with
-       | Symbol.N nt ->
-           Production.iternt nt (fun prod ->
-             let config' = (Item.import (prod, 0), offset) in
-             enqueue (Some config) config'
-            )
-       | Symbol.T _ ->
-           ()
-
-    ) queue;
-    assert false
-  with Done ->
-
-    (* We have found a (shortest) path from the start configuration to
-       the goal configuration. Turn it into an explicit derivation. *)
-
-    let configs = Misc.materialize table (stop, n) in
-    let _, _, rhs, pos, _ = Item.def stop in
-    let derivation = Derivation.tail pos rhs in
-    let derivation = follow derivation n configs in
-    derivation
-
-(* -------------------------------------------------------------------------- *)
-(* Explaining reduce actions. *)
-
-(* The existence of a reduce action stems from the existence of a
-   reduce item, whose lookahead set contains the token of interest, in
-   the state of interest. Here, lookahead sets are relevant only
-   insofar as they contain or do not contain the token of interest --
-   in other words, lookahead sets can be abstracted by Boolean
-   values. The existence of the reduce item is explained by finding a
-   path from a start item to the reduce item in the LR(1)
-   nondeterministic automaton, such that the symbols read along this
-   path form the (previously fixed) symbol string that leads to the
-   conflict state in the LR(1) automaton. There may be several such
-   paths: a shortest one is chosen. *)
-
-(* Symbolic execution of the nondeterministic LR(1) automaton. *)
-
-(* Configurations are pairs of an LR(1) item and an offset into the
-   input string, which indicates how much has been read so far. An
-   LR(1) item is itself represented as the combination of an LR(0)
-   item and a Boolean flag, telling whether the token of interest
-   appears or does not appear in the lookahead set. *)
-
-type configuration1 =
-    Item.t * bool * int
-
-(* This function builds a derivation out of a sequence of configurations. The
-   end of the sequence is dealt with specially -- we want to explain how the
-   lookahead symbol appears and is inherited. Once that is done, the rest
-   (that is, the beginning) of the derivation is dealt with as above. *)
-
-let config1toconfig0 (item, _, offset) =
-  (item, offset)
-
-let rec follow1 tok derivation offset' = function
-  | [] ->
-      assert (Terminal.equal tok Terminal.sharp);
-      (* One could emit a comment saying that the lookahead token is
-        initially [#]. That comment would have to be displayed above
-        the derivation, though, and there is no support for that
-        at the moment, so let's skip it. *)
-      derivation
-  | (item, _, offset) :: configs ->
-      let _, _, rhs, pos, length = Item.def item in
-      if offset = offset' then
-
-       (* This is an epsilon transition. Attack a new line and add
-          a comment that explains why the lookahead symbol is
-          produced or inherited. *)
-       
-       let nullable, first = Analysis.nullable_first_rhs rhs (pos + 1) in
-
-       if TerminalSet.mem tok first then
-
-         (* The lookahead symbol is produced (and perhaps also inherited,
-            but let's ignore that). *)
-
-         let e = Analysis.explain_first_rhs tok rhs (pos + 1) in
-         let comment =
-           "lookahead token appears" ^ (if e = "" then "" else " because " ^ e)
-         in
-         let derivation =
-           Derivation.build pos rhs derivation (Some comment)
-         in
-
-         (* Print the rest of the derivation without paying attention to
-            the lookahead symbols. *)
-
-         follow derivation offset (List.map config1toconfig0 configs)
-
-       else begin
-
-         (* The lookahead symbol is not produced, so it is definitely inherited. *)
-
-         assert nullable;
-
-         let comment =
-           "lookahead token is inherited" ^
-           (if pos + 1 < length then Printf.sprintf " because %scan vanish" (Symbol.printao (pos + 1) rhs) else "")
-         in
-         let derivation =
-           Derivation.build pos rhs derivation (Some comment)
-         in
-
-         follow1 tok derivation offset configs
-
-       end
-
-      else
-
-       (* This is a shift transition. Tack symbol in front of forest. *)
-
-       let derivation = 
-         Derivation.prepend rhs.(pos) derivation
-       in
-
-       follow1 tok derivation offset configs
-
-(* Symbolic execution is performed in the same manner as above. *)
-
-let explain_reduce_item
-    (tok : Terminal.t)
-    (start : Item.t)
-    (input : Symbol.t array)
-    (stop : Item.t)
-    : Derivation.t =
-
-  let n =
-    Array.length input
-  in
-
-  let table : (configuration1, configuration1 option) Hashtbl.t =
-    Hashtbl.create 1023
-  in
-
-  let queue : configuration1 Queue.t =
-    Queue.create()
-  in
-
-  let enqueue ancestor config =
-    try
-      let _ = Hashtbl.find table config in
-      ()
-    with Not_found ->
-      Hashtbl.add table config ancestor;
-      Queue.add config queue
-  in
-
-  (* If the lookahead token is #, then it initially appear in the lookahead
-     set, otherwise it doesn't. *)
-
-  enqueue None (start, Terminal.equal tok Terminal.sharp, 0);
-  try
-    Misc.qiter (function (item, lookahead, offset) as config ->
-
-      (* If the item we're looking at is the goal item and if
-        we have read all of the input symbols, stop. *)
-
-      if (Item.equal item stop) && lookahead && (offset = n) then
-       raise Done;
-
-      (* Otherwise, explore the transitions out of this item. *)
-
-      let prod, nt, rhs, pos, length = Item.def item in
-
-      (* Shift transition, followed only if the symbol matches
-        the symbol found in the input string. *)
-
-      if (pos < length)
-      && (offset < n)
-      && (Symbol.equal rhs.(pos) input.(offset)) then begin
-       let config' = (Item.import (prod, pos+1), lookahead, offset+1) in
-       enqueue (Some config) config'
-      end;
-
-      (* Epsilon transitions. *)
-
-      if pos < length then
-       match rhs.(pos) with
-       | Symbol.N nt ->
-           let nullable, first = Analysis.nullable_first_rhs rhs (pos + 1) in
-           let first : bool = TerminalSet.mem tok first in
-           let lookahead' =
-             if nullable then first || lookahead else first
-           in
-           Production.iternt nt (fun prod ->
-             let config' = (Item.import (prod, 0), lookahead', offset) in
-             enqueue (Some config) config'
-            )
-       | Symbol.T _ ->
-           ()
-
-    ) queue;
-    assert false
-  with Done ->
-
-    (* We have found a (shortest) path from the start configuration to
-       the goal configuration. Turn it into an explicit derivation. *)
-
-    let configs = Misc.materialize table (stop, true, n) in
-    let derivation = Derivation.empty in
-    let derivation = follow1 tok derivation n configs in
-    derivation
-
-(* -------------------------------------------------------------------------- *)
-(* Putting it all together. *)
-
-let () =
-  if Settings.explain then begin
-
-    Lr1.conflicts (fun toks node ->
-
-      (* Construct a partial LR(1) automaton, looking for a conflict
-        in a state that corresponds to this node. Because Pager's
-        algorithm can merge two states as soon as one of them has a
-        conflict, we can't be too specific about the conflict that we
-        expect to find in the canonical automaton. So, we must supply
-        a set of conflict tokens and accept any kind of conflict that
-        involves one of them. *)
-
-      (* TEMPORARY with the new compatibility criterion, we can be
-        sure that every conflict token is indeed involved in a
-        conflict. Exploit that? Avoid focusing on a single token? *)
-
-      let module P = Lr1partial.Run (struct
-       let tokens = toks
-       let goal = node
-      end) in
-
-      let closure =
-       Lr0.closure P.goal in
-
-      (* Determine what kind of conflict was found. *)
-
-      let shift, reduce = Item.Map.fold (fun item toks (shift, reduce) ->
-       match Item.classify item with
-       | Item.Shift (Symbol.T tok, _)
-         when Terminal.equal tok P.token ->
-             shift + 1, reduce
-       | Item.Reduce prod
-         when TerminalSet.mem P.token toks ->
-           shift, reduce + 1
-       | _ ->
-           shift, reduce
-      ) closure (0, 0) in
-
-      let kind =
-       if (shift > 0) && (reduce > 1) then
-         "shift/reduce/reduce"
-       else if (shift > 0) then
-         "shift/reduce"
-       else
-         "reduce/reduce"
-      in
-
-      (* Explain how the conflict state is reached. *)
-
-      let out = Lazy.force out in
-
-      Printf.fprintf out "\n\
-        ** Conflict (%s) in state %d.\n\
-       ** Token%s involved: %s\n%s\
-       ** This state is reached from %s after reading:\n\n%s\n"
-      kind (Lr1.number node)
-      (if TerminalSet.cardinal toks > 1 then "s" else "")
-      (TerminalSet.print toks)
-      (if TerminalSet.cardinal toks > 1 then
-       Printf.sprintf "** The following explanations concentrate on token %s.\n" (Terminal.print P.token)
-      else "")
-      (Nonterminal.print false (Item.startnt P.source))
-      (Symbol.printa P.path);
-
-      (* Examine the items in that state, focusing on one particular
-        token. Out of the shift items, we explain just one -- this
-        seems enough. We explain each of the reduce items. *)
-
-      (* First, build a mapping of items to derivations. *)
-
-      let (_ : bool), derivations =
-       Item.Map.fold (fun item toks (still_looking_for_shift_item, derivations) ->
-         match Item.classify item with
-
-         | Item.Shift (Symbol.T tok, _)
-           when still_looking_for_shift_item && (Terminal.equal tok P.token) ->
-
-             false,
-             let derivation = explain_shift_item P.source P.path item in
-             Item.Map.add item derivation derivations
-
-         | Item.Reduce prod
-           when TerminalSet.mem P.token toks ->
-
-             still_looking_for_shift_item,
-             let derivation = explain_reduce_item P.token P.source P.path item in
-             Item.Map.add item derivation derivations
-
-         | _ ->
-
-             still_looking_for_shift_item,
-             derivations
-
-        ) closure (true, Item.Map.empty)
-      in
-
-      (* Factor out the common context among all derivations, so as to avoid
-        repeating it. This helps prevent derivation trees from drifting too
-        far away towards the right. It also helps produce sub-derivations
-         that are quite compact. *)
-
-      let context, derivations =
-       Derivation.factor derivations
-      in
-
-      (* Display the common context. *)
-
-      Printf.fprintf out
-       "\n** The derivations that appear below have the following common factor:\
-        \n** (The question mark symbol (?) represents the spot where the derivations begin to differ.)\n\n";
-      Derivation.printc out context;
-
-      (* Then, display the sub-derivations. *)
-
-      Item.Map.iter (fun item derivation ->
-
-       Printf.fprintf out
-         "\n** In state %d, looking ahead at %s, "
-         (Lr1.number node)
-         (Terminal.print P.token);
-
-       begin match Item.classify item with
-       | Item.Shift _ ->
-           Printf.fprintf out "shifting is permitted\n** because of the following sub-derivation:\n\n"
-       | Item.Reduce prod ->
-           Printf.fprintf out
-             "reducing production\n** %s\n** is permitted because of the following sub-derivation:\n\n"
-             (Production.print prod)
-       end;
-
-       Derivation.print out derivation
-
-      ) derivations;
-
-      flush out
-
-    );
-    Time.tick "Explaining conflicts"
-
-  end
-
-(* ------------------------------------------------------------------------ *)
-(* Resolve the conflicts that remain in the automaton. *)
-
-let () =
-  Lr1.default_conflict_resolution();
-  Time.tick "Resolving remaining conflicts"
-