diff --git a/Changes b/Changes index 7f5bd5897421..d9bde71bd180 100644 --- a/Changes +++ b/Changes @@ -138,6 +138,12 @@ Working version - GPR#1585: optimize output of "ocamllex -ml" (Alain Frisch, review by Frédéric Bour and Gabriel Scherer) +- GPR#1590: ocamllex-generated lexers can be instructed not to update their + lex_curr_p/lex_start_p by setting lex_curr_p to Lexing.dummy_pos, + resuting in a significant performance gain when those fields are not + required + (Alain Frisch, review by ...) + ### Manual and documentation: - PR#7647, GPR#1384: emphasize ocaml.org website and forum in README diff --git a/stdlib/lexing.ml b/stdlib/lexing.ml index 2c2633d43e94..87dadd04e42b 100644 --- a/stdlib/lexing.ml +++ b/stdlib/lexing.ml @@ -63,7 +63,7 @@ external c_new_engine : lex_tables -> int -> lexbuf -> int let engine tbl state buf = let result = c_engine tbl state buf in - if result >= 0 then begin + if result >= 0 && buf.lex_curr_p != dummy_pos then begin buf.lex_start_p <- buf.lex_curr_p; buf.lex_curr_p <- {buf.lex_curr_p with pos_cnum = buf.lex_abs_pos + buf.lex_curr_pos}; @@ -73,7 +73,7 @@ let engine tbl state buf = let new_engine tbl state buf = let result = c_new_engine tbl state buf in - if result >= 0 then begin + if result >= 0 && buf.lex_curr_p != dummy_pos then begin buf.lex_start_p <- buf.lex_curr_p; buf.lex_curr_p <- {buf.lex_curr_p with pos_cnum = buf.lex_abs_pos + buf.lex_curr_pos}; @@ -215,10 +215,12 @@ let lexeme_end_p lexbuf = lexbuf.lex_curr_p let new_line lexbuf = let lcp = lexbuf.lex_curr_p in - lexbuf.lex_curr_p <- { lcp with - pos_lnum = lcp.pos_lnum + 1; - pos_bol = lcp.pos_cnum; - } + if lcp != dummy_pos then + lexbuf.lex_curr_p <- + { lcp with + pos_lnum = lcp.pos_lnum + 1; + pos_bol = lcp.pos_cnum; + } @@ -227,5 +229,6 @@ let new_line lexbuf = let flush_input lb = lb.lex_curr_pos <- 0; lb.lex_abs_pos <- 0; - lb.lex_curr_p <- {lb.lex_curr_p with pos_cnum = 0}; + let lcp = lb.lex_curr_p in + if lcp != dummy_pos then lb.lex_curr_p <- {lcp with pos_cnum = 0}; lb.lex_buffer_len <- 0; diff --git a/stdlib/lexing.mli b/stdlib/lexing.mli index 397d20cbb151..0d1ee7d7a08c 100644 --- a/stdlib/lexing.mli +++ b/stdlib/lexing.mli @@ -73,7 +73,12 @@ type lexbuf = accurate, they must be initialised before the first use of the lexbuf, and updated by the relevant lexer actions (i.e. at each end of line -- see also [new_line]). - *) + + Updating [lex_curr_p] and [lex_start_p] is disabled if + [lex_curr_p] is physically equal to [dummy_pos]. Setting + [lex_curr_p] to [dummy_pos] before calling the engine can thus be + used to avoid useless allocations and memory writes in contexts where + [lex_start_p] and [lex_curr_p] are not needed. *) val from_channel : in_channel -> lexbuf (** Create a lexer buffer on the given input channel.