Skip to content

Commit

Permalink
implement parsing of objects
Browse files Browse the repository at this point in the history
  • Loading branch information
gorm-issuu authored and Daniel Hilst committed Aug 28, 2022
1 parent 64d6ad2 commit e4e4546
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 13 deletions.
24 changes: 11 additions & 13 deletions lib/json5/parser.ml
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,25 @@ let rec parse_list acc = function
let s = Format.asprintf "Unexpected list token: %a" pp_token x in
failwith s)

(*
and parse_assoc acc = function
| [] -> failwith "Assoc never ends"
| CLOSE_BRACE::xs
| COMMA::CLOSE_BRACE::xs -> (acc, xs)
| (STRING k)::COLON::v::COMMA::xs
| (IDENTIFIER_NAME k)::COLON::v::COMMA::xs ->
let (v, xs) = parse [v] in
| (STRING k)::COLON::xs
| (IDENTIFIER_NAME k)::COLON::xs -> (
let (v, xs) = parse xs in
let item = (k, v) in
parse_assoc (item::acc) xs
| (STRING k)::COLON::v::CLOSE_BRACE::xs
| (IDENTIFIER_NAME k)::COLON::v::CLOSE_BRACE::xs ->
let (v, _) = parse [x]
let acc = (k, parse [v])::acc in
(acc, xs)
match xs with
| [] -> failwith "Object was not closed"
| CLOSE_BRACE::xs
| COMMA::CLOSE_BRACE::xs -> (item::acc, xs)
| COMMA::xs -> parse_assoc (item::acc) xs
| x::_ ->
let s = Format.asprintf "Unexpected assoc list token: %a" pp_token x in
failwith s)
| x::_ ->
let s = Format.asprintf "Unexpected assoc list token: %a" pp_token x in
failwith s
*)

and parse : token list -> (t * token list) = function
| [] -> failwith "empty list of tokens"
Expand All @@ -51,11 +51,9 @@ and parse : token list -> (t * token list) = function
| OPEN_BRACKET ->
let (l, xs) = parse_list [] xs in
(`List (List.rev l), xs)
(*
| OPEN_BRACE ->
let (a, xs) = parse_assoc [] xs in
(`Assoc (List.rev a), xs)
*)
| x ->
let s = Format.asprintf "Unexpected token: %a" pp_token x in
failwith s
Expand Down
21 changes: 21 additions & 0 deletions test/json5/json5_test.ml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ let test_single_line_comments () =
Alcotest.(check (list token)) "Simple case" [] (tokenize_json5 "//foo\n");
Alcotest.(check (list token)) "Between numbers" [INT_OR_FLOAT "1"; INT_OR_FLOAT "1"] (tokenize_json5 "1//foo\n1")
(**
* PARSING
*)
Expand All @@ -68,12 +69,30 @@ let test_parser_simple () =
Alcotest.(check yojson) "Simple null" `Null (parse [NULL]);
Alcotest.(check yojson) "Simple true" (`Bool true) (parse [TRUE]);
Alcotest.(check yojson) "Simple false" (`Bool false) (parse [FALSE]);
Alcotest.(check yojson) "Simple int" (`Int 3) (parse [INT 3]);
Alcotest.(check yojson) "Simple float" (`Float 3.4) (parse [FLOAT 3.4]);
()
let test_parser_string () =
Alcotest.(check yojson) "Simple string" (`String "hello") (parse [STRING "hello"]);
Alcotest.(check yojson) "Escape sequences" (`String "a\'\"\\\b\n\r\ta") (parse [STRING "a\'\"\\\b\n\r\ta"]);
()

let test_parser_list () =
Alcotest.(check yojson) "Empty list" (`List []) (parse [OPEN_BRACKET; CLOSE_BRACKET]);
Alcotest.(check yojson) "List with bools" (`List [`Bool false; `Bool true]) (parse [OPEN_BRACKET; FALSE; COMMA; TRUE; CLOSE_BRACKET]);
Alcotest.(check yojson) "List of lists" (`List [ `List []; `Null ]) (parse [OPEN_BRACKET; OPEN_BRACKET; CLOSE_BRACKET; COMMA; NULL; CLOSE_BRACKET]);
Alcotest.(check yojson) "List with trailing comma" (`List [ `Null ]) (parse [OPEN_BRACKET; NULL; COMMA; CLOSE_BRACKET]);
Alcotest.(check yojson) "List of list with content" (`List [ `List [ `Bool true ] ]) (parse [OPEN_BRACKET; OPEN_BRACKET; TRUE; CLOSE_BRACKET; CLOSE_BRACKET]);
()

let test_parser_object () =
Alcotest.(check yojson) "Empty object" (`Assoc []) (parse [OPEN_BRACE; CLOSE_BRACE]);
Alcotest.(check yojson) "String key" (`Assoc [ ("foo", `Null) ]) (parse [OPEN_BRACE; STRING "foo"; COLON; NULL; CLOSE_BRACE]);
Alcotest.(check yojson) "Identifer key" (`Assoc [ ("foo", `Null) ]) (parse [OPEN_BRACE; IDENTIFIER_NAME "foo"; COLON; NULL; CLOSE_BRACE]);
Alcotest.(check yojson) "Trailing comma" (`Assoc [ ("foo", `Null) ]) (parse [OPEN_BRACE; STRING "foo"; COLON; NULL; COMMA; CLOSE_BRACE]);
Alcotest.(check yojson) "Nested object" (`Assoc [ ("foo", `Assoc [ ("bar", `Null) ]) ]) (parse [OPEN_BRACE; STRING "foo"; COLON; OPEN_BRACE; STRING "bar"; COLON; NULL; CLOSE_BRACE; COMMA; CLOSE_BRACE]);
Alcotest.(check yojson) "Mixed keys and values" (`Assoc [ ("foo", `Bool true); ("bar", `Null); ("baz", `Bool false) ]) (parse [OPEN_BRACE; STRING "foo"; COLON; TRUE; COMMA; IDENTIFIER_NAME "bar"; COLON; NULL; COMMA; IDENTIFIER_NAME "baz"; COLON; FALSE; CLOSE_BRACE]);
()


Expand Down Expand Up @@ -101,6 +120,8 @@ let () =
];
"Parse", [
test_case "Simple parsing" `Quick test_parser_simple;
test_case "Strings" `Quick test_parser_string;
test_case "Simple list parsing" `Quick test_parser_list;
test_case "Simple object parsing" `Quick test_parser_object;
];
]

0 comments on commit e4e4546

Please sign in to comment.