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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
open Error
open Util.Source
let rec parse_string' (s : string) (i : int) (s_expect : string) (j : int) :
bool =
j = String.length s_expect
|| (s.[i] = s_expect.[j] && parse_string' s (i + 1) s_expect (j + 1))
let parse_string (source : Source.t) (s : string) : bool =
Source.left source >= String.length s
&& parse_string' source.s source.i s 0
&&
(Source.advn source (String.length s);
true)
let rec parse_space (source : Source.t) : unit =
if
(not (Source.eos source))
&& (Source.get source = ' '
|| Source.get source = '\t'
|| Source.get source = '\n')
then (
Source.adv source;
parse_space source)
let parse_splice_start (source : Source.t) (name : string) : bool =
parse_string source ("${" ^ name ^ ":")
let rec parse_id' (source : Source.t) : unit =
if not (Source.eos source) then
match Source.get source with
| 'A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '_' | '\'' | '`' | '-' | '*' | '.'
->
Source.adv source;
parse_id' source
| _ -> ()
let parse_id_ (source : Source.t) : string =
let i_prev = source.i in
parse_id' source;
if i_prev = source.i then error no_region "cannot parse identifier";
Source.str source i_prev
let parse_id_with_sub_ (source : Source.t) : string * string =
let id = parse_id_ source in
let id_sub = if parse_string source "/" then parse_id_ source else "" in
(id, id_sub)
let rec parse_ids (source : Source.t) : string list =
parse_space source;
if parse_string source "}" then []
else
let id = parse_id_ source in
id :: parse_ids source
let parse_id_with_sub (source : Source.t) : string * string =
parse_space source;
let id_with_sub = parse_id_with_sub_ source in
parse_space source;
let _ = parse_string source "}" in
id_with_sub