diff options
author | Stefan Weigl-Bosker <stefan@s00.xyz> | 2024-12-20 17:22:33 -0500 |
---|---|---|
committer | Stefan Weigl-Bosker <stefan@s00.xyz> | 2024-12-20 17:22:33 -0500 |
commit | 32d0ac56c27719c6fcde70c51238f11cf5f44141 (patch) | |
tree | da490e13f07be4573a0530c184fd873dc9c824dc /src/regex.zig | |
parent | dca73fef741a57c8cc1913def98a305c2b709391 (diff) | |
download | lg-32d0ac56c27719c6fcde70c51238f11cf5f44141.tar.gz |
regex parsing
Diffstat (limited to 'src/regex.zig')
-rw-r--r-- | src/regex.zig | 60 |
1 files changed, 59 insertions, 1 deletions
diff --git a/src/regex.zig b/src/regex.zig index a2f9c79..de24dc0 100644 --- a/src/regex.zig +++ b/src/regex.zig @@ -1,4 +1,6 @@ const std = @import("std"); +pub const Parser = @import("parser.zig").Parser; +pub const ParseTree = @import("parser.zig").ParseTree; pub const Token = struct { pub const Kind = enum { Literal, LParen, RParen, Class, Dot, Star, Plus, Question, Or }; @@ -25,6 +27,15 @@ pub const Token = struct { try writer.print(" }}", .{}); } + + pub fn deinit(self: *const Token) void { + if (self.value) |val| { + switch (val) { + .Class => |*rl| rl.deinit(), + else => {}, + } + } + } }; pub const Lexer = struct { @@ -32,11 +43,27 @@ pub const Lexer = struct { cursor: usize, regexp: []const u8, allocator: *std.mem.Allocator, + tokens: std.SinglyLinkedList(Token), pub const Error = error{ EndOfBuffer, InvalidCharacter, UnexpectedCharater }; pub fn init(regexp: []const u8, allocator: *std.mem.Allocator) Lexer { - return .{ .cursor = 0, .start = 0, .regexp = regexp, .allocator = allocator }; + return .{ .cursor = 0, .start = 0, .regexp = regexp, .allocator = allocator, .tokens = std.SinglyLinkedList(Token){ .first = null } }; + } + + pub fn deinit(self: *Lexer) void { + var it = self.tokens.first; + + while (it) |node| { + if (node.data.value) |val| { + switch (val) { + .Class => |*rl| rl.deinit(), + else => {}, + } + } + it = node.next; + self.allocator.destroy(node); + } } fn readChar(self: *Lexer) !u8 { @@ -47,6 +74,37 @@ pub const Lexer = struct { return self.regexp[self.cursor]; } + pub fn scan(self: *Lexer) !std.SinglyLinkedList(Token) { + if (self.tokens.first) |_| { + return self.tokens; + } else { + self.tokens.first = try self.allocator.create(std.SinglyLinkedList(Token).Node); + } + + var tail: ?*std.SinglyLinkedList(Token).Node = null; + var node = self.tokens.first; + + while (true) { + const token: Token = self.advance() catch |err| switch (err) { + Error.EndOfBuffer => { + self.allocator.destroy(node.?); + if (tail) |t| { + t.next = null; + } + return self.tokens; + }, + else => { + return err; + }, + }; + + node.?.data = token; + node.?.next = try self.allocator.create(std.SinglyLinkedList(Token).Node); + tail = node; + node = node.?.next; + } + } + pub fn advance(self: *Lexer) !Token { self.start = self.cursor; |