Skip to content

Instantly share code, notes, and snippets.

@andreypopp
Created January 11, 2023 11:20
Show Gist options
  • Save andreypopp/85224198ee9e1d85816bb4e5ade17d7f to your computer and use it in GitHub Desktop.
Save andreypopp/85224198ee9e1d85816bb4e5ade17d7f to your computer and use it in GitHub Desktop.
{
let collect state acc buf =
let should_collect =
match state with
| `empty -> true
| `start | `non_empty -> Buffer.length buf > 0
in
if should_collect
then (
let v = Buffer.contents buf in
Buffer.clear buf;
v::acc
) else acc
}
rule array = parse
'{' { read_array `start [] (Buffer.create 10) lexbuf }
| eof { raise End_of_file }
and read_array state acc buf = parse
',' {
let state = if state = `start then `empty else state in
read_array `empty (collect state acc buf) buf lexbuf
}
| '"' {
let v = read_quoted buf lexbuf in
Buffer.clear buf;
read_array `non_empty (v::acc) buf lexbuf
}
| '}' {
collect state acc buf
}
| eof { raise End_of_file }
| _ as v {
Buffer.add_char buf v;
read_array `non_empty acc buf lexbuf
}
and row = parse
'(' { read_row `start [] (Buffer.create 10) lexbuf }
| eof { raise End_of_file }
and read_row state acc buf = parse
',' {
let state = if state = `start then `empty else state in
read_row `empty (collect state acc buf) buf lexbuf
}
| '"' {
let v = read_quoted buf lexbuf in
Buffer.clear buf;
read_row `non_empty (v::acc) buf lexbuf
}
| ')' {
collect state acc buf
}
| eof { raise End_of_file }
| _ as v {
Buffer.add_char buf v;
read_row `non_empty acc buf lexbuf
}
and read_quoted buf = parse
'"' { Buffer.contents buf }
| '\\' '"' { Buffer.add_char buf '"'; read_quoted buf lexbuf }
| _ as v { Buffer.add_char buf v; read_quoted buf lexbuf }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment