mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-07 19:55:31 -05:00
support raw chars in Sexp
This commit is contained in:
parent
d5eb60d0ae
commit
dd1f331834
1 changed files with 30 additions and 12 deletions
40
misc/sexp.ml
40
misc/sexp.ml
|
|
@ -47,6 +47,7 @@ let _must_escape s =
|
||||||
let c = String.unsafe_get s i in
|
let c = String.unsafe_get s i in
|
||||||
match c with
|
match c with
|
||||||
| ' ' | ')' | '(' | '"' | '\n' | '\t' -> raise Exit
|
| ' ' | ')' | '(' | '"' | '\n' | '\t' -> raise Exit
|
||||||
|
| _ when Char.code c > 127 -> raise Exit (* non-ascii *)
|
||||||
| _ -> ()
|
| _ -> ()
|
||||||
done;
|
done;
|
||||||
false
|
false
|
||||||
|
|
@ -99,6 +100,8 @@ module Streaming = struct
|
||||||
| St_atom
|
| St_atom
|
||||||
| St_quoted
|
| St_quoted
|
||||||
| St_escaped
|
| St_escaped
|
||||||
|
| St_raw_char1 of int
|
||||||
|
| St_raw_char2 of int
|
||||||
| St_yield of token
|
| St_yield of token
|
||||||
| St_error of string
|
| St_error of string
|
||||||
| St_end
|
| St_end
|
||||||
|
|
@ -172,6 +175,9 @@ module Streaming = struct
|
||||||
d.st <- St_end;
|
d.st <- St_end;
|
||||||
raise EOI
|
raise EOI
|
||||||
|
|
||||||
|
let _is_digit c = Char.code '0' <= Char.code c && Char.code c <= Char.code '9'
|
||||||
|
let _digit2i c = Char.code c - Char.code '0'
|
||||||
|
|
||||||
(* next token *)
|
(* next token *)
|
||||||
let rec _next d st =
|
let rec _next d st =
|
||||||
d.st <- st;
|
d.st <- st;
|
||||||
|
|
@ -236,20 +242,32 @@ module Streaming = struct
|
||||||
Buffer.add_char d.atom c;
|
Buffer.add_char d.atom c;
|
||||||
_next d St_quoted
|
_next d St_quoted
|
||||||
end
|
end
|
||||||
|
| (St_escaped | St_raw_char1 _ | St_raw_char2 _) when d.stop ->
|
||||||
|
_error d "unexpected end of input (escaping)"
|
||||||
| St_escaped ->
|
| St_escaped ->
|
||||||
if d.stop
|
begin match _next_char d with
|
||||||
then _error d "unexpected end of input (escaping)";
|
| 'n' -> Buffer.add_char d.atom '\n'; _next d St_quoted
|
||||||
let c = _next_char d in
|
| 't' -> Buffer.add_char d.atom '\t'; _next d St_quoted
|
||||||
Buffer.add_char d.atom
|
| 'r' -> Buffer.add_char d.atom '\r'; _next d St_quoted
|
||||||
(match c with
|
| 'b' -> Buffer.add_char d.atom '\b'; _next d St_quoted
|
||||||
| 'n' -> '\n'
|
| '"' -> Buffer.add_char d.atom '"'; _next d St_quoted
|
||||||
| 't' -> '\t'
|
| '\\' -> Buffer.add_char d.atom '\\'; _next d St_quoted
|
||||||
| 'r' -> '\r'
|
| c when _is_digit c -> _next d (St_raw_char1 (_digit2i c))
|
||||||
| '"' -> '"'
|
|
||||||
| '\\' -> '\\'
|
|
||||||
| c -> _error d "unexpected escaped character %c" c
|
| c -> _error d "unexpected escaped character %c" c
|
||||||
);
|
end
|
||||||
|
| St_raw_char1 i ->
|
||||||
|
begin match _next_char d with
|
||||||
|
| c when _is_digit c -> _next d (St_raw_char2 (i*10 + _digit2i c))
|
||||||
|
| c -> _error d "expected digit, got %c" c
|
||||||
|
end
|
||||||
|
| St_raw_char2 i ->
|
||||||
|
begin match _next_char d with
|
||||||
|
| c when _is_digit c ->
|
||||||
|
(* read an escaped char *)
|
||||||
|
Buffer.add_char d.atom (Char.chr (i*10+_digit2i c));
|
||||||
_next d St_quoted
|
_next d St_quoted
|
||||||
|
| c -> _error d "expected digit, got %c" c
|
||||||
|
end
|
||||||
|
|
||||||
let feed d s i len =
|
let feed d s i len =
|
||||||
if d.stop then failwith "Sexp.Streaming.feed: end of input reached";
|
if d.stop then failwith "Sexp.Streaming.feed: end of input reached";
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue