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
4243 let split_ident ident =
4344 if ident = " ." then []
4445 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))
4550}
4651
4752let blank = [' ' '\t' ]*
@@ -56,7 +61,10 @@ rule space = parse
5661
5762and ident = parse
5863 | ident { lexeme lexbuf }
59- | eof { raise (Error " ident expected" ) }
64+ | " " { raise (Error " ident expected" ) }
65+
66+ and end_on expected = parse
67+ | (" }}" | " }}}" | " " ) as lexed { check_mustaches ~expected ~lexed }
6068
6169and comment acc = parse
6270 | " }}" { String. concat " " (List. rev acc) }
@@ -66,16 +74,14 @@ and comment acc = parse
6674 | eof { raise (Error " non-terminated comment" ) }
6775
6876and mustache = parse
69- | " {{{" { UNESCAPE_START (with_space space ident lexbuf |> split_ident) }
70- | " {{&" { UNESCAPE_START_AMPERSAND (with_space space ident lexbuf |> split_ident) }
71- | " {{#" { SECTION_START (with_space space ident lexbuf |> split_ident) }
72- | " {{^" { SECTION_INVERT_START (with_space space ident lexbuf |> split_ident) }
73- | " {{/" { SECTION_END (with_space space ident lexbuf |> split_ident) }
74- | " {{>" { PARTIAL_START (0 , with_space space ident lexbuf) }
75- | " {{!" { COMMENT (tok_arg (comment [] ) lexbuf) }
76- | " {{" { ESCAPE_START (with_space space ident lexbuf |> split_ident) }
77- | " }}}" { UNESCAPE_END }
78- | " }}" { 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 [] )) }
7985 | raw newline { new_line lexbuf; RAW (lexeme lexbuf) }
8086 | raw { RAW (lexeme lexbuf) }
8187 | ['{' '}' ] { RAW (lexeme lexbuf) }
@@ -120,33 +126,24 @@ and mustache = parse
120126 in
121127 loop 0 l
122128 in
123- let segment_before tail l =
124- let rec loop acc = function
125- | [] -> List. rev acc
126- | l when l == tail -> List. rev acc
127- | y :: ys -> loop (y :: acc) ys
128- in
129- loop [] l
130- in
131129 let is_standalone toks =
132130 let (skipped, toks) = skip_blanks toks in
133131 match toks with
134- | (SECTION_START _, _, _) :: ( END , _, _) :: toks'
135- | ( SECTION_INVERT_START _, _, _) :: ( END , _, _) :: toks'
136- | ( SECTION_END _, _, _) :: ( END , _, _) :: toks'
137- | ( PARTIAL_START _, _, _) :: ( END , _, _) :: toks'
138- | ( COMMENT _ , _ , _ ) :: toks' ->
132+ | (( OPEN_SECTION _
133+ | OPEN_INVERTED_SECTION _
134+ | CLOSE_SECTION _
135+ | PARTIAL _
136+ | COMMENT _ ) , _ , _ ) as tok :: toks' ->
139137 let (_, toks_rest) = skip_blanks toks' in
140138 begin match toks_rest with
141139 | [] | [(EOF , _, _)] ->
142- let toks_standalone =
143- segment_before toks' toks |>
144- function
145- | [(PARTIAL_START (_, p), loc1, loc2); tok_end] ->
146- [(PARTIAL_START (skipped, p), loc1, loc2); tok_end]
147- | toks -> toks
140+ let tok =
141+ match tok with
142+ | (PARTIAL (_ , p ), loc1 , loc2 ) ->
143+ (PARTIAL (skipped, p), loc1, loc2)
144+ | _ -> tok
148145 in
149- Some (toks_standalone , toks_rest)
146+ Some (tok , toks_rest)
150147 | _ -> None
151148 end
152149 | _ -> None
@@ -160,9 +157,9 @@ and mustache = parse
160157 | [] ->
161158 let toks = slurp_line () in
162159 match is_standalone toks with
163- | Some (toks_standalone , toks_rest ) ->
164- buffer := List. tl toks_standalone @ toks_rest;
165- List. hd toks_standalone
160+ | Some (tok_standalone , toks_rest ) ->
161+ buffer := toks_rest;
162+ tok_standalone
166163 | None ->
167164 buffer := List. tl toks; List. hd toks
168165}
0 commit comments