diff options
| author | Nathan Reiner <nathan@nathanreiner.xyz> | 2025-05-13 15:45:50 +0200 |
|---|---|---|
| committer | Nathan Reiner <nathan@nathanreiner.xyz> | 2025-05-13 15:45:50 +0200 |
| commit | 76f808ea98313dc847f634b2d8e31066b7a1c68d (patch) | |
| tree | ceead1140f66547bb26cd3af364d37913b380398 /src/grammar.zig | |
| parent | eff19cc15a9bf4df60e7f90c3a7ee525c65266c0 (diff) | |
make it work sometimes
Diffstat (limited to 'src/grammar.zig')
| -rw-r--r-- | src/grammar.zig | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/src/grammar.zig b/src/grammar.zig index 298932c..b3785ba 100644 --- a/src/grammar.zig +++ b/src/grammar.zig @@ -51,6 +51,12 @@ pub fn parse(entry: []const u8, buffer: []const u8, allocator: std.mem.Allocator self.generate_first(); self.generate_follows(); + for (self.non_terminals) |non_terminal| { + std.debug.print("{s} := {}\n", .{non_terminal.name, non_terminal.follows}); + } + + std.debug.print("{}\n", .{self}); + return self; } @@ -181,6 +187,45 @@ fn generate_follows(self: *Self) void { } } +pub fn is_next_char(self: *const Self, rule_slice: []Character, current: usize, char: u8) bool { + var is_char_in_first = false; + var is_epsilon_in_first = true; + + for (rule_slice) |character| { + switch(character) { + .terminal => |c| { + is_char_in_first = c == char; + break; + }, + .non_terminal => |n| { + is_char_in_first = self.non_terminals[n].first.is_set(char); + + if (is_char_in_first or !self.non_terminals[n].first.is_set(Character.EPSILON)) { + break; + } + }, + else => {}, + } + } + + for (rule_slice) |character| { + switch(character) { + .terminal => is_epsilon_in_first = false, + .non_terminal => |n| { + if (!self.non_terminals[n].first.is_set(Character.EPSILON)) { + is_epsilon_in_first = false; + break; + } + }, + else => {}, + } + } + + const result = is_char_in_first or (is_epsilon_in_first and self.non_terminals[current].follows.is_set(char)); + + return result; +} + pub fn format( self: *const Self, comptime fmt: []const u8, |