Source file identifier.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
let is_valid s =
let n = String.length s in
let ascii_start c =
(c >= Char.code 'a' && c <= Char.code 'z')
|| (c >= Char.code 'A' && c <= Char.code 'Z')
in
let ascii_cont c =
ascii_start c
|| (c >= Char.code '0' && c <= Char.code '9')
|| c = Char.code '_'
|| c = Char.code '\''
in
let rec cont i =
if i >= n then true
else
let d = String.get_utf_8_uchar s i in
if not (Uchar.utf_decode_is_valid d) then false
else
let c = Uchar.to_int (Uchar.utf_decode_uchar d) in
let ok = if c < 0x80 then ascii_cont c else Xid.is_xid_continue c in
ok && cont (i + Uchar.utf_decode_length d)
in
n > 0
&&
let d = String.get_utf_8_uchar s 0 in
Uchar.utf_decode_is_valid d
&&
let c = Uchar.to_int (Uchar.utf_decode_uchar d) in
let len = Uchar.utf_decode_length d in
if c < 0x80 then
if c = Char.code '_' then len < n && cont len else ascii_start c && cont len
else Xid.is_xid_start c && cont len