Skip to content

Commit c879919

Browse files
committed
Real stdin parsing instead of reading it into a string to parse
1 parent 9e7c4be commit c879919

File tree

9 files changed

+82
-142
lines changed

9 files changed

+82
-142
lines changed

doc/parsing.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ module P =
4949
(Dolmen.Std.Loc)(Dolmen.Std.Id)(Dolmen.Std.Term)(Dolmen.Std.Statement)
5050
(Dolmen.Std.Extensions.Smtlib2)
5151
52-
let _ = P.parse_file "example.smt2"
52+
let _ = P.parse_all (`File "example.smt2")
5353
```
5454

5555
For more examples, see the [tutorial](https://github.com/Gbury/dolmen/tree/master/doc/tuto.md).

doc/tuto.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,12 @@ let test file =
3131
(* Parse the file, and we get a tuple:
3232
- format: the guessed format (according to the file extension)
3333
- loc: some meta-data used for source file locations
34-
- statements: the list of top-level directives found in the file *)
35-
let format, loc, parsed_statements = Logic.parse_file file in
34+
- statements: a lazy list of top-level directives found in the file *)
35+
let format, loc, parsed_statements_lazy = Logic.parse_all (`File file) in
36+
37+
(* Any lexing/parsing error will be raised when forcing the lazy list
38+
of statements *)
39+
let parsed_statements = Lazy.force parsed_statements_lazy in
3640
3741
(* You can match on the detected format of the input *)
3842
let () =

src/classes/logic.ml

Lines changed: 14 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,6 @@ module type S = sig
2121
val find :
2222
?language:language ->
2323
?dir:string -> string -> string option
24-
val parse_file :
25-
?language:language ->
26-
string -> language * file * statement list
2724
val parse_all :
2825
?language:language ->
2926
[< `File of string | `Stdin of language
@@ -146,45 +143,31 @@ module Make
146143
let _, _, (module P : S) = of_language l in
147144
P.find ~dir file
148145

149-
let parse_file ?language file =
150-
let l, _, (module P : S) =
151-
match language with
152-
| None -> of_filename file
153-
| Some l -> of_language l
154-
in
155-
let locfile, res = P.parse_file file in
156-
l, locfile, res
157-
158-
let parse_raw_lazy ?language ~filename contents =
159-
let l, _, (module P : S) =
160-
match language with
161-
| None -> of_filename filename
162-
| Some l -> of_language l
163-
in
164-
let locfile, res = P.parse_raw_lazy ~filename contents in
165-
l, locfile, res
166-
167146
let parse_all ?language = function
168147
| `File file ->
169148
let l, _, (module P : S) =
170149
match language with
171150
| None -> of_filename file
172151
| Some l -> of_language l
173152
in
174-
let locfile, res = P.parse_file_lazy file in
153+
let locfile, res = P.parse_all (`File file) in
175154
l, locfile, res
176155
| `Raw (filename, l, s) ->
177-
let language =
178-
match language with Some _ -> language | None -> Some l
156+
let l, _, (module P : S) =
157+
match language with
158+
| None -> of_language l
159+
| Some lang -> of_language lang
179160
in
180-
parse_raw_lazy ?language ~filename s
161+
let locfile, res = P.parse_all (`Contents (filename, s)) in
162+
l, locfile, res
181163
| `Stdin l ->
182-
let filename = "<stdin>" in
183-
let s = Dolmen_std.Misc.read_all ~size:1024 stdin in
184-
let language =
185-
match language with Some _ -> language | None -> Some l
164+
let l, _, (module P : S) =
165+
match language with
166+
| None -> of_language l
167+
| Some lang -> of_language lang
186168
in
187-
parse_raw_lazy ?language ~filename s
169+
let locfile, res = P.parse_all `Stdin in
170+
l, locfile, res
188171

189172
let parse_input ?language = function
190173
| `File file ->
@@ -205,4 +188,5 @@ module Make
205188
(match language with | Some l' -> l' | None -> l) in
206189
let locfile, gen, cl = P.parse_input (`Contents (filename, s)) in
207190
l, locfile, gen, cl
191+
208192
end

src/classes/logic.mli

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ module type S = sig
1414
exception Extension_not_found of string
1515
(** Raised when trying to find a language given a file extension. *)
1616

17+
1718
(** {2 Supported languages} *)
1819

1920
type language =
@@ -39,28 +40,14 @@ module type S = sig
3940
val string_of_language : language -> string
4041
(** String representation of the variant *)
4142

43+
4244
(** {2 High-level parsing} *)
4345

4446
val find :
4547
?language:language ->
4648
?dir:string -> string -> string option
4749
(** Tries and find the given file, using the language specification. *)
4850

49-
val parse_file :
50-
?language:language ->
51-
string -> language * file * statement list
52-
(** Given a filename, parse the file, and return the detected language
53-
together with the list of statements parsed.
54-
55-
WARNING: please note that this function makes it difficult to report
56-
error locations, since exceptions might be raised during parsing
57-
and any caller of this function will not have access to the [file]
58-
return value of the function, which is necessary to correctly
59-
interpret the locations in error exceptions. Instead, please use
60-
either {parse_all} or {parse_input}.
61-
62-
@param language specify a language; overrides auto-detection. *)
63-
6451
val parse_all :
6552
?language:language ->
6653
[< `File of string
@@ -86,7 +73,7 @@ module type S = sig
8673
| `Stdin of language
8774
| `Raw of string * language * string ] ->
8875
language * file * (unit -> statement option) * (unit -> unit)
89-
(** Incremental parsing of either a file (see {!parse_file}), stdin
76+
(** Incremental parsing of either a file, stdin
9077
(with given language), or some arbitrary contents, of the form
9178
[`Raw (filename, language, contents)].
9279
Returns a quadruplet [(lan, file, gen, cl)], containing:

src/classes/response.ml

Lines changed: 29 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,11 @@ module type S = sig
1616
val find :
1717
?language:language ->
1818
?dir:string -> string -> string option
19-
val parse_file :
19+
val parse_all :
2020
?language:language ->
21-
string -> language * file * statement list
22-
val parse_file_lazy :
23-
?language:language ->
24-
string -> language * file * statement list Lazy.t
25-
val parse_raw_lazy :
26-
?language:language ->
27-
filename:string -> string -> language * file * statement list Lazy.t
21+
[< `File of string | `Stdin of language
22+
| `Raw of string * language * string ] ->
23+
language * file * statement list Lazy.t
2824
val parse_input :
2925
?language:language ->
3026
[< `File of string | `Stdin of language
@@ -104,32 +100,31 @@ module Make
104100
let _, _, (module P : S) = of_language l in
105101
P.find ~dir file
106102

107-
let parse_file ?language file =
108-
let l, _, (module P : S) =
109-
match language with
110-
| None -> of_filename file
111-
| Some l -> of_language l
112-
in
113-
let locfile, res = P.parse_file file in
114-
l, locfile, res
115-
116-
let parse_file_lazy ?language file =
117-
let l, _, (module P : S) =
118-
match language with
119-
| None -> of_filename file
120-
| Some l -> of_language l
121-
in
122-
let locfile, res = P.parse_file_lazy file in
123-
l, locfile, res
124-
125-
let parse_raw_lazy ?language ~filename contents =
126-
let l, _, (module P : S) =
127-
match language with
128-
| None -> of_filename filename
129-
| Some l -> of_language l
130-
in
131-
let locfile, res = P.parse_raw_lazy ~filename contents in
132-
l, locfile, res
103+
let parse_all ?language = function
104+
| `File file ->
105+
let l, _, (module P : S) =
106+
match language with
107+
| None -> of_filename file
108+
| Some l -> of_language l
109+
in
110+
let locfile, res = P.parse_all (`File file) in
111+
l, locfile, res
112+
| `Raw (filename, l, s) ->
113+
let l, _, (module P : S) =
114+
match language with
115+
| None -> of_language l
116+
| Some lang -> of_language lang
117+
in
118+
let locfile, res = P.parse_all (`Contents (filename, s)) in
119+
l, locfile, res
120+
| `Stdin l ->
121+
let l, _, (module P : S) =
122+
match language with
123+
| None -> of_language l
124+
| Some lang -> of_language lang
125+
in
126+
let locfile, res = P.parse_all `Stdin in
127+
l, locfile, res
133128

134129
let parse_input ?language = function
135130
| `File file ->

src/classes/response.mli

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -36,26 +36,23 @@ module type S = sig
3636
?dir:string -> string -> string option
3737
(** Tries and find the given file, using the language specification. *)
3838

39-
val parse_file :
39+
val parse_all :
4040
?language:language ->
41-
string -> language * file * statement list
42-
(** Given a filename, parse the file, and return the detected language
43-
together with the list of statements parsed.
44-
@param language specify a language; overrides auto-detection. *)
45-
46-
val parse_file_lazy :
47-
?language:language ->
48-
string -> language * file * statement list Lazy.t
49-
(** Given a filename, parse the file, and return the detected language
50-
together with the list of statements parsed.
51-
@param language specify a language; overrides auto-detection. *)
41+
[< `File of string | `Stdin of language
42+
| `Raw of string * language * string ] ->
43+
language * file * statement list Lazy.t
44+
(** Full (but lazy) parsing of either a file (see {!parse_file}), stdin
45+
(with given language), or some arbitrary contents, of the form
46+
[`Raw (filename, language, contents)].
47+
Returns a triplet [(lan, file, stmts)], containing:
48+
- the language [lan] detected
49+
- a [file] value that stores the metadata about file locations
50+
- a lazy list of statements [stmts]; forcing this list will run the actual
51+
parsing of the whole input given as argument, and may raise errors, if
52+
any arises during the parsing (such as lexical errors, etc..)
5253
53-
val parse_raw_lazy :
54-
?language:language ->
55-
filename:string -> string -> language * file * statement list Lazy.t
56-
(** Given a filename and a string, parse the string, and return the detected
57-
language together with the list of statements parsed.
58-
@param language specify a language; overrides auto-detection. *)
54+
@param language specify a language for parsing, overrides auto-detection
55+
and stdin specification. *)
5956

6057
val parse_input :
6158
?language:language ->

src/interface/language.ml

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,13 @@ module type S = sig
2828
Separates directory and file because most include directives in languages
2929
are relative to the directory of the original file being processed. *)
3030

31-
val parse_file : string -> file * statement list
32-
(** Parse the whole given file into a list. *)
33-
34-
val parse_file_lazy : string -> file * statement list Lazy.t
35-
(** Parse the whole given file into a list. *)
36-
37-
val parse_raw_lazy : filename:string -> string -> file * statement list Lazy.t
38-
(** Parse the whole given string into a list. *)
31+
val parse_all :
32+
[ `Stdin | `File of string | `Contents of string * string ] ->
33+
file * statement list Lazy.t
34+
(** Whole input parsing. Given an input to read (either a file, stdin,
35+
or some contents of the form [(filename, s)] where [s] is the contents to parse),
36+
returns a lazy list of the parsed statements. Forcing the lazy list may raise
37+
an exception if some error occurs during parsing (e.g. lexing or parsing error). *)
3938

4039
val parse_input :
4140
[ `Stdin | `File of string | `Contents of string * string ] ->

src/loop/parser.ml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -342,8 +342,9 @@ module Make(State : State.S) = struct
342342
let file = { file with loc = file_loc; lang = Some lang; } in
343343
st, file, gen_finally gen cl
344344
| Some `Full ->
345-
let lang, file_loc, l = Response.parse_raw_lazy ?language:file.lang
346-
~filename contents
345+
let lang, file_loc, l =
346+
Response.parse_all ?language:file.lang
347+
(`Raw (filename, Response.Smtlib2 `Latest, contents))
347348
in
348349
let file = { file with loc = file_loc; lang = Some lang; } in
349350
st, file, gen_of_llist l
@@ -364,7 +365,7 @@ module Make(State : State.S) = struct
364365
st, file, gen_finally gen cl
365366
| Some `Full ->
366367
let lang, file_loc, l =
367-
Response.parse_file_lazy ?language:file.lang filename
368+
Response.parse_all ?language:file.lang (`File filename)
368369
in
369370
let file = { file with loc = file_loc; lang = Some lang; } in
370371
st, file, gen_of_llist l

src/standard/transformer.ml

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -130,36 +130,9 @@ module Make
130130
(* Instantiations of the parsing loop
131131
---------------------------------- *)
132132

133-
let parse_file file =
134-
let lexbuf, cleanup = Misc.mk_lexbuf (`File file) in
135-
let locfile = Loc.mk_file file in
136-
let newline = Loc.newline locfile in
137-
let sync = Loc.update_size locfile in
138-
let k_exn () = cleanup () in
139-
let res = parse_aux ~k_exn newline sync lexbuf Parser.file () in
140-
let () = cleanup () in
141-
locfile, res
142-
143-
let parse_file_lazy file =
144-
let lexbuf, cleanup = Misc.mk_lexbuf (`File file) in
145-
let locfile = Loc.mk_file file in
146-
let newline = Loc.newline locfile in
147-
let sync = Loc.update_size locfile in
148-
let k_exn () = cleanup () in
149-
let res =
150-
lazy (
151-
let res =
152-
parse_aux ~k_exn newline sync lexbuf Parser.file ()
153-
in
154-
let () = cleanup () in
155-
res
156-
)
157-
in
158-
locfile, res
159-
160-
let parse_raw_lazy ~filename contents =
161-
let lexbuf, cleanup = Misc.mk_lexbuf (`Contents (filename, contents)) in
162-
let locfile = Loc.mk_file filename in
133+
let parse_all i =
134+
let lexbuf, cleanup = Misc.mk_lexbuf i in
135+
let locfile = Loc.mk_file (Misc.filename_of_input i) in
163136
let newline = Loc.newline locfile in
164137
let sync = Loc.update_size locfile in
165138
let k_exn () = cleanup () in

0 commit comments

Comments
 (0)