ocaml/stdlib/lexing.ml

102 lines
3.4 KiB
OCaml

(***********************************************************************)
(* *)
(* Caml Special Light *)
(* *)
(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
(* *)
(* Copyright 1995 Institut National de Recherche en Informatique et *)
(* Automatique. Distributed only by permission. *)
(* *)
(***********************************************************************)
(* $Id$ *)
(* The run-time library for lexers generated by camllex *)
type lexbuf =
{ refill_buff : lexbuf -> unit;
mutable lex_buffer : string;
mutable lex_buffer_len : int;
mutable lex_abs_pos : int;
mutable lex_start_pos : int;
mutable lex_curr_pos : int;
mutable lex_last_pos : int }
type lex_tables =
{ lex_base: string;
lex_backtrk: string;
lex_default: string;
lex_trans: string;
lex_check: string }
external engine: lex_tables -> int -> lexbuf -> int = "lex_engine"
let lex_aux_buffer = String.create 1024
let lex_refill read_fun lexbuf =
let read =
read_fun lex_aux_buffer 1024 in
let n =
if read > 0
then read
else (String.unsafe_set lex_aux_buffer 0 '\000'; 1) in
if lexbuf.lex_start_pos < n then begin
let oldlen = lexbuf.lex_buffer_len in
let newlen = oldlen * 2 in
let newbuf = String.create newlen in
String.unsafe_blit lexbuf.lex_buffer 0 newbuf oldlen oldlen;
lexbuf.lex_buffer <- newbuf;
lexbuf.lex_buffer_len <- newlen;
lexbuf.lex_abs_pos <- lexbuf.lex_abs_pos - oldlen;
lexbuf.lex_curr_pos <- lexbuf.lex_curr_pos + oldlen;
lexbuf.lex_start_pos <- lexbuf.lex_start_pos + oldlen;
lexbuf.lex_last_pos <- lexbuf.lex_last_pos + oldlen
end;
String.unsafe_blit lexbuf.lex_buffer n
lexbuf.lex_buffer 0
(lexbuf.lex_buffer_len - n);
String.unsafe_blit lex_aux_buffer 0
lexbuf.lex_buffer (lexbuf.lex_buffer_len - n)
n;
lexbuf.lex_abs_pos <- lexbuf.lex_abs_pos + n;
lexbuf.lex_curr_pos <- lexbuf.lex_curr_pos - n;
lexbuf.lex_start_pos <- lexbuf.lex_start_pos - n;
lexbuf.lex_last_pos <- lexbuf.lex_last_pos - n
let from_function f =
{ refill_buff = lex_refill f;
lex_buffer = String.create 2048;
lex_buffer_len = 2048;
lex_abs_pos = - 2048;
lex_start_pos = 2048;
lex_curr_pos = 2048;
lex_last_pos = 2048 }
let from_channel ic =
from_function (fun buf n -> input ic buf 0 n)
let from_string s =
{ refill_buff =
(fun lexbuf -> lexbuf.lex_curr_pos <- lexbuf.lex_curr_pos - 1);
lex_buffer = s ^ "\000";
lex_buffer_len = String.length s + 1;
lex_abs_pos = 0;
lex_start_pos = 0;
lex_curr_pos = 0;
lex_last_pos = 0 }
let lexeme lexbuf =
let len = lexbuf.lex_curr_pos - lexbuf.lex_start_pos in
let s = String.create len in
String.unsafe_blit lexbuf.lex_buffer lexbuf.lex_start_pos s 0 len;
s
let lexeme_char lexbuf i =
String.get lexbuf.lex_buffer (lexbuf.lex_start_pos + i)
let lexeme_start lexbuf =
lexbuf.lex_abs_pos + lexbuf.lex_start_pos
and lexeme_end lexbuf =
lexbuf.lex_abs_pos + lexbuf.lex_curr_pos