Parsing ZON files (NOT build.zig.zon) from Zig code

Could somebody please point me in the direction of ZON parsing functionality in stdlib (I hope it’s there, where else would it be)?

I have found myself in need of a ‘config’ file format, and while I have used JSON, YAML, TOML and my own homegrown file formats in the past for this purpose, I think ZON is the obvious choice in Zig programs.

Upd: these seem to be relevant:
https://github.com/ziglang/zig/blob/master/lib/std/zig/Parse.zig
https://github.com/ziglang/zig/blob/master/lib/std/zig/Ast.zig
but for me they’re a ball of yarn I’d have to untangle. Not that I don’t want to learn (I do), but abstract syntax trees are not my primary focus right now, and so I would be grateful if I could just throw a ZON file at a function and get some form of parsed result in return.

Maybe reading the loadManifest function can help in Fetch.zig?

1 Like

Thank you.
I’m currently looking at fn parse in Ast.zig: zig/lib/std/zig/Ast.zig at master · ziglang/zig · GitHub , at it uses std.zig.Parse, hoping I can copy from it.

Update: well, this does do something:

    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const alloc8r = gpa.allocator();

    const zon_txt =
        \\.{
        \\    .name = "libffmpeg",
        \\    .version = "5.1.2",
        \\}
        ;

    var ast = try std.zig.Ast.parse(alloc8r, zon_txt, .zon);
    defer ast.deinit(alloc8r);
    std.debug.print("{}\n", .{ ast });
$ zig run zon_parse.zig 
zig.Ast{ .source = { 46, 123, 10, 32, 32, 32, 32, 46, 110, 97, 109, 101, 32, 61, 32, 34, 108, 105, 98, 102, 102, 109, 112, 101, 103, 34, 44, 10, 32, 32, 32, 32, 46, 118, 101, 114, 115, 105, 111, 110, 32, 61, 32, 34, 53, 46, 49, 46, 50, 34, 44, 10, 125 }, .tokens = multi_array_list.MultiArrayList(zig.Ast.TokenList__struct_4036).Slice{ .ptrs = { u8@7f8bf672b050, u8@7f8bf672b000 }, .len = 14, .capacity = 20 }, .nodes = multi_array_list.MultiArrayList(zig.Ast.Node).Slice{ .ptrs = { u8@7f8bf672b0e0, u8@7f8bf672b080, u8@7f8bf672b0a0 }, .len = 4, .capacity = 8 }, .extra_data = {  }, .mode = zig.Ast.Mode.zon, .errors = {  } }

You can have a look at what Manifest does and you’re all set.

1 Like

I have found this post - Zig Parser – Mitchell Hashimoto

BTW, it looks like Parse struct is not public, meaning that ZON parsing functionality is for not for external use either :cry:

Just wanted to share that I’m making some progress by following @figsoda’s zon2nix, more specifically, function parse: zon2nix/src/parse.zig at main · nix-community/zon2nix · GitHub

1 Like

BTW, does ZON support arrays?

Both .uint_arr = { 1, 2, 3, 4 }, and .uint_arr = .{ 1, 2, 3, 4 }, seem to be passing std.zig.Ast.parse with flying colors.

I wonder which of them (if any) is correct.
With .uint_arr = .{ I’m getting zig.Ast.Node.Tag.array_init_dot, and with .uint_arr_2 = { - zig.Ast.Node.Tag.block_two, so I guess .{ is correct. Maybe.

Or is it something like [_]{ 1, 2, 3, 4 } ?

Ok, never mind that last question about arrays (yes, they are supported).

I think I have achieved what I wanted, here’s the link - ZON field value extractor (for the lack of better name) - zon_get_fields

2 Likes

I made zon2json tool for my zig2nix repo zig2nix/tools/zon2json at master · Cloudef/zig2nix · GitHub

2 Likes

I split it into separate module zig2nix/tools/zon2json/src at master · Cloudef/zig2nix · GitHub
Not sure if zig package manager can access subpaths in git repo though.
It’s mainly used to generate lockfiles for nix zig2nix/tools/fixtures/2.zig.zon2json-lock at master · Cloudef/zig2nix · GitHub

Though I may eventually replace this tool, reason here:

3 Likes