2 * ----------------------------------------------------------------------
3 * PXP: The polymorphic XML parser for Objective Caml.
4 * Copyright by Gerd Stolpmann. See LICENSE for details.
12 let write_expr_ext_id out extid =
15 output_string out ("(Pxp_types.System\"" ^ String.escaped s ^ "\")")
17 output_string out ("(Pxp_types.Public(\"" ^ String.escaped s ^
19 String.escaped t ^ "\"))")
21 output_string out "Pxp_types.Anonymous"
25 let rec write_expr_content_model out cm =
27 Unspecified -> output_string out "Pxp_types.Unspecified"
28 | Empty -> output_string out "Pxp_types.Empty"
29 | Any -> output_string out "Pxp_types.Any"
30 | Mixed msl -> output_string out "(Pxp_types.Mixed [";
33 write_expr_mixed_spec out ms;
34 output_string out "; ";
37 output_string out "])";
38 | Regexp re -> output_string out "(Pxp_types.Regexp ";
39 write_expr_regexp_spec out re;
40 output_string out ")";
42 and write_expr_mixed_spec out ms =
44 MPCDATA -> output_string out "Pxp_types.MPCDATA"
45 | MChild s -> output_string out ("(Pxp_types.MChild \"" ^
46 String.escaped s ^ "\")")
48 and write_expr_regexp_spec out re =
50 Optional re' -> output_string out "(Pxp_types.Optional ";
51 write_expr_regexp_spec out re';
52 output_string out ")";
53 | Repeated re' -> output_string out "(Pxp_types.Repeated ";
54 write_expr_regexp_spec out re';
55 output_string out ")";
56 | Repeated1 re' -> output_string out "(Pxp_types.Repeated1 ";
57 write_expr_regexp_spec out re';
58 output_string out ")";
59 | Alt rel -> output_string out "(Pxp_types.Alt [";
62 write_expr_regexp_spec out re';
63 output_string out "; ";
66 output_string out "])";
67 | Seq rel -> output_string out "(Pxp_types.Seq [";
70 write_expr_regexp_spec out re';
71 output_string out "; ";
74 output_string out "])";
75 | Child s -> output_string out ("(Pxp_types.Child \"" ^
76 String.escaped s ^ "\")")
80 let write_expr_att_type out at =
82 A_cdata -> output_string out "Pxp_types.A_cdata"
83 | A_id -> output_string out "Pxp_types.A_id"
84 | A_idref -> output_string out "Pxp_types.A_idref"
85 | A_idrefs -> output_string out "Pxp_types.A_idrefs"
86 | A_entity -> output_string out "Pxp_types.A_entity"
87 | A_entities -> output_string out "Pxp_types.A_entities"
88 | A_nmtoken -> output_string out "Pxp_types.A_nmtoken"
89 | A_nmtokens -> output_string out "Pxp_types.A_nmtokens"
90 | A_notation sl -> output_string out "(Pxp_types.A_notation [";
93 output_string out ("\"" ^
94 String.escaped s ^ "\"; "))
96 output_string out "])";
97 | A_enum sl -> output_string out "(Pxp_types.A_enum [";
100 output_string out ("\"" ^
101 String.escaped s ^ "\"; "))
103 output_string out "])";
107 let write_expr_att_default out ad =
109 D_required -> output_string out "Pxp_types.D_required"
110 | D_implied -> output_string out "Pxp_types.D_implied"
111 | D_default s -> output_string out ("(Pxp_types.D_default \"" ^
112 String.escaped s ^ "\")")
113 | D_fixed s -> output_string out ("(Pxp_types.D_fixed \"" ^
114 String.escaped s ^ "\")")
118 let write_expr_att_value out av =
120 Value s -> output_string out ("(Pxp_types.Value \"" ^
121 String.escaped s ^ "\")")
122 | Valuelist sl -> output_string out ("(Pxp_types.Valuelist [");
125 output_string out ("\"" ^ String.escaped s ^
129 output_string out "])";
130 | Implied_value -> output_string out "Pxp_types.Implied_value"
134 let ocaml_encoding enc =
136 `Enc_utf8 -> "`Enc_utf8"
137 | `Enc_utf16 -> "`Enc_utf16"
138 | `Enc_utf16_le -> "`Enc_utf16_le"
139 | `Enc_utf16_be -> "`Enc_utf16_be"
140 | `Enc_iso88591 -> "`Enc_iso88591"
144 let write_expr_new_pi out pi =
145 output_string out ("(new Pxp_dtd.proc_instruction \"" ^
146 String.escaped(pi # target) ^ "\" \"" ^
147 String.escaped(pi # value) ^ "\" " ^
148 ocaml_encoding(pi # encoding) ^ ")")
152 let write_expr_node_type out nt =
154 T_data -> output_string out "Pxp_document.T_data"
155 | T_element s -> output_string out ("(Pxp_document.T_element \"" ^
156 String.escaped s ^ "\")")
157 | T_super_root -> output_string out "Pxp_document.T_super_root"
158 | T_pinstr s -> output_string out ("(Pxp_document.T_pinstr \"" ^
159 String.escaped s ^ "\")")
160 | T_comment -> output_string out "Pxp_document.T_comment"
165 let write_local_dtd out (dtd : dtd) =
166 (* Outputs "let mkdtd warner = ... in" to 'out' *)
167 output_string out "let mkdtd warner =\n";
168 output_string out ("let encoding = " ^ ocaml_encoding (dtd # encoding) ^
170 output_string out "let dtdobj = new Pxp_dtd.dtd warner encoding in\n";
173 output_string out "dtdobj # set_id ";
174 begin match dtd # id with
176 | Some(External x) ->
177 output_string out "(Pxp_types.External ";
178 write_expr_ext_id out x;
179 output_string out ");\n"
181 output_string out "(Pxp_types.Derived ";
182 write_expr_ext_id out x;
183 output_string out ");\n"
185 output_string out "Pxp_types.Internal;\n";
188 (* Set standalone declaration: *)
189 output_string out ("dtdobj # set_standalone_declaration " ^
190 string_of_bool (dtd # standalone_declaration) ^ ";\n");
195 let no = dtd # notation noname in
196 output_string out ("let no = new Pxp_dtd.dtd_notation \"" ^
197 String.escaped noname ^ "\" ");
198 write_expr_ext_id out (no # ext_id);
199 output_string out " encoding in\n";
200 output_string out "dtdobj # add_notation no;\n";
202 (List.sort Pervasives.compare (dtd # notation_names));
204 (* Add unparsed entities: *)
207 let en, _ = dtd # gen_entity enname in
208 if en # is_ndata then begin
209 let ext_id = en # ext_id in
210 let notation = en # notation in
211 let encoding = en # encoding in
212 output_string out ("let ndata = new Pxp_entity.ndata_entity \"" ^
213 String.escaped enname ^ "\" ");
214 write_expr_ext_id out ext_id;
215 output_string out ("\"" ^ String.escaped notation ^ "\" " ^
216 ocaml_encoding encoding ^ " in \n");
217 output_string out "dtdobj # add_gen_entity (ndata :> Pxp_entity.entity) false;\n";
220 (List.sort Pervasives.compare (dtd # gen_entity_names));
226 (* Create the element 'el': *)
227 let el = dtd # element elname in
228 output_string out ("let el = new Pxp_dtd.dtd_element dtdobj \"" ^
229 String.escaped elname ^ "\" in\n");
230 output_string out "let cm = ";
231 write_expr_content_model out (el # content_model);
232 output_string out " in\n";
233 output_string out "el # set_cm_and_extdecl cm false;\n";
234 (* Add attributes: *)
237 let atttype, attdefault = el # attribute attname in
238 output_string out ("el # add_attribute \"" ^
239 String.escaped attname ^ "\" ");
240 write_expr_att_type out atttype;
241 output_string out " ";
242 write_expr_att_default out attdefault;
243 output_string out " false;\n";
245 (List.sort Pervasives.compare (el # attribute_names));
247 (* Allow arbitrary? *)
248 if el # arbitrary_allowed then
249 output_string out "el # allow_arbitrary;\n"
251 output_string out "el # disallow_arbitrary;\n";
254 output_string out "el # validate;\n";
256 (* Add the element 'el' to 'dtdobj': *)
257 output_string out "dtdobj # add_element el;\n";
259 (List.sort Pervasives.compare (dtd # element_names));
261 (* Add processing instructions: *)
264 let pilist = dtd # pinstr target in
267 output_string out "let pi = ";
268 write_expr_new_pi out pi;
269 output_string out " in\n";
270 output_string out "dtdobj # add_pinstr pi;\n";
274 (List.sort Pervasives.compare (dtd # pinstr_names));
276 (* Set the name of the root element: *)
277 begin match dtd # root with
280 output_string out ("dtdobj # set_root \"" ^
281 String.escaped rootname ^ "\";\n")
284 (* Special options: *)
285 if dtd # arbitrary_allowed then
286 output_string out "dtdobj # allow_arbitrary;\n"
288 output_string out "dtdobj # disallow_arbitrary;\n";
291 output_string out "dtdobj in\n"
295 let rec write_local_subtree out n =
296 (* Outputs the term generating the subtree *)
298 output_string out "let nt = ";
299 write_expr_node_type out (n # node_type);
300 output_string out " in\n";
302 begin match n # node_type with
304 output_string out ("let t = Pxp_document.create_data_node spec dtd \"" ^
305 String.escaped (n # data) ^ "\" in\n")
306 | T_element elname ->
307 let loc, line, col = n # position in
309 ("let pos = \"" ^ String.escaped loc ^ "\", " ^
310 string_of_int line ^ ", " ^
311 string_of_int col ^ " in\n");
313 ("let t = Pxp_document.create_element_node ~position:pos spec dtd \"" ^
314 String.escaped elname ^ "\" [ ");
317 begin match value with
319 output_string out ("\"" ^ String.escaped name ^ "\", ");
320 output_string out ("\"" ^ String.escaped s ^ "\"; ")
322 output_string out ("\"" ^ String.escaped name ^ "\", ");
323 output_string out ("\"" ^
324 String.escaped (String.concat " " sl) ^
331 output_string out " ] in\n";
333 let loc, line, col = n # position in
335 ("let pos = \"" ^ String.escaped loc ^ "\", " ^
336 string_of_int line ^ ", " ^
337 string_of_int col ^ " in\n");
339 ("let t = Pxp_document.create_super_root_node ~position:pos spec dtd in\n")
341 let loc, line, col = n # position in
343 ("let pos = \"" ^ String.escaped loc ^ "\", " ^
344 string_of_int line ^ ", " ^
345 string_of_int col ^ " in\n");
346 output_string out "let pi = ";
347 write_expr_new_pi out (List.hd (n # pinstr piname));
348 output_string out " in\n";
350 ("let t = Pxp_document.create_pinstr_node ~position:pos spec dtd pi in\n")
352 let loc, line, col = n # position in
354 ("let pos = \"" ^ String.escaped loc ^ "\", " ^
355 string_of_int line ^ ", " ^
356 string_of_int col ^ " in\n");
357 output_string out "let comment = ";
358 ( match n # comment with
360 | Some c -> output_string out ("\"" ^ String.escaped c ^ "\"")
362 output_string out " in\n";
364 ("let t = Pxp_document.create_comment_node ~position:pos spec dtd comment in\n")
369 (* Add processing instructions: *)
370 begin match n # node_type with
376 let pilist = n # pinstr target in
379 output_string out "let pi = ";
380 write_expr_new_pi out pi;
381 output_string out " in\n";
382 output_string out "add_pinstr t pi;\n";
386 (List.sort Pervasives.compare (n # pinstr_names));
389 (* Add the sub nodes: *)
392 output_string out "add_node t (\n";
393 write_local_subtree out n';
394 output_string out ");\n";
398 output_string out "local_validate t;\n";
401 output_string out "t\n"
405 let write_local_document out (d : 'ext document) =
406 (* Outputs "let mkdoc warner spec = ... in" *)
408 output_string out "let mkdoc warner spec =\n";
409 output_string out "let doc = new Pxp_document.document warner in\n";
410 output_string out ("doc # init_xml_version \"" ^
411 String.escaped (d # xml_version) ^ "\";\n");
412 write_local_dtd out (d # dtd);
413 output_string out "let dtd = mkdtd warner in\n";
414 output_string out "let root = ";
415 write_local_subtree out (d # root);
416 output_string out " in\n";
417 output_string out "doc # init_root root;\n";
419 (* Add processing instructions: *)
422 let pilist = d # pinstr target in
425 output_string out "let pi = ";
426 write_expr_new_pi out pi;
427 output_string out " in\n";
428 output_string out "doc # add_pinstr pi;\n";
432 (List.sort Pervasives.compare (d # pinstr_names));
434 (* Return the result: *)
435 output_string out "doc in\n"
439 let write_helpers out =
440 output_string out "let add_node t n = (t : 'ext Pxp_document.node) # add_node (n : 'ext Pxp_document.node) in\n";
441 output_string out "let add_pinstr t pi = (t : 'ext Pxp_document.node) # add_pinstr (pi : Pxp_dtd.proc_instruction) in\n";
442 output_string out "let local_validate t = (t : 'ext Pxp_document.node) # local_validate ()in\n"
446 let write_document out d =
447 output_string out "let create_document warner spec =\n";
449 write_local_document out d;
450 output_string out "mkdoc warner spec;;\n"
454 let write_dtd out dtd =
455 output_string out "let create_dtd warner =\n";
456 write_local_dtd out dtd;
457 output_string out "mkdtd warner;;\n"
461 let write_subtree out t =
462 output_string out "let create_subtree dtd spec =\n";
464 write_local_subtree out t;
465 output_string out "mktree dtd spec;;\n"
468 (* ======================================================================
472 * Revision 1.1 2000/11/17 09:57:29 lpadovan
475 * Revision 1.7 2000/08/30 15:48:07 gerd
478 * Revision 1.6 2000/08/18 20:16:59 gerd
479 * Updates because of new node types T_comment, T_pinstr, T_super_root.
481 * Revision 1.5 2000/07/23 02:16:51 gerd
482 * Changed signature of local_validate.
484 * Revision 1.4 2000/07/09 17:59:35 gerd
485 * Updated: The position of element nodes is also written.
487 * Revision 1.3 2000/07/09 00:30:00 gerd
488 * Notations are written before they are used.
489 * Unparsed entities are included.
492 * Revision 1.2 2000/07/08 22:59:14 gerd
493 * [Merging 0.2.10:] Improved: The resulting code can be compiled
494 * faster, and the compiler is less hungry on memory.
495 * Updated because of PXP interface changes.
497 * Revision 1.1 2000/05/29 23:48:38 gerd
498 * Changed module names:
499 * Markup_aux into Pxp_aux
500 * Markup_codewriter into Pxp_codewriter
501 * Markup_document into Pxp_document
502 * Markup_dtd into Pxp_dtd
503 * Markup_entity into Pxp_entity
504 * Markup_lexer_types into Pxp_lexer_types
505 * Markup_reader into Pxp_reader
506 * Markup_types into Pxp_types
507 * Markup_yacc into Pxp_yacc
508 * See directory "compatibility" for (almost) compatible wrappers emulating
509 * Markup_document, Markup_dtd, Markup_reader, Markup_types, and Markup_yacc.
511 * ======================================================================
512 * Old logs from markup_codewriter.ml:
514 * Revision 1.1 2000/03/11 22:57:28 gerd