diff --git a/src/main.zig b/src/main.zig index d2db292..6c4e940 100644 --- a/src/main.zig +++ b/src/main.zig @@ -322,7 +322,8 @@ fn processCommand(allocator: std.mem.Allocator, sentence: [:0]const u8, parser: defer tree.deinit(); const action_words = tree.sentenceAction() catch |err| { - std.log.err("Failed to extract action: {}\n", .{err}); + if (!builtin.is_test) + std.log.err("Failed to extract action: {}\nParse tree: {f}", .{ err, tree }); continue; }; defer allocator.free(action_words); @@ -537,7 +538,6 @@ test "processCommand with word replacement like to light - three words" { var devices = std.StringHashMap([]const u8).init(std.testing.allocator); defer devices.deinit(); - if (true) return error.SkipZigTest; try devices.put("jack bedroom light", "192.168.1.101"); var parser = try pos.Parser.init(std.testing.allocator); @@ -547,9 +547,9 @@ test "processCommand with word replacement like to light - three words" { const sentence_z = try std.testing.allocator.dupeZ(u8, sentence); defer std.testing.allocator.free(sentence_z); - const ll = std.testing.log_level; - std.testing.log_level = .debug; - defer std.testing.log_level = ll; + // const ll = std.testing.log_level; + // std.testing.log_level = .debug; + // defer std.testing.log_level = ll; try processCommand(std.testing.allocator, sentence_z, &parser, &devices); try std.testing.expectEqualStrings("192.168.1.101", test_device_entry.value_ptr.*); diff --git a/src/root.zig b/src/root.zig index 5f76d4f..f9c98aa 100644 --- a/src/root.zig +++ b/src/root.zig @@ -82,28 +82,46 @@ pub const ParseTree = struct { 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| { - // This should be looking through the consituent tree - // 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]); + if (self.constituent_tree == null) return error.NoConstituentTree; + var node = self.constituent_tree.?; + // https://www.link.cs.cmu.edu/link/dict/section-S.html + if (!std.mem.startsWith(u8, node.label, "S")) + return error.NoSubjectNounFound; + if (node.child == null) @panic("S node must have a child"); + node = node.child.?; + + // I'm not entirely sure this will be universally true, but we'll see + // in real life testing + // https://www.link.cs.cmu.edu/link/dict/section-V.html + // https://www.link.cs.cmu.edu/link/dict/section-P.html + if (!std.mem.eql(u8, node.label, "VP")) + return error.VerbBeLinkageNotFound; + + if (node.child == null) @panic("VP node must have a child"); + node = node.child.?; + + // This should be our action + if (node.start != node.end) + return error.MultiWordVerbsNotSupported; // this should be our issue... + + const verb = self.words[node.start + 1]; // +1 due to LEFT_WALL + if (!std.mem.endsWith(u8, verb, ".v")) + return error.VerbNotLabeledWithDotV; + + // From this verb, we can just look at the linkage to find what to append + 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) == (node.start + 1) and + std.mem.startsWith(u8, l.label, "MV")) + { + // this is an modifying verb + try al.append(self.allocator, verb[0 .. verb.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); } }