Commit 6fb9250b authored by POTTIER Francois's avatar POTTIER Francois

Eliminate [index2id].

parent c15ac728
...@@ -18,25 +18,27 @@ open ListMonad ...@@ -18,25 +18,27 @@ open ListMonad
let drop = MenhirLib.General.drop let drop = MenhirLib.General.drop
let take = MenhirLib.General.take let take = MenhirLib.General.take
(* -------------------------------------------------------------------------- *)
(* Throughout this file, branches (productions) are represented as lists of
producers. We consider it acceptable to perform operations whose cost is
linear in the length of a production, even when (with more complicated
code) it would be possible to eliminate this cost. *)
(* -------------------------------------------------------------------------- *)
(* [search p i xs] searches the list [xs] for an element [x] that satisfies [p]. (* [search p i xs] searches the list [xs] for an element [x] that satisfies [p].
If successful, then it returns a pair of 1. [i] plus the offset of [x] in the If successful, then it returns a pair of: - [i] plus the offset of [x] in the
list, and 2. the element [x]. *) list, and - the element [x]. *)
let rec search (p : 'a -> bool) i (xs : 'a list) : (int * 'a) option = let rec search (p : 'a -> bool) (i : int) (xs : 'a list) : (int * 'a) option =
match xs with match xs with
| [] -> | [] ->
None None
| x :: xs -> | x :: xs ->
if p x then Some (i, x) else search p (i+1) xs if p x then Some (i, x) else search p (i+1) xs
(* [index2id] converts a 0-based index (into a list of producers) to (* -------------------------------------------------------------------------- *)
an identifier (the name of the producer). *)
let index2id producers i =
try
producer_identifier (List.nth producers i)
with Failure _ ->
assert false (* should not happen *)
(* [rename_sw_outer] transforms the keywords in the outer production (the (* [rename_sw_outer] transforms the keywords in the outer production (the
caller) during inlining. It replaces [$startpos(x)] and [$endpos(x)], where caller) during inlining. It replaces [$startpos(x)] and [$endpos(x)], where
...@@ -229,7 +231,7 @@ let inline_branch caller (site : site) (callee : branch) : branch = ...@@ -229,7 +231,7 @@ let inline_branch caller (site : site) (callee : branch) : branch =
(* For debugging: check that each producer carries a unique name. *) (* For debugging: check that each producer carries a unique name. *)
let (_ : StringSet.t) = names producers in let (_ : StringSet.t) = names producers in
let index2id = index2id producers in let name = producers |> Array.of_list |> Array.map producer_identifier in
let inlined_producers = List.length inlined_producers in let inlined_producers = List.length inlined_producers in
...@@ -247,13 +249,13 @@ let inline_branch caller (site : site) (callee : branch) : branch = ...@@ -247,13 +249,13 @@ let inline_branch caller (site : site) (callee : branch) : branch =
(* If the inner production is non-epsilon, things are easy. The start (* If the inner production is non-epsilon, things are easy. The start
position of the inner production is the start position of its first position of the inner production is the start position of its first
element. *) element. *)
RightNamed (index2id nprefix), WhereStart RightNamed name.(nprefix), WhereStart
else if nprefix > 0 then else if nprefix > 0 then
(* If the inner production is epsilon, we are supposed to compute the (* If the inner production is epsilon, we are supposed to compute the
end position of whatever comes in front of it. If the prefix is end position of whatever comes in front of it. If the prefix is
nonempty, then this is the end position of the last symbol in the nonempty, then this is the end position of the last symbol in the
prefix. *) prefix. *)
RightNamed (index2id (nprefix - 1)), WhereEnd RightNamed (name.(nprefix - 1)), WhereEnd
else else
(* If the inner production is epsilon and the prefix is empty, then (* If the inner production is epsilon and the prefix is empty, then
we need to look up the end position stored in the top stack cell. we need to look up the end position stored in the top stack cell.
...@@ -273,7 +275,7 @@ let inline_branch caller (site : site) (callee : branch) : branch = ...@@ -273,7 +275,7 @@ let inline_branch caller (site : site) (callee : branch) : branch =
if inlined_producers > 0 then if inlined_producers > 0 then
(* If the inner production is non-epsilon, things are easy: its end (* If the inner production is non-epsilon, things are easy: its end
position is the end position of its last element. *) position is the end position of its last element. *)
RightNamed (index2id (nprefix + inlined_producers - 1)), WhereEnd RightNamed (name.(nprefix + inlined_producers - 1)), WhereEnd
else else
(* If the inner production is epsilon, then its end position is equal (* If the inner production is epsilon, then its end position is equal
to its start position. *) to its start position. *)
...@@ -289,7 +291,7 @@ let inline_branch caller (site : site) (callee : branch) : branch = ...@@ -289,7 +291,7 @@ let inline_branch caller (site : site) (callee : branch) : branch =
let beforeendp = let beforeendp =
if nprefix > 0 then if nprefix > 0 then
RightNamed (index2id (nprefix - 1)), WhereEnd RightNamed (name.(nprefix - 1)), WhereEnd
else else
Before, WhereEnd Before, WhereEnd
in in
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
open UnparameterizedSyntax open UnparameterizedSyntax
(** [inline g] traverses the grammar [g] and inlines the nonterminal symbol (** [inline g] traverses the grammar [g] and inlines away the nonterminal
definitions that are marked [%inline]. *) symbols whose definitions are marked [%inline]. The result is a grammar
where no symbols are marked [%inline]. *)
val inline: grammar -> grammar val inline: grammar -> grammar
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