2525
2626 exception Error of string
2727
28- let tok_arg f lexbuf =
28+ let tok_arg lexbuf f =
2929 let start_p = lexbuf.Lexing. lex_start_p in
3030 let x = f lexbuf in
3131 lexbuf.Lexing. lex_start_p < - start_p;
3232 x
3333
34- let with_space space f =
35- tok_arg (fun lexbuf ->
34+ let lex_tag lexbuf space ident tag_end =
35+ tok_arg lexbuf (fun lexbuf ->
3636 let () = space lexbuf in
37- let x = f lexbuf in
37+ let name = ident lexbuf in
3838 let () = space lexbuf in
39- x
39+ let () = tag_end lexbuf in
40+ name
4041 )
4142
42- let split_on_char sep s =
43- let open String in
44- let r = ref [] in
45- let j = ref (length s) in
46- for i = length s - 1 downto 0 do
47- if unsafe_get s i = sep then begin
48- r := sub s (i + 1 ) (! j - i - 1 ) :: ! r;
49- j := i
50- end
51- done ;
52- sub s 0 ! j :: ! r
53-
5443 let split_ident ident =
5544 if ident = " ." then []
56- else split_on_char '.' ident
45+ else String. split_on_char '.' ident
46+
47+ let check_mustaches ~expected ~lexed =
48+ if expected <> lexed then
49+ raise (Error (Printf. sprintf " '%s' expected" expected))
5750}
5851
5952let blank = [' ' '\t' ]*
@@ -66,13 +59,12 @@ rule space = parse
6659 | blank newline { new_line lexbuf; space lexbuf }
6760 | blank { () }
6861
69- and id = parse
70- | id { lexeme lexbuf }
71- | eof { raise (Error " id expected" ) }
72-
7362and ident = parse
7463 | ident { lexeme lexbuf }
75- | eof { raise (Error " ident expected" ) }
64+ | " " { raise (Error " ident expected" ) }
65+
66+ and end_on expected = parse
67+ | (" }}" | " }}}" | " " ) as lexed { check_mustaches ~expected ~lexed }
7668
7769and comment acc = parse
7870 | " }}" { String. concat " " (List. rev acc) }
@@ -82,16 +74,14 @@ and comment acc = parse
8274 | eof { raise (Error " non-terminated comment" ) }
8375
8476and mustache = parse
85- | " {{{" { UNESCAPE_START (with_space space ident lexbuf |> split_ident) }
86- | " {{&" { UNESCAPE_START_AMPERSAND (with_space space ident lexbuf |> split_ident) }
87- | " {{#" { SECTION_START (with_space space ident lexbuf |> split_ident) }
88- | " {{^" { SECTION_INVERT_START (with_space space ident lexbuf |> split_ident) }
89- | " {{/" { SECTION_END (with_space space ident lexbuf |> split_ident) }
90- | " {{>" { PARTIAL_START (0 , with_space space ident lexbuf) }
91- | " {{!" { COMMENT (tok_arg (comment [] ) lexbuf) }
92- | " {{" { ESCAPE_START (with_space space ident lexbuf |> split_ident) }
93- | " }}}" { UNESCAPE_END }
94- | " }}" { END }
77+ | " {{" { ESCAPE (lex_tag lexbuf space ident (end_on " }}" ) |> split_ident) }
78+ | " {{{" { UNESCAPE (lex_tag lexbuf space ident (end_on " }}}" ) |> split_ident) }
79+ | " {{&" { UNESCAPE (lex_tag lexbuf space ident (end_on " }}" ) |> split_ident) }
80+ | " {{#" { OPEN_SECTION (lex_tag lexbuf space ident (end_on " }}" ) |> split_ident) }
81+ | " {{^" { OPEN_INVERTED_SECTION (lex_tag lexbuf space ident (end_on " }}" ) |> split_ident) }
82+ | " {{/" { CLOSE_SECTION (lex_tag lexbuf space ident (end_on " }}" ) |> split_ident) }
83+ | " {{>" { PARTIAL (0 , lex_tag lexbuf space ident (end_on " }}" )) }
84+ | " {{!" { COMMENT (tok_arg lexbuf (comment [] )) }
9585 | raw newline { new_line lexbuf; RAW (lexeme lexbuf) }
9686 | raw { RAW (lexeme lexbuf) }
9787 | ['{' '}' ] { RAW (lexeme lexbuf) }
@@ -136,33 +126,24 @@ and mustache = parse
136126 in
137127 loop 0 l
138128 in
139- let segment_before tail l =
140- let rec loop acc = function
141- | [] -> List. rev acc
142- | l when l == tail -> List. rev acc
143- | y :: ys -> loop (y :: acc) ys
144- in
145- loop [] l
146- in
147129 let is_standalone toks =
148130 let (skipped, toks) = skip_blanks toks in
149131 match toks with
150- | (SECTION_START _, _, _) :: ( END , _, _) :: toks'
151- | ( SECTION_INVERT_START _, _, _) :: ( END , _, _) :: toks'
152- | ( SECTION_END _, _, _) :: ( END , _, _) :: toks'
153- | ( PARTIAL_START _, _, _) :: ( END , _, _) :: toks'
154- | ( COMMENT _ , _ , _ ) :: toks' ->
132+ | (( OPEN_SECTION _
133+ | OPEN_INVERTED_SECTION _
134+ | CLOSE_SECTION _
135+ | PARTIAL _
136+ | COMMENT _ ) , _ , _ ) as tok :: toks' ->
155137 let (_, toks_rest) = skip_blanks toks' in
156138 begin match toks_rest with
157139 | [] | [(EOF , _, _)] ->
158- let toks_standalone =
159- segment_before toks' toks |>
160- function
161- | [(PARTIAL_START (_, p), loc1, loc2); tok_end] ->
162- [(PARTIAL_START (skipped, p), loc1, loc2); tok_end]
163- | toks -> toks
140+ let tok =
141+ match tok with
142+ | (PARTIAL (_ , p ), loc1 , loc2 ) ->
143+ (PARTIAL (skipped, p), loc1, loc2)
144+ | _ -> tok
164145 in
165- Some (toks_standalone , toks_rest)
146+ Some (tok , toks_rest)
166147 | _ -> None
167148 end
168149 | _ -> None
@@ -176,9 +157,9 @@ and mustache = parse
176157 | [] ->
177158 let toks = slurp_line () in
178159 match is_standalone toks with
179- | Some (toks_standalone , toks_rest ) ->
180- buffer := List. tl toks_standalone @ toks_rest;
181- List. hd toks_standalone
160+ | Some (tok_standalone , toks_rest ) ->
161+ buffer := toks_rest;
162+ tok_standalone
182163 | None ->
183164 buffer := List. tl toks; List. hd toks
184165}
0 commit comments