~ubuntu-branches/ubuntu/oneiric/ocsigen/oneiric

« back to all changes in this revision

Viewing changes to xmlp4/oldocaml/xmllexer.ml

  • Committer: Bazaar Package Importer
  • Author(s): Stephane Glondu
  • Date: 2009-07-02 10:02:08 UTC
  • mfrom: (1.1.9 upstream) (4.1.3 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090702100208-n158b1sqwzn0asil
Tags: 1.2.0-2
Fix build on non-native architectures

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
(* camlp4r *)
2
 
 
3
 
(* xmllexer.ml provide a generic XML lexer for Camlp4. *)
4
 
(* Manuel.Maarek@macs.hw.ac.uk (Heriot-Watt University) *)
5
 
(* Manuel.Maarek@spi.lip6.fr (LIP6) *)
6
 
(* Modif by VB for xmlp4 *)
7
 
 
8
 
 
9
 
(* derived from the default lexer of Camlp4: plexer.ml *)
10
 
(***********************************************************************)
11
 
(*                                                                     *)
12
 
(*                             Camlp4                                  *)
13
 
(*                                                                     *)
14
 
(*        Daniel de Rauglaudre, projet Cristal, INRIA Rocquencourt     *)
15
 
(*                                                                     *)
16
 
(*  Copyright 2002 Institut National de Recherche en Informatique et   *)
17
 
(*  Automatique.  Distributed only by permission.                      *)
18
 
(*                                                                     *)
19
 
(***********************************************************************)
20
 
(* based on: plexer.ml,v 1.10 2002/07/19 *)
21
 
 
22
 
open Stdpp;
23
 
open Token;
24
 
 
25
 
 
26
 
(* The string buffering machinery *)
27
 
 
28
 
value buff = ref (String.create 80);
29
 
value store len x =
30
 
  do {
31
 
    if len >= String.length buff.val then
32
 
      buff.val := buff.val ^ String.create (String.length buff.val)
33
 
    else ();
34
 
    buff.val.[len] := x;
35
 
    succ len
36
 
  }
37
 
;
38
 
value mstore len s =
39
 
  add_rec len 0 where rec add_rec len i =
40
 
    if i == String.length s then len else add_rec (store len s.[i]) (succ i)
41
 
;
42
 
value get_buff len = String.sub buff.val 0 len;
43
 
 
44
 
 
45
 
value string_of_space_char = fun
46
 
  [ ' ' -> " "
47
 
  | '\n' -> "\n"
48
 
  | '\t' -> "\t"
49
 
  | _ -> "" ];
50
 
 
51
 
(* The lexer *)
52
 
 
53
 
value rec ident len =
54
 
  parser
55
 
  [ [: `('A'..'Z' | 'a'..'z' | '\192'..'\214' | '\216'..'\246' |
56
 
         '\248'..'\255' | '0'..'9' | '_' | ''' as
57
 
         c)
58
 
        ;
59
 
       s :] ->
60
 
      ident (store len c) s
61
 
  | [: :] -> len ]
62
 
and ident2 len =
63
 
  parser
64
 
  [ [: `('!' | '?' | '~' | '=' | '@' | '^' | '&' | '+' | '-' | '*' | '/' |
65
 
         '%' | '.' | ':' | '<' | '>' | '|' | '$' as
66
 
         c)
67
 
        ;
68
 
       s :] ->
69
 
      ident2 (store len c) s
70
 
  | [: :] -> len ]
71
 
and ident3 len =
72
 
  parser
73
 
  [ [: `('0'..'9' | 'A'..'Z' | 'a'..'z' | '\192'..'\214' | '\216'..'\246' |
74
 
         '\248'..'\255' | '_' | '!' | '%' | '&' | '*' | '+' | '-' | '.' |
75
 
         '/' | ':' | '<' | '=' | '>' | '?' | '@' | '^' | '|' | '~' | ''' |
76
 
         '$' as
77
 
         c)
78
 
        ;
79
 
       s :] ->
80
 
      ident3 (store len c) s
81
 
  | [: :] -> len ]
82
 
;
83
 
 
84
 
value error_on_unknown_keywords = ref False;
85
 
value err loc msg = raise_with_loc loc (Token.Error msg);
86
 
 
87
 
value ((begin_attr, end_attr), waiting_for_attr) =
88
 
  let b = ref False in
89
 
  (((fun () -> b.val := True),
90
 
   (fun () -> b.val := False)),
91
 
  (fun () -> b.val));
92
 
 
93
 
 
94
 
value ((push_tag,pop_tag),(size_tag_stack,string_of_tag_stack)) =
95
 
  let stack = Stack.create () in
96
 
  ((
97
 
   (fun t -> Stack.push t stack)
98
 
     ,
99
 
   (fun () -> try Stack.pop stack with [Stack.Empty -> "" ])
100
 
  ),
101
 
   ((fun () -> Stack.length stack)
102
 
      ,
103
 
    (fun () ->
104
 
      let s = ref "" in
105
 
      do {
106
 
       Stack.iter
107
 
         (fun tag -> s.val := (if (s.val == "") then " " else s.val) ^ tag)
108
 
         stack;
109
 
         s.val}
110
 
     )
111
 
   ));
112
 
 
113
 
value next_token_fun find_kwd fname lnum bolpos =
114
 
  let make_pos p =
115
 
    do{
116
 
     {Lexing.pos_fname = fname.val; Lexing.pos_lnum = lnum.val;
117
 
      Lexing.pos_bol = bolpos.val; Lexing.pos_cnum = p}} in
118
 
  let mkloc (bp, ep) = (make_pos bp, make_pos ep) in
119
 
  let keyword_or_error (bp,ep) s =
120
 
    let loc = mkloc (bp, ep) in
121
 
      try (("", find_kwd s), loc) with
122
 
      [ Not_found ->
123
 
        if error_on_unknown_keywords.val then err loc ("illegal token: " ^ s)
124
 
        else (("", s), loc) ]
125
 
  in
126
 
  let rec next_token =
127
 
    ( fun s ->
128
 
      if waiting_for_attr () then
129
 
        next_token_attr s
130
 
      else
131
 
        next_token_normal s )
132
 
  and next_token_attr =
133
 
    parser bp
134
 
    [ [: `(' ' | '\t'); s :] -> next_token s
135
 
      | [: `('\013' | '\010'); s :] ep ->
136
 
        do {bolpos.val := ep; incr lnum; next_token s}
137
 
      |        [: `('a'..'z' | 'A'..'Z' | '_' | ':' as c); s
138
 
         :] -> name_attribut bp (store 0 c) s
139
 
      |        [: `'=' :] ep -> (("","="),mkloc (bp,ep))
140
 
      |        [: `'"'; s :] ep ->
141
 
          (("VALUE", get_buff (value_attribut_in_double_quote bp 0 s)),mkloc (bp,ep))
142
 
      |        [: `'''; s :] ep ->
143
 
          (("VALUE", get_buff (value_attribut_in_quote bp 0 s)),mkloc (bp,ep))
144
 
      |        [: `'$'; s :] -> (* for caml expressions *) camlexprattr (bp+1) 0 s
145
 
      |        [: `'/'; `'>' :] ep ->
146
 
          let name = pop_tag () in
147
 
          do {
148
 
          end_attr ();
149
 
          (("GAT",name),mkloc (bp,ep)) }
150
 
      |        [: `'>'; s :] -> do { end_attr (); next_token s}
151
 
    ]
152
 
  and next_token_normal =
153
 
    parser bp
154
 
    [ [: `(' ' | '\t' | '\026' | '\012' as c); s :] ep ->
155
 
      let c_string = string_of_space_char c in
156
 
      (("WHITESPACE",
157
 
        get_buff (whitespaces bp (mstore 0 c_string) s)),mkloc (bp,ep))
158
 
    | [: `('\013' | '\010' as c); s :] ep ->
159
 
      let c_string = string_of_space_char c in
160
 
      do {bolpos.val := ep; incr lnum;
161
 
      (("WHITESPACE",
162
 
        get_buff (whitespaces bp (mstore 0 c_string) s)),mkloc (bp,ep))}
163
 
    | [: `('A'..'Z' | '\192'..'\214' | '\216'..'\222' | 'a'..'z' |
164
 
      '\223'..'\246' | '\248'..'\255' | '_' | '1'..'9' | '0' | '\'' | '"' |
165
 
      (* '$' | *)
166
 
      '!' | '=' | '@' | '^' | '&' | '+' | '-' | '*' | '/' | '%' | '~' |
167
 
      '?' | ':' | '|' | '[' | ']' | '{' | '}' | '.' | ';' | ',' | '\\' | '(' |
168
 
      ')' | '#' | '>' | '`'
169
 
        as c); s :] ep ->
170
 
          (("DATA", get_buff (data bp (store 0 c) s)),mkloc (bp,ep))
171
 
    | [: `'$'; s :] -> (* for caml expr *) camlexpr (bp+1) s
172
 
    | [: `'<'; s :] ->
173
 
        match s with parser
174
 
      [        [: `'?'; `'x'; `'m'; `'l';
175
 
         len = question_mark_tag bp 0
176
 
           :] ep -> (("XMLDECL", get_buff len), mkloc (bp, ep))
177
 
      |        [: `'!'; s :] ->
178
 
          match s with parser
179
 
            [ [: `'-'; `'-'; ct :] ep ->
180
 
                (("COMMENT", get_buff (comment_tag 0 bp 0 ct)),
181
 
                 mkloc (bp,ep))
182
 
            | [: len = exclamation_mark_tag bp 0
183
 
                 :] ep -> (("DECL", get_buff len),mkloc (bp,ep)) ]
184
 
      |        [: `'/'; `('a'..'z' | 'A'..'Z' | '_' | ':' as c); s
185
 
           :] -> end_tag bp (store 0 c) s
186
 
      |        [: `('a'..'z' | 'A'..'Z' | '_' (* | ':'*) as c); s
187
 
           :] -> start_tag bp (store 0 c) s ]
188
 
    | [: `c :] ep -> keyword_or_error (bp,ep) (String.make 1 c)
189
 
    | [: _ = Stream.empty :] ep ->
190
 
        let size = size_tag_stack () in
191
 
        if (size == 0)
192
 
        then
193
 
          do {lnum.val := 1;
194
 
            (("EOI", ""), mkloc (bp, succ bp))}
195
 
        else
196
 
          err (mkloc (bp, ep)) ( (string_of_int size) ^ " tag" ^ (if size == 1 then "" else "s") ^ " not terminated (" ^ (string_of_tag_stack ()) ^ ").")
197
 
    ]
198
 
 
199
 
(* XML *)
200
 
  and question_mark_tag bp len =
201
 
    parser
202
 
    [ [: `'?'; `'>' :] -> len
203
 
    | [: `c; s :] -> question_mark_tag bp (store len c) s
204
 
    | [: :] ep -> err (mkloc (bp, ep)) "XMLDecl tag (<? ?>) not terminated" ]
205
 
  and comment_tag prof bp len =
206
 
    parser
207
 
    [ [: `'-'; s :] -> dash_in_comment_tag prof bp len s
208
 
      |        [: `'<'; s :] -> comment_tag2 prof bp len s
209
 
      |        [: `c; s :] -> comment_tag prof bp (store len c) s
210
 
      | [: :] ep -> err (mkloc (bp, ep)) "comment (<!-- -->) not terminated" ]
211
 
  and comment_tag2 prof bp len =
212
 
    parser
213
 
    [ [: `'!'; s :] -> comment_tag3 prof bp len s
214
 
      |        [: s :] -> comment_tag prof bp (store len '<') s ]
215
 
  and comment_tag3 prof bp len =
216
 
    parser
217
 
    [ [: `'-'; s :] -> comment_tag4 prof bp len s
218
 
      |        [: s :] -> comment_tag prof bp (mstore len "<!") s ]
219
 
  and comment_tag4 prof bp len =
220
 
    parser
221
 
    [ [: `'-'; s :] -> comment_tag (prof+1) bp (mstore len "<!--") s
222
 
      |        [: s :] -> comment_tag prof bp (mstore len "<!-") s ]
223
 
  and dash_in_comment_tag prof bp len =
224
 
    parser
225
 
    [ [: `'-'; s :] -> dash_in_comment_tag2 prof bp len s
226
 
    | [: a = comment_tag prof bp (store len '-') :] -> a ]
227
 
  and dash_in_comment_tag2 prof bp len =
228
 
    parser
229
 
    [ [: `'>'; s :] -> if prof = 0
230
 
                    then len
231
 
                    else comment_tag (prof-1) bp (mstore len "-->") s
232
 
    | [: a = comment_tag prof bp (mstore len "--") :] -> a ]
233
 
  and exclamation_mark_tag bp len =
234
 
    parser bp_sb
235
 
    [ [: `'>' :] -> len
236
 
    | [: `('[' as c); s :] ->
237
 
        sq_bracket_in_exclamation_mark_tag bp_sb (store len c) s
238
 
    | [: `c; s :] -> exclamation_mark_tag bp (store len c) s
239
 
    | [: :] ep -> err (mkloc (bp, ep)) "Decl tag (<! >) not terminated" ]
240
 
  and sq_bracket_in_exclamation_mark_tag bp len =
241
 
    parser
242
 
      [ [: `(']' as c ); s :] ->
243
 
          exclamation_mark_tag bp (store len c) s
244
 
      | [: `c; s :] -> sq_bracket_in_exclamation_mark_tag bp (store len c) s
245
 
      | [: :] ep -> err (mkloc (bp, ep))
246
 
            "Decl tag with open square bracket (<! ... [) not terminated" ]
247
 
  and end_tag bp len =
248
 
    parser
249
 
    [ [: `'>' :] ep ->
250
 
      let name = get_buff len in
251
 
      let last_open = pop_tag () in
252
 
      if last_open = name then
253
 
        (("GAT",name), mkloc (bp,ep))
254
 
      else
255
 
               err (mkloc (bp, ep)) ("bad end tag: </"
256
 
                      ^ name
257
 
                      ^ ">"
258
 
                      ^ (
259
 
                        if last_open = "" then
260
 
                          ""
261
 
                        else
262
 
                          " (</" ^last_open ^ "> expected)"
263
 
                       ))
264
 
      | [: `('a'..'z' | 'A'..'Z' | '1'..'9' | '0' |
265
 
        '.' | '-' | '_' | ':'  as c); s :] -> end_tag bp (store len c) s
266
 
      |        [: :] ep -> err (mkloc (bp, ep)) "end tag (</ >) not terminated" ]
267
 
  and start_tag bp len =
268
 
    parser
269
 
    [ [: `'>' :] ep ->
270
 
      let name = get_buff len in
271
 
      do { push_tag name;
272
 
           (("TAG", name), mkloc (bp,ep)) }
273
 
      |        [: `('\013' | ' ' | '\t') :] ep ->
274
 
          let name = get_buff len in
275
 
          do { push_tag name;
276
 
               begin_attr ();
277
 
               (("TAG", name), mkloc (bp,ep)) }
278
 
      |        [: `('\010') :] ep ->
279
 
          let name = get_buff len in
280
 
          do { bolpos.val := ep; incr lnum;
281
 
               push_tag name;
282
 
               begin_attr ();
283
 
               (("TAG", name), mkloc (bp,ep)) }
284
 
      | [: `( 'a'..'z' | 'A'..'Z' | '1'..'9' | '0' |
285
 
        '.' | '-' | '_' | ':' as c); s :] ->
286
 
            start_tag bp (store len c) s
287
 
      |        [: :] ep ->
288
 
          let name = get_buff len in
289
 
          do { push_tag name;
290
 
               begin_attr ();
291
 
               (("TAG", name), mkloc (bp,ep)) } ]
292
 
 (*     |        [: :] ep -> err (mkloc (bp, ep)) "start tag (< > or < />) not terminated" ] *)
293
 
  and name_attribut bp len =
294
 
    parser
295
 
    [ [: `('\013' | ' ' | '\t') :] ep ->
296
 
      (("ATTR",get_buff len), mkloc (bp,ep))
297
 
      |        [: `('\010') :] ep ->
298
 
      do { bolpos.val := ep; incr lnum ; (("ATTR",get_buff len), mkloc (bp,ep))}
299
 
      |        [: `( 'a'..'z' | 'A'..'Z' | '1'..'9' | '0' |
300
 
    '.' | '-' | '_' | ':'
301
 
      as c); s :] -> name_attribut bp (store len c) s
302
 
      |        [: s :] ep -> (("ATTR",get_buff len), mkloc (bp,ep))
303
 
      |        [: :] ep -> err (mkloc (bp, ep)) "start tag (< > or < />) not terminated" ]
304
 
  and value_attribut_in_double_quote bp len =
305
 
    parser
306
 
    [ [: `'"' :] -> len
307
 
(*      |        [: `'\\'; `'"'; s :] ->
308
 
          value_attribut_in_double_quote bp (store (store len '\\') '"') s *)
309
 
      |        [: `c; s :] ->
310
 
          value_attribut_in_double_quote bp (store len c) s
311
 
      |        [: :] ep -> err (mkloc (bp, ep)) "attribut value not terminated" ]
312
 
  and camlexpr bp =
313
 
    parser
314
 
    [ [: `('a'..'z' | '\223'..'\246' | '\248'..'\255' | '_' as c); s :] ->
315
 
      antiquotname bp ((ident (store 0 c)) s) s
316
 
    | [: `'$'; s :] ep -> (("DATA", "$"), mkloc (bp,ep))
317
 
    | [: s :] ep -> (("CAMLEXPRXML", get_buff (camlexpr2 bp 0 s)),
318
 
                     mkloc (bp,ep)) ]
319
 
  and antiquotname bp len =
320
 
    parser bp2
321
 
    [ [: `':'; s :] ep -> let buff = get_buff len in
322
 
    let bp2 = bp2+2 in
323
 
    if buff = "list"
324
 
    then (("CAMLEXPRXMLL", get_buff (camlexpr2 bp2 0 s)), mkloc (bp2,ep))
325
 
    else if buff = "str"
326
 
    then (("CAMLEXPRXMLS", get_buff (camlexpr2 bp2 0 s)), mkloc (bp2,ep))
327
 
    else err (mkloc (bp, ep)) "unknown antiquotation"
328
 
    | [: `'$'; s :] ep -> (("CAMLEXPRXML", (get_buff len)), mkloc (bp,ep))
329
 
    | [: s :] ep -> (("CAMLEXPRXML", get_buff (camlexpr2 bp len s)),
330
 
                     mkloc (bp,ep)) ]
331
 
  and camlexpr2 bp len =
332
 
    parser
333
 
    [ [: `'$'; s :] -> len
334
 
    | [: `('\010' as c) ; s :] ep ->
335
 
     do { bolpos.val := ep; incr lnum;
336
 
     camlexpr2 bp (store len c) s}
337
 
    | [: `(_ as c) ; s :] -> camlexpr2 bp (store len c) s ]
338
 
 
339
 
 
340
 
 
341
 
  and camlexprattr bp len =
342
 
    parser
343
 
    [ [: `('a'..'z' | '\223'..'\246' | '\248'..'\255' | '_' as c); s :] ->
344
 
      antiquotname_attr bp ((ident (store 0 c)) s) s
345
 
    | [: `'$'; s :] ep -> (("DATA", "$"), mkloc (bp,ep))
346
 
    | [: s :] ep -> (("CAMLEXPR", get_buff (camlexpr2 bp 0 s)),
347
 
                     mkloc (bp,ep)) ]
348
 
  and antiquotname_attr bp len =
349
 
    parser
350
 
    [ [: `':'; s :] ep -> let buff = get_buff len in
351
 
        if buff = "list"
352
 
        then (("CAMLEXPRL", get_buff (camlexpr2 bp 0 s)), mkloc (bp,ep))
353
 
        else err (mkloc (bp, ep)) "unknown antiquotation"
354
 
    | [: `'$'; s :] ep -> (("CAMLEXPR", get_buff len), mkloc (bp,ep))
355
 
    | [: s :] ep -> (("CAMLEXPR", get_buff (camlexpr2 bp len s)), mkloc (bp,ep)) ]
356
 
 
357
 
  and value_attribut_in_quote bp len =
358
 
    parser
359
 
    [ [: `''' :] -> len
360
 
      |        [: `'\\'; `'''; s :] ->
361
 
          value_attribut_in_quote bp (store (store len '\\') ''') s
362
 
      |        [: `c; s :] ->
363
 
          value_attribut_in_quote bp (store len c) s
364
 
      |        [: :] ep -> err (mkloc (bp, ep)) "attribut value not terminated" ]
365
 
  and data bp len =
366
 
    parser
367
 
    [ (* [: `(' ' | '\n' | '\t' as c); s :] ->
368
 
      let c_string = string_of_space_char c in
369
 
      spaces_in_data bp len c_string s
370
 
    | *) [: `('A'..'Z' | '\192'..'\214' | '\216'..'\222' | 'a'..'z' |
371
 
      '\223'..'\246' | '\248'..'\255' | '_' | '1'..'9' | '0' | '\'' | '"' |
372
 
      (* '$' | *)
373
 
      '!' | '=' | '@' | '^' | '&' | '+' | '-' | '*' | '/' | '%' | '~' |
374
 
      '?' | ':' | '|' | '[' | ']' | '{' | '}' | '.' | ';' | ',' | '\\' | '(' |
375
 
      ')' | '#' | '>' | '`'
376
 
        as c) ; s :] -> data bp (store len c) s
377
 
    | [: s :] -> len ]
378
 
(*  and spaces_in_data bp len spaces =
379
 
    parser
380
 
    [ [: `('\n' as c); s :] ep ->
381
 
      let c_string = string_of_space_char c in
382
 
      do { bolpos.val := ep; incr lnum ; spaces_in_data bp len (spaces ^ c_string) s}
383
 
    | [: `(' ' | '\t' as c); s :] ->
384
 
      let c_string = string_of_space_char c in
385
 
      spaces_in_data bp len (spaces ^ c_string) s
386
 
    | [: `('A'..'Z' | '\192'..'\214' | '\216'..'\222' | 'a'..'z' |
387
 
      '\223'..'\246' | '\248'..'\255' | '_' | '1'..'9' | '0' | '\'' | '"' |
388
 
      (* '$' | *)
389
 
      '!' | '=' | '@' | '^' | '&' | '+' | '-' | '*' | '/' | '%' | '~' |
390
 
      '?' | ':' | '|' | '[' | ']' | '{' | '}' | '.' | ';' | ',' | '\\' | '(' |
391
 
      ')' | '#' | '`'
392
 
        as c) ; s :] ->
393
 
                 data bp (store (mstore len spaces) c) s
394
 
    | [: s :] -> len ] *)
395
 
  and whitespaces bp len =
396
 
    parser
397
 
    [ [: `('\013' | ' ' | '\t' | '\026' | '\012' as c); s :] ->
398
 
      let c_string = string_of_space_char c in
399
 
      whitespaces bp (mstore len c_string) s
400
 
    | [: `('\010' as c); s :] ep ->
401
 
      let c_string = string_of_space_char c in
402
 
      do { bolpos.val := ep; incr lnum;
403
 
           whitespaces bp (mstore len c_string) s}
404
 
    | [: s :] -> len ]
405
 
(* /XML *)
406
 
 
407
 
  in
408
 
  fun cstrm ->
409
 
    try
410
 
      next_token cstrm
411
 
    with
412
 
    [ Stream.Error str ->
413
 
        err (mkloc (Stream.count cstrm, Stream.count cstrm + 1)) str ]
414
 
;
415
 
 
416
 
value func kwd_table =
417
 
  let bolpos = ref 0 in
418
 
  let lnum = ref 1 in
419
 
  let fname = ref "" in
420
 
  let find = Hashtbl.find kwd_table in
421
 
  Token.lexer_func_of_parser (next_token_fun find fname lnum bolpos)
422
 
;
423
 
 
424
 
value rec check_keyword_stream =
425
 
  parser [: _ = check; _ = Stream.empty :] -> True
426
 
and check =
427
 
  parser
428
 
  [ [: `'A'..'Z' | 'a'..'z' | '\192'..'\214' | '\216'..'\246' | '\248'..'\255'
429
 
        ;
430
 
       s :] ->
431
 
      check_ident s
432
 
  | [: `'!' | '?' | '~' | '=' | '@' | '^' | '&' | '+' | '-' | '*' | '/' |
433
 
        '%' | '.'
434
 
        ;
435
 
       s :] ->
436
 
      check_ident2 s
437
 
  | [: `'<'; s :] ->
438
 
      match Stream.npeek 1 s with
439
 
      [ [':' | '<'] -> ()
440
 
      | _ -> check_ident2 s ]
441
 
  | [: `':';
442
 
       _ =
443
 
         parser
444
 
         [ [: `']' | ':' | '=' | '>' :] -> ()
445
 
         | [: :] -> () ] :] ->
446
 
      ()
447
 
  | [: `'>' | '|';
448
 
       _ =
449
 
         parser
450
 
         [ [: `']' | '}' :] -> ()
451
 
         | [: a = check_ident2 :] -> a ] :] ->
452
 
      ()
453
 
  | [: `'[' | '{'; s :] ->
454
 
      match Stream.npeek 2 s with
455
 
      [ ['<'; '<' | ':'] -> ()
456
 
      | _ ->
457
 
          match s with parser
458
 
          [ [: `'|' | '<' | ':' :] -> ()
459
 
          | [: :] -> () ] ]
460
 
  | [: `';';
461
 
       _ =
462
 
         parser
463
 
         [ [: `';' :] -> ()
464
 
         | [: :] -> () ] :] ->
465
 
      ()
466
 
  | [: `_ :] -> () ]
467
 
and check_ident =
468
 
  parser
469
 
  [ [: `'A'..'Z' | 'a'..'z' | '\192'..'\214' | '\216'..'\246' |
470
 
        '\248'..'\255' | '0'..'9' | '_' | '''
471
 
        ;
472
 
       s :] ->
473
 
      check_ident s
474
 
  | [: :] -> () ]
475
 
and check_ident2 =
476
 
  parser
477
 
  [ [: `'!' | '?' | '~' | '=' | '@' | '^' | '&' | '+' | '-' | '*' | '/' |
478
 
        '%' | '.' | ':' | '<' | '>' | '|'
479
 
        ;
480
 
       s :] ->
481
 
      check_ident2 s
482
 
  | [: :] -> () ]
483
 
;
484
 
 
485
 
value check_keyword s =
486
 
  try check_keyword_stream (Stream.of_string s) with _ -> False
487
 
;
488
 
 
489
 
value error_no_respect_rules p_con p_prm =
490
 
  raise
491
 
     (Token.Error
492
 
         ("the token " ^
493
 
          (if p_con = "" then "\"" ^ p_prm ^ "\""
494
 
           else if p_prm = "" then p_con
495
 
           else p_con ^ " \"" ^ p_prm ^ "\"") ^
496
 
          " does not respect Plexer rules"))
497
 
;
498
 
 
499
 
value error_ident_and_keyword p_con p_prm =
500
 
  raise
501
 
    (Token.Error
502
 
        ("the token \"" ^ p_prm ^ "\" is used as " ^ p_con ^
503
 
         " and as keyword"))
504
 
;
505
 
 
506
 
value using_token kwd_table ident_table (p_con, p_prm) =
507
 
  match p_con with
508
 
  [ "" ->
509
 
      if not (Hashtbl.mem kwd_table p_prm) then
510
 
        if check_keyword p_prm then
511
 
          if Hashtbl.mem ident_table p_prm then
512
 
            error_ident_and_keyword (Hashtbl.find ident_table p_prm) p_prm
513
 
          else Hashtbl.add kwd_table p_prm p_prm
514
 
        else error_no_respect_rules p_con p_prm
515
 
      else ()
516
 
  | "QUOTATION" |
517
 
    "CAMLEXPR" | "CAMLEXPRXML" |
518
 
    "CAMLEXPRL" | "CAMLEXPRXMLL" |
519
 
    "CAMLEXPRXMLS" | "COMMENT" |
520
 
    "TAG" | "GAT" | "ATTR" | "VALUE" | "XMLDECL" |
521
 
    "DECL" | "DATA" | "WHITESPACE" | "EOI" ->
522
 
      ()
523
 
  | _ ->
524
 
      raise
525
 
        (Token.Error
526
 
           ("the constructor \"" ^ p_con ^
527
 
              "\" is not recognized by Plexer")) ]
528
 
;
529
 
 
530
 
value removing_token kwd_table ident_table (p_con, p_prm) =
531
 
  match p_con with
532
 
  [ "" -> Hashtbl.remove kwd_table p_prm
533
 
  | "LIDENT" | "UIDENT" ->
534
 
      if p_prm <> "" then Hashtbl.remove ident_table p_prm
535
 
      else ()
536
 
  | _ -> () ]
537
 
;
538
 
 
539
 
value text =
540
 
  fun
541
 
  [ ("", t) -> "'" ^ t ^ "'"
542
 
  | ("CAMLEXPR", k) -> "camlexpr \"" ^ k ^ "\""
543
 
  | ("CAMLEXPRXML", k) -> "camlvarxml \"" ^ k ^ "\""
544
 
  | ("CAMLEXPRL", k) -> "camlexprl \"" ^ k ^ "\""
545
 
  | ("CAMLEXPRXMLL", k) -> "camlvarxmll \"" ^ k ^ "\""
546
 
  | ("COMMENT", k) -> "comment \"" ^ k ^ "\""
547
 
 
548
 
  | ("TAG","") -> "tag"
549
 
  | ("TAG",t) -> "tag \"" ^ t ^ "\""
550
 
  | ("GAT","") -> "end tag"
551
 
  | ("ATTR","") -> "attribut"
552
 
  | ("ATTR",a) -> "attribut \"" ^ a ^ "\""
553
 
  | ("VALUE","") -> "value"
554
 
  | ("VALUE",v) -> "value \"" ^ v ^ "\""
555
 
  | ("XMLDECL","") -> "XML declaration"
556
 
  | ("DECL","") -> "declaration"
557
 
  | ("DATA","") -> "data"
558
 
  | ("WHITESPACE","") -> "whitespace"
559
 
 
560
 
  | ("EOI", "") -> "end of input"
561
 
  | (con, "") -> con
562
 
  | (con, prm) -> con ^ " \"" ^ prm ^ "\"" ]
563
 
;
564
 
 
565
 
value tok_match =
566
 
  fun tok -> Token.default_match tok
567
 
;
568
 
 
569
 
value gmake () =
570
 
  let kwd_table = Hashtbl.create 301 in
571
 
  let id_table = Hashtbl.create 301 in
572
 
  {tok_func = func kwd_table; tok_using = using_token kwd_table id_table;
573
 
   tok_removing = removing_token kwd_table id_table;
574
 
   tok_match = tok_match; tok_text = text;
575
 
   tok_comm = None}
576
 
;
577
 
 
578
 
value tparse =
579
 
  fun _ -> None
580
 
;
581
 
 
582
 
value make () =
583
 
  let kwd_table = Hashtbl.create 301 in
584
 
  let id_table = Hashtbl.create 301 in
585
 
  {func = func kwd_table; using = using_token kwd_table id_table;
586
 
   removing = removing_token kwd_table id_table; tparse = tparse;
587
 
   text = text}
588
 
;
589
 
 
590
 
(* $Id: xmllexer.ml,v 1.4 2005/06/04 21:02:26 balat Exp $ *)