Skip to content

Commit cf33f52

Browse files
committed
Run the pre-precessor once before building the first parser checkpoint
This completely removes the need to handle cases of dummy left-most positions in the source overlay module.
1 parent 0c95ca5 commit cf33f52

File tree

2 files changed

+19
-27
lines changed

2 files changed

+19
-27
lines changed

src/lsp/cobol_parser/parser_engine.ml

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ module Make (Config: Cobol_config.T) = struct
220220

221221
(* --- *)
222222

223-
let do_parse: type m. m state -> _ -> _ * m state =
223+
let do_parse: type m. m state -> _ -> _ -> _ * m state =
224224

225225
let rec next_tokens ({ preproc = { tokzr; _ }; _ } as ps) tokens =
226226
match Tokzr.next_token tokzr tokens with
@@ -424,16 +424,22 @@ module Make (Config: Cobol_config.T) = struct
424424
Some v, ps
425425

426426
in
427-
fun ps c -> normal ps [] c
427+
fun ps tokens c -> normal ps tokens c
428428

429429
let parse ?verbose ?show ~recovery
430-
(type m) ~(memory: m memory) pp checkpoint
430+
(type m) ~(memory: m memory) pp make_checkpoint
431431
: ('a option, m) output * _ =
432432
let ps = init_parser ?verbose ?show ~recovery
433433
~tokenizer_memory:memory pp in
434434
let res, ps =
435435
(* TODO: catch in a deeper context to grab parsed tokens *)
436-
try do_parse ps checkpoint with e -> None, add_diag (DIAGS.of_exn e) ps
436+
let ps, tokens = produce_tokens ps in
437+
let first_pos = match tokens with
438+
| [] -> Cobol_preproc.position ps.preproc.pp
439+
| t :: _ -> Cobol_common.Srcloc.start_pos ~@t
440+
in
441+
try do_parse ps tokens (make_checkpoint first_pos)
442+
with e -> None, add_diag (DIAGS.of_exn e) ps
437443
in
438444
match memory with
439445
| Amnesic ->
@@ -480,9 +486,8 @@ let parse
480486
init_source_format = source_format}
481487
in
482488
let module P = Make (val config) in
483-
P.parse ?verbose ?show ~memory ~recovery pp @@
484-
Grammar.Incremental.compilation_group @@
485-
Cobol_preproc.position pp
489+
P.parse ?verbose ?show ~memory ~recovery pp
490+
Grammar.Incremental.compilation_group
486491
end
487492
in
488493
{

src/lsp/cobol_preproc/src_overlay.ml

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ type manager =
6767
over_right_gap: limit Links.t; (** associates the right limit of a token to
6868
the left limit of the next *)
6969
cache: (srcloc * limit) Links.t;
70-
leftmost_in_file: (string, limit) Hashtbl.t;
7170
id: string; (** manager identifier (for logging/debugging) *)
7271
}
7372

@@ -80,7 +79,6 @@ let new_manager: string -> manager =
8079
right_of = Links.create 42;
8180
over_right_gap = Links.create 42;
8281
cache = Links.create 42;
83-
leftmost_in_file = Hashtbl.create 3;
8482
id = Pretty.to_string "%s-%u" manager_name !id;
8583
}
8684

@@ -96,21 +94,13 @@ let limits: manager -> srcloc -> limit * limit = fun ctx loc ->
9694
| _ -> Limit.make_virtual (), Limit.make_virtual ()
9795
in
9896
Links.replace ctx.right_of s (loc, e); (* replace to deal with duplicates *)
99-
if not (Hashtbl.mem ctx.leftmost_in_file s.pos_fname)
100-
then Hashtbl.add ctx.leftmost_in_file s.pos_fname s;
10197
s, e
10298

10399
(** Links token limits *)
104100
let link_limits ctx left right =
105101
(* Replace to deal with overriding of limits during recovery. *)
106102
Links.replace ctx.over_right_gap left right
107103

108-
(** [leftmost_limit_in ~filename ctx] finds the leftmost limit from a location
109-
in [filename] that is registered in [ctx] (internal). Use with moderation
110-
as this is quite inefficient. *)
111-
let leftmost_limit_in ~filename ctx =
112-
Hashtbl.find_opt ctx.leftmost_in_file filename
113-
114104
(** Returns a source location that spans between two given limits; returns a
115105
valid pointwise location if the two given limits are physically equal. *)
116106
let join_limits: manager -> limit * limit -> srcloc = fun ctx (s, e) ->
@@ -165,17 +155,14 @@ let join_limits: manager -> limit * limit -> srcloc = fun ctx (s, e) ->
165155
in
166156
(* first attempt assumes proper token limits: `s` is a left and `e` is a
167157
right of tokens *)
168-
try try_limits (s, e) with Not_found ->
158+
try
159+
try_limits (s, e)
160+
with Not_found ->
169161
(* otherwise try assuming `s` is an end of token *)
170-
try try_limits (Links.find ctx.over_right_gap s, e) with Not_found ->
171-
try if s.pos_cnum = 0 (* potential special case with left-position forged by
172-
the parser: retry with leftmost limit if it differs
173-
from s *)
174-
then match leftmost_limit_in ~filename:s.pos_fname ctx with
175-
| Some l when l != s -> try_limits (l, e) (* physical equality is enough *)
176-
| Some _ | None -> raise Not_found
177-
else raise Not_found
178-
with Not_found -> join_failure (s, e)
162+
try
163+
try_limits (Links.find ctx.over_right_gap s, e)
164+
with Not_found ->
165+
join_failure (s, e)
179166

180167
module New_manager (Id: sig val name: string end) : MANAGER = struct
181168
let ctx = new_manager Id.name

0 commit comments

Comments
 (0)