Commit 79c2b979 authored by POTTIER Francois's avatar POTTIER Francois

Removed fix.patch.

parent f03ba64a
Index: grammar.ml
===================================================================
--- grammar.ml (revision 128)
+++ grammar.ml (working copy)
@@ -273,6 +273,15 @@
)
)
+ type property =
+ t
+
+ let bottom =
+ empty
+
+ let is_maximal _ =
+ false
+
end
(* Maps over terminals. *)
@@ -787,18 +796,60 @@
);
property, symbol_has_property
-let () =
+let nonempty =
let nonempty, _ = compute true in
for nt = Nonterminal.start to Nonterminal.n - 1 do
if not nonempty.(nt) then
Error.warningN
(Nonterminal.positions nt)
(Printf.sprintf "%s generates the empty language." (Nonterminal.print false nt))
- done
+ done;
+ nonempty
let (nullable : bool array), (nullable_symbol : Symbol.t -> bool) =
compute false
+let rhs basecase nt get =
+ (* disjunction over all productions for this nonterminal *)
+ Production.foldnt nt false (fun prod accu ->
+ accu ||
+ let rhs = Production.rhs prod in
+ (* conjunction over all symbols in the right-hand side *)
+ Array.fold_left (fun accu symbol ->
+ accu && match symbol with
+ | Symbol.T _ ->
+ basecase
+ | Symbol.N nt ->
+ get nt
+ ) true rhs
+ )
+
+module NONEMPTY =
+ Fix.Make
+ (Maps.PersistentMapsToImperativeMaps(NonterminalMap))
+ (Boolean)
+ (struct
+ type variable = Nonterminal.t
+ type property = bool
+ let rhs = rhs true
+ end)
+
+module NULLABLE =
+ Fix.Make
+ (Maps.PersistentMapsToImperativeMaps(NonterminalMap))
+ (Boolean)
+ (struct
+ type variable = Nonterminal.t
+ type property = bool
+ let rhs = rhs false
+ end)
+
+let () =
+ for nt = Nonterminal.start to Nonterminal.n - 1 do
+ assert (nonempty.(nt) = NONEMPTY.get nt);
+ assert (nullable.(nt) = NULLABLE.get nt)
+ done
+
(* ------------------------------------------------------------------------ *)
(* Compute FIRST sets. *)
@@ -840,6 +891,54 @@
TerminalSet.compare original updated <> 0
)
+module FIRST =
+ Fix.Make
+ (Maps.PersistentMapsToImperativeMaps(NonterminalMap))
+ (TerminalSet)
+ (struct
+ type variable = Nonterminal.t
+ type property = TerminalSet.t
+
+ let rhs nt first =
+
+ let first_symbol = function
+ | Symbol.T tok ->
+ TerminalSet.singleton tok
+ | Symbol.N nt ->
+ first nt
+ in
+
+ let nullable_first_rhs (rhs : Symbol.t array) (i : int) : bool * TerminalSet.t =
+ let length = Array.length rhs in
+ assert (i <= length);
+ let rec loop i toks =
+ if i = length then
+ true, toks
+ else
+ let symbol = rhs.(i) in
+ let toks = TerminalSet.union (first_symbol symbol) toks in
+ if nullable_symbol symbol then
+ loop (i+1) toks
+ else
+ false, toks
+ in
+ loop i TerminalSet.empty
+ in
+
+ (* union over all productions for this nonterminal *)
+ Production.foldnt nt TerminalSet.empty (fun prod accu ->
+ let rhs = Production.rhs prod in
+ let _, toks = nullable_first_rhs rhs 0 in
+ TerminalSet.union toks accu
+ )
+
+ end)
+
+let () =
+ for nt = Nonterminal.start to Nonterminal.n - 1 do
+ assert (TerminalSet.equal first.(nt) (FIRST.get nt))
+ done
+
(* ------------------------------------------------------------------------ *)
(* Dump the analysis results. *)
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