Commit 0a077a78 by POTTIER Francois

### Added the computation of the minimal length of each nonterminal.

```This information is displayed at log level -lg 2.
Changed the display to not include the artificial start symbols.```
parent 1eb50c49
 (* The natural numbers, completed with [Infinity], and ordered towards zero (i.e. [Infinity] is [bottom], [Finite 0] is [top]). *) type t = | Finite of int | Infinity type property = t let equal p1 p2 = match p1, p2 with | Finite i1, Finite i2 -> i1 = i2 | Infinity, Infinity -> true | _, _ -> false let bottom = Infinity let is_maximal p = match p with | Finite 0 -> true | _ -> false let min p1 p2 = match p1, p2 with | Finite i1, Finite i2 -> Finite (min i1 i2) | p, Infinity | Infinity, p -> p let min_lazy p1 p2 = match p1 with | Finite 0 -> p1 | _ -> min p1 (Lazy.force p2) let add p1 p2 = match p1, p2 with | Finite i1, Finite i2 -> Finite (i1 + i2) | _, _ -> Infinity let add_lazy p1 p2 = match p1 with | Infinity -> Infinity | _ -> add p1 (Lazy.force p2) let print p = match p with | Finite i -> string_of_int i | Infinity -> "infinity"
 (* The natural numbers, completed with [Infinity], and ordered towards zero (i.e. [Infinity] is [bottom], [Finite 0] is [top]). *) type t = | Finite of int | Infinity include Fix.PROPERTY with type property = t val min: t -> t -> t val add: t -> t -> t val min_lazy: t -> t Lazy.t -> t val add_lazy: t -> t Lazy.t -> t val print: t -> string
 ... ... @@ -1013,20 +1013,49 @@ let () = (Printf.sprintf "%s generates the empty language." (Nonterminal.print false nt)); done (* ------------------------------------------------------------------------ *) (* For every nonterminal symbol [nt], compute the minimal length of any word generated by [nt]. This analysis subsumes [NONEMPTY] and [NULLABLE]. Indeed, [nt] produces a nonempty language if only if the minimal length is finite; [nt] is nullable if only if the minimal length is zero. *) (* This analysis is more costly than the [NONEMPTY] and [NULLABLE], so it is performed only on demand. *) module MINIMAL = GenericAnalysis (CompletedNat) (struct open CompletedNat (* A terminal symbol has length 1. *) let terminal _ = Finite 1 (* The length of an alternative is the minimum length of any branch. *) let disjunction = min_lazy (* The length of a sequence is the sum of the lengths of the members. *) let conjunction _ = add_lazy (* The epsilon sequence has length 0. *) let epsilon = Finite 0 end) (* ------------------------------------------------------------------------ *) (* Dump the analysis results. *) let () = Error.logG 2 (fun f -> for nt = 0 to Nonterminal.n - 1 do for nt = Nonterminal.start to Nonterminal.n - 1 do Printf.fprintf f "nullable(%s) = %b\n" (Nonterminal.print false nt) (NULLABLE.nonterminal nt) done; for nt = 0 to Nonterminal.n - 1 do for nt = Nonterminal.start to Nonterminal.n - 1 do Printf.fprintf f "first(%s) = %s\n" (Nonterminal.print false nt) (TerminalSet.print (FIRST.nonterminal nt)) done; for nt = Nonterminal.start to Nonterminal.n - 1 do Printf.fprintf f "minimal(%s) = %s\n" (Nonterminal.print false nt) (CompletedNat.print (MINIMAL.nonterminal nt)) done ) ... ... @@ -1086,7 +1115,7 @@ let follow : Nonterminal.t -> TerminalSet.t = let () = Error.logG 2 (fun f -> for nt = 0 to Nonterminal.n - 1 do for nt = Nonterminal.start to Nonterminal.n - 1 do Printf.fprintf f "follow(%s) = %s\n" (Nonterminal.print false nt) (TerminalSet.print (follow nt)) ... ...
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!