Commit c0d5c888 authored by POTTIER Francois's avatar POTTIER Francois

New functions in [GrammarFunctor].

- [Terminal.init], [Nonterminal.init], [Production.init] create arrays
  indexed with (integer codes for) symbols and productions.
- Several functions allow finding the attributes attached with
  symbols, with producers, and with the grammar.
parent 6778f8f4
...@@ -118,6 +118,9 @@ module Nonterminal = struct ...@@ -118,6 +118,9 @@ module Nonterminal = struct
let positions nt = let positions nt =
(StringMap.find (print false nt) grammar.rules).positions (StringMap.find (print false nt) grammar.rules).positions
let init f =
Array.init n f
let iter f = let iter f =
Misc.iteri n f Misc.iteri n f
...@@ -153,6 +156,18 @@ module Nonterminal = struct ...@@ -153,6 +156,18 @@ module Nonterminal = struct
let tabulate f = let tabulate f =
Array.get (Array.init n f) Array.get (Array.init n f)
let attributes : Syntax.attributes array =
Array.make n []
let () =
StringMap.iter (fun nonterminal { attributes = attrs } ->
let nt = lookup nonterminal in
attributes.(nt) <- attrs
) grammar.rules
let attributes nt =
attributes.(nt)
end end
(* Sets and maps over nonterminals. *) (* Sets and maps over nonterminals. *)
...@@ -250,6 +265,9 @@ module Terminal = struct ...@@ -250,6 +265,9 @@ module Terminal = struct
let ocamltype tok = let ocamltype tok =
token_properties.(tok).tk_ocamltype token_properties.(tok).tk_ocamltype
let init f =
Array.init n f
let iter f = let iter f =
Misc.iteri n f Misc.iteri n f
...@@ -280,6 +298,9 @@ module Terminal = struct ...@@ -280,6 +298,9 @@ module Terminal = struct
with Not_found -> with Not_found ->
None None
let attributes tok =
token_properties.(tok).tk_attributes
(* The sub-module [Word] offers an implementation of words (that is, (* The sub-module [Word] offers an implementation of words (that is,
sequences) of terminal symbols. It is used by [LRijkstra]. We sequences) of terminal symbols. It is used by [LRijkstra]. We
make it a functor, because it has internal state (a hash table) make it a functor, because it has internal state (a hash table)
...@@ -563,6 +584,9 @@ module Production = struct ...@@ -563,6 +584,9 @@ module Production = struct
let positions : Positions.t list array = let positions : Positions.t list array =
Array.make n [] Array.make n []
let rhs_attributes : Syntax.attributes array array =
Array.make n [||]
let (start : int), let (start : int),
(startprods : index NonterminalMap.t) = (startprods : index NonterminalMap.t) =
StringSet.fold (fun nonterminal (k, startprods) -> StringSet.fold (fun nonterminal (k, startprods) ->
...@@ -586,13 +610,14 @@ module Production = struct ...@@ -586,13 +610,14 @@ module Production = struct
let dummy = ProductionLevel (InputFile.builtin_input_file, 0) in let dummy = ProductionLevel (InputFile.builtin_input_file, 0) in
Array.make n dummy Array.make n dummy
let (_ : int) = StringMap.fold (fun nonterminal { branches = branches } k -> let (_ : int) = StringMap.fold (fun nonterminal { branches } k ->
let nt = Nonterminal.lookup nonterminal in let nt = Nonterminal.lookup nonterminal in
let k' = List.fold_left (fun k branch -> let k' = List.fold_left (fun k branch ->
let symbols = Array.of_list branch.producers in let symbols = Array.of_list branch.producers in
table.(k) <- (nt, Array.map (fun producer -> Symbol.lookup (producer_symbol producer)) symbols); table.(k) <- (nt, Array.map (fun producer -> Symbol.lookup (producer_symbol producer)) symbols);
identifiers.(k) <- Array.map producer_identifier symbols; identifiers.(k) <- Array.map producer_identifier symbols;
actions.(k) <- Some branch.action; actions.(k) <- Some branch.action;
rhs_attributes.(k) <- Array.map producer_attributes symbols;
production_level.(k) <- branch.branch_production_level; production_level.(k) <- branch.branch_production_level;
prec_decl.(k) <- branch.branch_prec_annotation; prec_decl.(k) <- branch.branch_prec_annotation;
positions.(k) <- [ branch.branch_position ]; positions.(k) <- [ branch.branch_position ];
...@@ -602,8 +627,7 @@ module Production = struct ...@@ -602,8 +627,7 @@ module Production = struct
k' k'
) grammar.rules start ) grammar.rules start
(* Iteration over the productions associated with a specific (* Iteration over the productions associated with a specific nonterminal. *)
nonterminal. *)
let iternt nt f = let iternt nt f =
let k, k' = ntprods.(nt) in let k, k' = ntprods.(nt) in
...@@ -677,6 +701,12 @@ module Production = struct ...@@ -677,6 +701,12 @@ module Production = struct
let positions prod = let positions prod =
positions.(prod) positions.(prod)
let lhs_attributes prod =
Nonterminal.attributes (nt prod)
let rhs_attributes prod =
rhs_attributes.(prod)
let startsymbol2startprod nt = let startsymbol2startprod nt =
try try
NonterminalMap.find nt startprods NonterminalMap.find nt startprods
...@@ -685,6 +715,9 @@ module Production = struct ...@@ -685,6 +715,9 @@ module Production = struct
(* Iteration. *) (* Iteration. *)
let init f =
Array.init n f
let iter f = let iter f =
Misc.iteri n f Misc.iteri n f
...@@ -1349,6 +1382,9 @@ module Analysis = struct ...@@ -1349,6 +1382,9 @@ module Analysis = struct
let follow = follow let follow = follow
let attributes =
grammar.gr_attributes
end end
(* ------------------------------------------------------------------------ *) (* ------------------------------------------------------------------------ *)
......
...@@ -70,6 +70,10 @@ module Nonterminal : sig ...@@ -70,6 +70,10 @@ module Nonterminal : sig
val ocamltype_of_start_symbol: t -> Stretch.ocamltype val ocamltype_of_start_symbol: t -> Stretch.ocamltype
(* Creation of a table indexed by nonterminals. *)
val init: (t -> 'a) -> 'a array
(* Iteration over nonterminals. The order in which elements are (* Iteration over nonterminals. The order in which elements are
examined, and the order of [map]'s output list, correspond to the examined, and the order of [map]'s output list, correspond to the
numeric indices produced by [n2i] above. *) numeric indices produced by [n2i] above. *)
...@@ -98,6 +102,11 @@ module Nonterminal : sig ...@@ -98,6 +102,11 @@ module Nonterminal : sig
val is_start: t -> bool val is_start: t -> bool
(* [attributes nt] is the list of attributes attached with the nonterminal
symbol [nt]. *)
val attributes: t -> Syntax.attribute list
end end
(* ------------------------------------------------------------------------ *) (* ------------------------------------------------------------------------ *)
...@@ -167,6 +176,10 @@ module Terminal : sig ...@@ -167,6 +176,10 @@ module Terminal : sig
val pseudo: t -> bool val pseudo: t -> bool
val real: t -> bool val real: t -> bool
(* Creation of a table indexed by terminals. *)
val init: (t -> 'a) -> 'a array
(* Iteration over terminals. The order in which elements are (* Iteration over terminals. The order in which elements are
examined, and the order of [map]'s output list, correspond to the examined, and the order of [map]'s output list, correspond to the
numeric indices produced by [t2i] above. *) numeric indices produced by [t2i] above. *)
...@@ -183,6 +196,11 @@ module Terminal : sig ...@@ -183,6 +196,11 @@ module Terminal : sig
val iter_real: (t -> unit) -> unit val iter_real: (t -> unit) -> unit
(* [attributes t] is the list of attributes attached with the terminal
symbol [t]. *)
val attributes: t -> Syntax.attribute list
(* The sub-module [Word] offers an implementation of words (that is, (* The sub-module [Word] offers an implementation of words (that is,
sequences) of terminal symbols. It is used by [LRijkstra]. We sequences) of terminal symbols. It is used by [LRijkstra]. We
make it a functor, because it has internal state (a hash table) make it a functor, because it has internal state (a hash table)
...@@ -352,6 +370,19 @@ module Production : sig ...@@ -352,6 +370,19 @@ module Production : sig
val positions: index -> Positions.t list val positions: index -> Positions.t list
(* [lhs_attributes prod] returns the attributes attached with the
head symbol of the production [prod]. It is equivalent to
[Nonterminal.attributes (nt prod)]. [rhs_attributes prod] returns
an array of the attributes attached with each element in the
right-hand side of the production [prod]. *)
val lhs_attributes: index -> Syntax.attributes
val rhs_attributes: index -> Syntax.attributes array
(* Creation of a table indexed by productions. *)
val init: (index -> 'a) -> 'a array
(* Iteration over all productions. The order in which elements (* Iteration over all productions. The order in which elements
are examined, and the order of [map]'s output list, correspond are examined, and the order of [map]'s output list, correspond
to the numeric indices produced by [p2i] above. *) to the numeric indices produced by [p2i] above. *)
...@@ -466,6 +497,10 @@ module Analysis : sig ...@@ -466,6 +497,10 @@ module Analysis : sig
val follow: Nonterminal.t -> TerminalSet.t val follow: Nonterminal.t -> TerminalSet.t
(* [attributes] are the attributes attached with the grammar. *)
val attributes: Syntax.attributes
end end
(* ------------------------------------------------------------------------ *) (* ------------------------------------------------------------------------ *)
......
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