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

Compute and expose [incoming_symbol] information for LR(0) states.

parent 13988a4f
...@@ -132,14 +132,21 @@ let _reductions : (SymbolicLookahead.t * Production.index) list InfiniteArray.t ...@@ -132,14 +132,21 @@ let _reductions : (SymbolicLookahead.t * Production.index) list InfiniteArray.t
let map : (Item.Set.t, node) Hashtbl.t = let map : (Item.Set.t, node) Hashtbl.t =
Hashtbl.create 50021 Hashtbl.create 50021
let incoming : Symbol.t option InfiniteArray.t =
InfiniteArray.make None
(* The automaton is built depth-first. *) (* The automaton is built depth-first. *)
let rec explore (state : Item.Set.t) : node = let rec explore (symbol : Symbol.t option) (state : Item.Set.t) : node =
(* Find out whether this state was already explored. *) (* Find out whether this state was already explored. *)
try try
Hashtbl.find map state
let k = Hashtbl.find map state in
assert (InfiniteArray.get incoming k = symbol);
k
with Not_found -> with Not_found ->
(* If not, create a new node. *) (* If not, create a new node. *)
...@@ -149,6 +156,10 @@ let rec explore (state : Item.Set.t) : node = ...@@ -149,6 +156,10 @@ let rec explore (state : Item.Set.t) : node =
InfiniteArray.set states k state; InfiniteArray.set states k state;
Hashtbl.add map state k; Hashtbl.add map state k;
(* Record its incoming symbol. *)
InfiniteArray.set incoming k symbol;
(* Build a symbolic version of the current state, where each item (* Build a symbolic version of the current state, where each item
is associated with a distinct lookahead set variable, numbered is associated with a distinct lookahead set variable, numbered
consecutively. *) consecutively. *)
...@@ -170,8 +181,8 @@ let rec explore (state : Item.Set.t) : node = ...@@ -170,8 +181,8 @@ let rec explore (state : Item.Set.t) : node =
dropping the symbolic lookahead information, explore the dropping the symbolic lookahead information, explore the
transitions to further LR(0) states. *) transitions to further LR(0) states. *)
InfiniteArray.set _transitions k (SymbolMap.map (fun symbolic_state -> InfiniteArray.set _transitions k (SymbolMap.mapi (fun symbol symbolic_state ->
let (k : node) = explore (Item.Map.domain symbolic_state) in let (k : node) = explore (Some symbol) (Item.Map.domain symbolic_state) in
let lookahead : SymbolicLookahead.t array = let lookahead : SymbolicLookahead.t array =
Array.make (Item.Map.cardinal symbolic_state) SymbolicLookahead.empty in Array.make (Item.Map.cardinal symbolic_state) SymbolicLookahead.empty in
let (_ : int) = Item.Map.fold (fun _ s i -> let (_ : int) = Item.Map.fold (fun _ s i ->
...@@ -194,7 +205,7 @@ let start prod : Item.Set.t = ...@@ -194,7 +205,7 @@ let start prod : Item.Set.t =
let entry : node ProductionMap.t = let entry : node ProductionMap.t =
ProductionMap.start (fun prod -> ProductionMap.start (fun prod ->
explore (start prod) explore None (start prod)
) )
let () = let () =
...@@ -213,6 +224,9 @@ let () = ...@@ -213,6 +224,9 @@ let () =
let items node : Item.Set.t = let items node : Item.Set.t =
InfiniteArray.get states node InfiniteArray.get states node
let incoming_symbol node : Symbol.t option =
InfiniteArray.get incoming node
(* ------------------------------------------------------------------------ *) (* ------------------------------------------------------------------------ *)
(* Help for building the LR(1) automaton. *) (* Help for building the LR(1) automaton. *)
......
...@@ -25,6 +25,12 @@ val entry: node ProductionMap.t ...@@ -25,6 +25,12 @@ val entry: node ProductionMap.t
val items: node -> Item.Set.t val items: node -> Item.Set.t
(* The incoming symbol of an LR(0) node is the symbol carried by all of the
edges that enter this node. A node has zero incoming edges (and, thus, no
incoming symbol) if and only if it is a start node.. *)
val incoming_symbol: node -> Symbol.t option
(* ------------------------------------------------------------------------ *) (* ------------------------------------------------------------------------ *)
(* Help for building the LR(1) automaton. *) (* Help for building the LR(1) automaton. *)
......
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