add helper methods for coolio things

This commit is contained in:
Emil Lerch 2025-09-18 15:50:08 -07:00
parent a6425b2aa1
commit d1defaf919
Signed by: lobo
GPG key ID: A7B62D657EF764F8

View file

@ -3,8 +3,6 @@ const c = @cImport({
@cInclude("link-includes.h");
});
pub const sentence = "When your back is is against the whiteboard, I'll be back to back you up";
pub const Link = struct {
left_word: []const u8,
right_word: []const u8,
@ -30,6 +28,74 @@ pub const ParseTree = struct {
}
self.allocator.free(self.links);
}
pub fn firstVerb(self: *ParseTree) ?[]const u8 {
for (self.words) |word| {
if (std.mem.endsWith(u8, word, ".v")) {
return word[0 .. word.len - 2];
}
}
return null;
}
pub fn sentenceAction(self: *ParseTree) ![][]const u8 {
var al: std.ArrayList([]const u8) = .{};
defer al.deinit(self.allocator);
for (self.words, 0..) |word, i| {
if (std.mem.endsWith(u8, word, ".v")) {
// adjective or noun
for (self.links) |l| {
// We're looking for a modifying verb, see:
// https://www.link.cs.cmu.edu/link/dict/section-MV.html
if (@as(usize, l.left_index) == i and
std.mem.startsWith(u8, l.label, "MV"))
{
// this is an modifying verb
try al.append(self.allocator, word[0 .. word.len - 2]);
try al.append(
self.allocator,
l.right_word[0 .. std.mem.lastIndexOfScalar(u8, l.right_word, '.') orelse l.right_word.len],
);
return al.toOwnedSlice(self.allocator);
}
}
// no adjective, just this noun
try al.append(self.allocator, word[0 .. word.len - 2]);
return al.toOwnedSlice(self.allocator);
}
}
return al.toOwnedSlice(self.allocator);
}
pub fn sentenceObject(self: *ParseTree) ![][]const u8 {
var al: std.ArrayList([]const u8) = .{};
defer al.deinit(self.allocator);
for (self.words, 0..) |word, i| {
if (std.mem.endsWith(u8, word, ".n")) {
// adjective or noun
for (self.links) |l| {
if (@as(usize, l.left_index) == i and
std.mem.startsWith(u8, l.label, "AN"))
{
// this is an adjective. We need to add both it and the noun to the list
// https://www.link.cs.cmu.edu/link/dict/section-AN.html
try al.append(self.allocator, word[0 .. word.len - 2]);
try al.append(
self.allocator,
l.right_word[0 .. std.mem.lastIndexOfScalar(u8, l.right_word, '.') orelse l.right_word.len],
);
return al.toOwnedSlice(self.allocator);
}
}
// no adjective, just this noun
try al.append(self.allocator, word[0 .. word.len - 2]);
return al.toOwnedSlice(self.allocator);
}
}
return al.toOwnedSlice(self.allocator);
}
};
pub const Parser = struct {
@ -138,5 +204,51 @@ test "parser functionality" {
var tree = try parser.parse("The cat sat on the mat");
defer tree.deinit();
try std.testing.expect(tree.words.len > 0);
// for (tree.links) |w|
// std.debug.print("l: '{s}', r: '{s}', label: '{s}'\n", .{ w.left_word, w.right_word, w.label });
//
// std.debug.print("{any}\n", .{tree.words.len});
// LEFT-WALL
// the
// cat.n
// sat.v
// on
// the
// mat.n
// RIGHT-WALL
try std.testing.expect(tree.words.len == 8); // 6 + LEFT_WALL / RIGHT_WALL
}
test "from website" {
const sentence = "When your back is is against the whiteboard, I'll be back to back you up";
var parser = try Parser.init(std.testing.allocator);
defer parser.deinit();
var tree = try parser.parse(sentence);
defer tree.deinit();
}
test "real usage" {
var parser = try Parser.init(std.testing.allocator);
defer parser.deinit();
var tree = try parser.parse("turn on the bedroom light");
defer tree.deinit();
// for (tree.links) |w|
// std.debug.print("l: '{s}', r: '{s}', label: '{s}'\n", .{ w.left_word, w.right_word, w.label });
//
// for (tree.words) |w|
// std.debug.print("{s}\n", .{w});
// std.debug.print("{any}\n", .{tree.words.len});
try std.testing.expect(tree.words.len == 7); // 5 + LEFT_WALL / RIGHT_WALL
try std.testing.expectEqualStrings("turn", tree.firstVerb().?);
const sentence_action = try tree.sentenceAction();
defer std.testing.allocator.free(sentence_action);
try std.testing.expect(sentence_action.len == 2);
try std.testing.expectEqualStrings("turn", sentence_action[0]);
try std.testing.expectEqualStrings("on", sentence_action[1]);
const sentence_object = try tree.sentenceObject();
defer std.testing.allocator.free(sentence_object);
try std.testing.expect(sentence_object.len == 2);
try std.testing.expectEqualStrings("bedroom", sentence_object[0]);
try std.testing.expectEqualStrings("light", sentence_object[1]);
}