authorgravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2026-07-08 11:24:15+02:00
committergravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2026-07-08 15:49:43+02:00
logb2c3c33eef468634a2fc47b19bfb2e6f51a1a9b4
tree9fa9992724acfd1a460e5cbd853af95d6528a5c5
parent06b1896a619d13a8b3471dc119d2076f04f85b93
signaturelock-open Commit is signed but in an unrecognized format.

build: check if parser oracle must be regenerated


2 files changed, 37 insertions(+), 12 deletions(-)

build.zig+15-6
...@@ -720,18 +720,27 @@ pub fn build(b: *std.Build) !void {...@@ -720,18 +720,27 @@ pub fn build(b: *std.Build) !void {
720 check_mingw_step.dependOn(&check_mingw_run.step);720 check_mingw_step.dependOn(&check_mingw_run.step);
721721
722 {722 {
723 const gpo_step = b.step("gen-parser-oracle", "Regenerate lib/std/zig/parser_generated_oracle.zig from doc/langref/grammar.peg");723 const gen_oracle_exe = b.addExecutable(.{
724 const gpo_exe = b.addExecutable(.{
725 .name = "gen_parser_oracle",724 .name = "gen_parser_oracle",
726 .root_module = b.createModule(.{725 .root_module = b.createModule(.{
727 .root_source_file = b.path("tools/gen_parser_oracle.zig"),726 .root_source_file = b.path("tools/gen_parser_oracle.zig"),
728 .target = b.graph.host,727 .target = b.graph.host,
729 }),728 }),
730 });729 });
731 const gpo_run = b.addRunArtifact(gpo_exe);730
732 gpo_run.addFileArg(b.path("doc/langref/grammar.peg"));731 const gen_oracle_step = b.step("gen-parser-oracle", "Regenerate lib/std/zig/parser_generated_oracle.zig from doc/langref/grammar.peg");
733 gpo_run.addFileArg(b.path("lib/std/zig/parser_generated_oracle.zig"));732 const gen_oracle_run = b.addRunArtifact(gen_oracle_exe);
734 gpo_step.dependOn(&gpo_run.step);733 gen_oracle_run.addFileArg(b.path("doc/langref/grammar.peg"));
734 gen_oracle_run.addFileArg(b.path("lib/std/zig/parser_generated_oracle.zig"));
735 gen_oracle_step.dependOn(&gen_oracle_run.step);
736
737 const check_oracle_step = b.step("check-parser-oracle", "Check if doc/langref/grammar.peg was modified without regenerating the oracle");
738 const check_oracle_run = b.addRunArtifact(gen_oracle_exe);
739 check_oracle_run.addFileArg(b.path("doc/langref/grammar.peg"));
740 check_oracle_run.addFileArg(b.path("lib/std/zig/parser_generated_oracle.zig"));
741 check_oracle_run.addArg("--check");
742 check_oracle_step.dependOn(&check_oracle_run.step);
743 test_step.dependOn(check_oracle_step);
735 }744 }
736745
737 const test_incremental_step = b.step("test-incremental", "Run the incremental compilation test cases");746 const test_incremental_step = b.step("test-incremental", "Run the incremental compilation test cases");
tools/gen_parser_oracle.zig+22-6
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1//! Example usage:1//! Example usage:
2//! zig build gen-parser-oracle2//! zig build gen-parser-oracle
3//! zig build check-parser-oracle
34
4// This program implements a subset of the PEG grammar definition5// This program implements a subset of the PEG grammar definition
5// in the peg(1) man page.6// in the peg(1) man page.
...@@ -22,6 +23,7 @@ pub fn main(init: std.process.Init) !void {...@@ -22,6 +23,7 @@ pub fn main(init: std.process.Init) !void {
2223
23 const grammar_path = args[1];24 const grammar_path = args[1];
24 const out_path = args[2];25 const out_path = args[2];
26 const check = args.len > 3 and mem.eql(u8, args[3], "--check");
2527
26 const grammar = try Io.Dir.cwd().readFileAlloc(io, grammar_path, gpa, .unlimited);28 const grammar = try Io.Dir.cwd().readFileAlloc(io, grammar_path, gpa, .unlimited);
27 defer gpa.free(grammar);29 defer gpa.free(grammar);
...@@ -53,13 +55,27 @@ pub fn main(init: std.process.Init) !void {...@@ -53,13 +55,27 @@ pub fn main(init: std.process.Init) !void {
53 return error.ParseError;55 return error.ParseError;
54 }56 }
5557
56 var out_file = try Io.Dir.cwd().createFile(io, out_path, .{});58 if (check) {
57 var out_buffer: [4096]u8 = undefined;59 const current = try Io.Dir.cwd().readFileAlloc(io, out_path, gpa, .unlimited);
58 var out_writer = out_file.writer(io, &out_buffer);60 defer gpa.free(current);
59 const out = &out_writer.interface;61 var aw: Io.Writer.Allocating = .init(gpa);
62 defer aw.deinit();
63 try tree.render(gpa, &aw.writer, .{});
64 if (!mem.eql(u8, current, aw.written())) {
65 std.log.err("grammar.peg modified without regenerating oracle", .{});
66 std.log.info("Run zig build gen-parser-oracle to regenerate", .{});
67 std.process.exit(1);
68 }
69 } else {
70 var out_file = try Io.Dir.cwd().createFile(io, out_path, .{});
71 defer out_file.close(io);
72 var out_buffer: [4096]u8 = undefined;
73 var out_writer = out_file.writer(io, &out_buffer);
74 const out = &out_writer.interface;
6075
61 try tree.render(gpa, out, .{});76 try tree.render(gpa, out, .{});
62 try out.flush();77 try out.flush();
78 }
63}79}
6480
65const Generator = struct {81const Generator = struct {