Skip to content

Commit ce2e3d8

Browse files
committed
Fix and reorganize code to avoid future buffer sharing
1 parent bff0933 commit ce2e3d8

File tree

12 files changed

+114
-38
lines changed

12 files changed

+114
-38
lines changed

src/cli/strings.ml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ open! Core
22
open Lwt.Infix
33
open Lwt.Syntax
44

5-
let version = "2.2.0"
5+
let version = "2.2.1"
66

77
let header = sprintf "/* Generated by okTurtles/strings v%s */\n\n" version
88

@@ -104,8 +104,8 @@ let rec process_dir traversal ~path = function
104104
Lwt.return_unit
105105
in
106106
let on_error ~msg:_ = slow_parse () in
107-
Parsing.Basic.exec_parser ~on_ok ~on_error Parsing.Pug.parser ~path ~language_name:"Pug"
108-
source
107+
Parsing.(Basic.exec_parser ~on_ok ~on_error (Pug.parser (Basic.make_string_parsers ())))
108+
~path ~language_name:"Pug" source
109109
in
110110
collector)
111111
| { st_kind = S_REG; _ }, _, _ when String.is_suffix filename ~suffix:".html" ->
@@ -229,6 +229,7 @@ let write_other ~outdir ~language english other =
229229

230230
let main options = function
231231
| Debug lang ->
232+
let string_parsers = Parsing.Basic.make_string_parsers () in
232233
Lwt_list.iter_s
233234
(fun path ->
234235
let* () = Lwt_io.printlf "\n>>> Debugging [%s]" path in
@@ -254,8 +255,8 @@ let main options = function
254255
Vue.debug_template ~path [ Pug_native { parsed; length = None } ] template_script lang
255256
in
256257
let on_error ~msg:_ = slow_parse () in
257-
Parsing.Basic.exec_parser ~on_ok ~on_error Parsing.Pug.parser ~path ~language_name:"Pug"
258-
source)
258+
Parsing.Basic.exec_parser ~on_ok ~on_error (Parsing.Pug.parser string_parsers) ~path
259+
~language_name:"Pug" source)
259260
| Html, _ when String.is_suffix path ~suffix:".html" ->
260261
let on_ok parsed =
261262
Vue.debug_template ~path [ Html { parsed; length = None } ] template_script lang

src/cli/vue.ml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,7 @@ module Language = struct
3333
| Template (Template.HTML source) ->
3434
let on_ok parsed = Html { parsed; length = Some (String.length source) } in
3535
let on_error ~msg = Failed msg in
36-
Parsing.Basic.exec_parser ~on_ok ~on_error Parsing.Html.parser ~path ~language_name:"HTML" source
37-
|> Lwt.return
36+
Basic.exec_parser ~on_ok ~on_error Html.parser ~path ~language_name:"HTML" source |> Lwt.return
3837
| Template (Template.PUG source) -> (
3938
let slow_parse () =
4039
let collector = Utils.Collector.create ~path in
@@ -46,7 +45,9 @@ module Language = struct
4645
| false ->
4746
let on_ok parsed = Pug_native { parsed; length = Some (String.length source) } |> Lwt.return in
4847
let on_error ~msg:_ = slow_parse () in
49-
Basic.exec_parser ~on_ok ~on_error Pug.parser ~path ~language_name:"Pug" source)
48+
Basic.exec_parser ~on_ok ~on_error
49+
(Pug.parser (Basic.make_string_parsers ()))
50+
~path ~language_name:"Pug" source)
5051
| Script (Script.JS s) -> Js s |> Lwt.return
5152
| Script (Script.TS s) -> Ts s |> Lwt.return
5253
| Style (Style.CSS s) -> Css (String.length s) |> Lwt.return

src/parsing/basic.ml

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ let escapable_string_parser ~escape ~separator =
5454
let is_separator = Char.( = ) separator in
5555
let is_escape = Char.( = ) escape in
5656
let buf = Buffer.create 50 in
57-
(char separator
57+
char separator
5858
*>
5959
let rec loop escaping =
6060
any_char >>= fun x ->
@@ -74,12 +74,25 @@ let escapable_string_parser ~escape ~separator =
7474
Buffer.add_char buf c;
7575
loop escaping
7676
in
77-
loop false)
78-
<?> "Escapable string"
77+
loop false
78+
<|> ( return () >>= fun () ->
79+
Buffer.clear buf;
80+
fail "Invalid escapable string" )
81+
82+
let make_sq_string () = escapable_string_parser ~escape:'\\' ~separator:'\''
83+
84+
let make_dq_string () = escapable_string_parser ~escape:'\\' ~separator:'"'
85+
86+
type string_parsers = {
87+
sq_string: string Angstrom.t;
88+
dq_string: string Angstrom.t;
89+
}
90+
91+
let make_string_parsers () = { sq_string = make_sq_string (); dq_string = make_dq_string () }
7992

8093
let boundary_parsers tag =
81-
let sq_string = escapable_string_parser ~escape:'\\' ~separator:'\'' in
82-
let dq_string = escapable_string_parser ~escape:'\\' ~separator:'"' in
94+
let sq_string = make_sq_string () in
95+
let dq_string = make_dq_string () in
8396
let quoted_string =
8497
peek_char >>= function
8598
| Some '\'' -> sq_string
@@ -96,7 +109,8 @@ let boundary_parsers tag =
96109
let ends = string "</" *> mlws *> string tag <* mlws <* char '>' in
97110
starts, ends
98111

99-
let block_parser (starts, ends) buf ~f =
112+
let block_parser boundaries buf ~f =
113+
let starts, ends = boundaries () in
100114
let line =
101115
take_remaining <* advance 1 >>| fun src_line ->
102116
Buffer.add_string buf src_line;

src/parsing/basic.mli

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
open! Core
2+
3+
val lowercase : char -> bool
4+
5+
val alphanum : char -> bool
6+
7+
val is_identifier : char -> bool
8+
9+
val is_ws : char -> bool
10+
11+
val is_mlws : char -> bool
12+
13+
val ws : unit Angstrom.t
14+
15+
val ws1 : unit Angstrom.t
16+
17+
val mlws : unit Angstrom.t
18+
19+
val mlws1 : unit Angstrom.t
20+
21+
val take_remaining : string Angstrom.t
22+
23+
val skip_remaining : unit Angstrom.t
24+
25+
val maybe : 'a Angstrom.t -> 'a option Angstrom.t
26+
27+
val make_sq_string : unit -> string Angstrom.t
28+
29+
val make_dq_string : unit -> string Angstrom.t
30+
31+
type string_parsers = {
32+
sq_string: string Angstrom.t;
33+
dq_string: string Angstrom.t;
34+
}
35+
36+
val make_string_parsers : unit -> string_parsers
37+
38+
val boundary_parsers : string -> (string, string option) Core.Tuple2.t list Angstrom.t * string Angstrom.t
39+
40+
val block_parser :
41+
(unit -> 'a Angstrom.t * 'b Angstrom.t) -> Buffer.t -> f:(string -> 'a -> 'c) -> 'c Angstrom.t
42+
43+
val default_error_handler : path:string -> language_name:string -> unparsed:string -> 'a
44+
45+
val default_syntax_error_handler : path:string -> language_name:string -> msg:string -> 'a
46+
47+
val exec_parser :
48+
on_ok:('a -> 'b) ->
49+
?on_error:(msg:string -> 'b) ->
50+
'a Angstrom.t ->
51+
path:string ->
52+
language_name:string ->
53+
string ->
54+
'b
55+
56+
val exec_parser_lwt :
57+
on_ok:('a -> 'b Lwt.t) ->
58+
?on_error:(unparsed:string -> 'a option -> 'b Lwt.t) ->
59+
'a Angstrom.t ->
60+
path:string ->
61+
language_name:string ->
62+
Lwt_io.input_channel ->
63+
'b Lwt.t

src/parsing/html.mli

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
open! Core
22

3-
include S.Parser
3+
type t [@@deriving sexp_of]
4+
5+
val collect : Utils.Collector.t -> t -> unit
6+
7+
val parser : t Angstrom.t

src/parsing/pug.ml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ let rollup (lines : lines) =
8484
let lvl = List.hd lines |> Option.value_map ~default:0 ~f:fst in
8585
loop lvl [] None lines |> fst3 |> Array.of_list_rev
8686

87-
let parser =
87+
let parser Basic.{ sq_string; dq_string } =
8888
let open Angstrom in
8989
let open Basic in
9090
let comments = string "//" *> skip_remaining in
@@ -93,10 +93,8 @@ let parser =
9393
let mlblank = sep_by comments mlws in
9494
let mlblank1 = sep_by1 comments mlws1 in
9595
let pug_string =
96-
let single_quoted_string = escapable_string_parser ~escape:'\\' ~separator:'\'' in
97-
let double_quoted_string = escapable_string_parser ~escape:'\\' ~separator:'"' in
9896
let unquoted_string = take_while1 is_identifier in
99-
choice [ single_quoted_string; double_quoted_string; unquoted_string ]
97+
choice [ sq_string; dq_string; unquoted_string ]
10098
in
10199
let symbols ll = ll |> List.map ~f:string |> choice in
102100

src/parsing/pug.mli

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
open! Core
22

3-
include S.Parser
3+
type t [@@deriving sexp_of]
4+
5+
val collect : Utils.Collector.t -> t -> unit
6+
7+
val parser : Basic.string_parsers -> t Angstrom.t

src/parsing/s.ml

Lines changed: 0 additions & 9 deletions
This file was deleted.

src/parsing/script.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ type raw =
55
| TS of string
66
[@@deriving sexp, yojson]
77

8-
let boundaries =
8+
let boundaries () =
99
let open Angstrom in
1010
let starts, ends = Basic.boundary_parsers "script" in
1111
let starts =

src/parsing/strings.ml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,14 @@ type line =
44
| Translation of (string * string)
55
| Comment
66

7-
let parser =
7+
let parser ~dq_string =
88
let open Angstrom in
99
let open Basic in
10-
let double_quoted_string = escapable_string_parser ~escape:'\\' ~separator:'"' in
1110
let line =
1211
lift2
1312
(fun x y -> Translation (x, y))
14-
(mlws *> double_quoted_string <* mlws <* char '=')
15-
(mlws *> double_quoted_string <* mlws <* char ';' <* mlws)
13+
(mlws *> dq_string <* mlws <* char '=')
14+
(mlws *> dq_string <* mlws <* char ';' <* mlws)
1615
in
1716
let comment =
1817
(mlws
@@ -44,9 +43,10 @@ let parse ~path ic =
4443
(String.take_while ~f:(Char.( <> ) '\n') unparsed)
4544
()
4645
in
46+
let dq_string = Basic.make_dq_string () in
4747
let+ lines =
48-
Basic.exec_parser_lwt ~on_ok:Lwt.return ~on_error:error_handler parser ~path ~language_name:".strings"
49-
ic
48+
Basic.exec_parser_lwt ~on_ok:Lwt.return ~on_error:error_handler (parser ~dq_string) ~path
49+
~language_name:".strings" ic
5050
in
5151
List.iter lines ~f:(function
5252
| Translation (x, y) -> String.Table.set table ~key:x ~data:y

0 commit comments

Comments
 (0)