Ensuite, petite remarque : pour améliorer l'abstraction du code, je te conseille de remplacer les "string" par des types créés à l'occasion type tag = string
type xmls = Elem of (tag * (string * string) list * xmls list);;
Et ainsi de suite.
type tag = string
type key = string
type value = string
type xmls = Elem of (tag * ((key * value) option)) * ((xmls list) option)
type field = {
tag : key;
key : key option;
value : value option;
children : field list option;
}
(*
*)
let monXMLS = Elem (
("foo", Some ("bar","qux")),
Some [
Elem( ("jour", Some ("heure","midi")), None);
Elem( ("nuit", None), None)])
let rec parse xmls = match xmls with
| Elem((t,kvOpt),lOpt) -> parseElem t kvOpt lOpt
and parseElem t kvOpt lOpt =
let (k,v) = match kvOpt with
| Some (k,v) -> (Some k, Some v)
| None -> (None, None)
in let l = match lOpt with
| Some l -> Some (List.map parse l) (* appel récursif d'abord, avant de créer le parent *)
| None -> None in
{
tag = t;
key = k;
value = v;
children = l;
};;
parse monXMLS;;
Une autre solution consiste à utiliser ocamllex et ocamlyacc directement (et encore, tu dois pouvoir utiliser yacc avec tes propres données, sans passer par un lexeur).
# Parsing
Posté par Axioplase ıɥs∀ (site web personnel) . En réponse au message [OCaml] Quel stratégie pour transformer un arbre en grammaire ?. Évalué à 3.
Bon, en fait, tu veux simplement écrire un "bête" analyseur grammatical (un "parser").
Pour cela, de bons indices ici: http://caml.inria.fr/pub/docs/oreilly-book/html.bak/book-ora(...)
Sinon, à la main (cf mon code plus bas)
Ensuite, petite remarque : pour améliorer l'abstraction du code, je te conseille de remplacer les "string" par des types créés à l'occasion
type tag = stringtype xmls = Elem of (tag * (string * string) list * xmls list);;
Et ainsi de suite.
type tag = string
type key = string
type value = string
type xmls = Elem of (tag * ((key * value) option)) * ((xmls list) option)
type field = {
tag : key;
key : key option;
value : value option;
children : field list option;
}
(*
*)
let monXMLS = Elem (
("foo", Some ("bar","qux")),
Some [
Elem( ("jour", Some ("heure","midi")), None);
Elem( ("nuit", None), None)])
let rec parse xmls = match xmls with
| Elem((t,kvOpt),lOpt) -> parseElem t kvOpt lOpt
and parseElem t kvOpt lOpt =
let (k,v) = match kvOpt with
| Some (k,v) -> (Some k, Some v)
| None -> (None, None)
in let l = match lOpt with
| Some l -> Some (List.map parse l) (* appel récursif d'abord, avant de créer le parent *)
| None -> None in
{
tag = t;
key = k;
value = v;
children = l;
};;
parse monXMLS;;
Une autre solution consiste à utiliser ocamllex et ocamlyacc directement (et encore, tu dois pouvoir utiliser yacc avec tes propres données, sans passer par un lexeur).