Working new filter parse

Now the parseFilter function return a Filter struct.

It is a tree of Condition and Logic operator  that will then be use when
parsing row. Need to do the evaluate function with the []Data and test
some error
This commit is contained in:
Adrien Bouvais 2024-10-27 21:56:57 +01:00
parent 15171f73c6
commit 2a946eafd0
2 changed files with 44 additions and 42 deletions

View File

@ -1,8 +1,18 @@
// Should do a tree like that:
// AND
// / \
// OR OR
// / \ / \
// name name age age
// ='A' ='B' >80 <20
//
// For {(name = 'Adrien' OR name = 'Bob') AND (age > 80 OR age < 20)}
const std = @import("std");
const ZipponError = @import("errors.zig").ZipponError;
const DataType = @import("dtype").DataType;
pub const ComparisonOperator = enum {
const ComparisonOperator = enum {
equal,
different,
superior,
@ -24,7 +34,7 @@ pub const ComparisonOperator = enum {
}
};
pub const LogicalOperator = enum {
const LogicalOperator = enum {
AND,
OR,
@ -44,7 +54,7 @@ pub const Condition = struct {
// data_index: usize TODO: add this member, this is the position in the row of the value, to use in the evaluate method
};
pub const FilterNode = union(enum) {
const FilterNode = union(enum) {
condition: Condition,
logical: struct {
operator: LogicalOperator,
@ -173,9 +183,8 @@ pub const Filter = struct {
}
pub fn debugPrint(self: Filter) void {
std.debug.print("\n\n", .{});
self.printNode(self.root.*);
std.debug.print("\n\n", .{});
std.debug.print("\n", .{});
}
fn printNode(self: Filter, node: FilterNode) void {

View File

@ -48,8 +48,7 @@ const State = enum {
expect_comma_OR_r_bracket,
// For the filter parser
expect_left_condition, // Condition is a struct in FileEngine, it's all info necessary to get a list of UUID usinf FileEngine.getUUIDListUsingCondition
expect_right_condition,
expect_condition,
expect_operation, // Operations are = != < <= > >=
expect_value,
expect_ANDOR_OR_end,
@ -390,48 +389,17 @@ pub const Parser = struct {
var keep_next = false;
var token = self.toker.next();
var state: State = .expect_left_condition;
var state: State = .expect_condition;
while (state != .end) : ({
token = if (keep_next) token else self.toker.next();
keep_next = false;
}) {
switch (state) {
.expect_left_condition => switch (token.tag) {
.expect_condition => switch (token.tag) {
.r_brace => {
state = .end;
},
else => {
const condition = try self.parseCondition(&token, struct_name);
try filter.addCondition(condition);
state = .expect_ANDOR_OR_end;
token = self.toker.last();
keep_next = true;
},
},
.expect_ANDOR_OR_end => switch (token.tag) {
.r_brace, .r_paren => {
state = .end;
},
.keyword_and => {
try filter.addLogicalOperator(.AND);
state = .expect_right_condition;
},
.keyword_or => {
try filter.addLogicalOperator(.OR);
state = .expect_right_condition;
},
else => return printError(
"Error: Expected AND, OR, or }",
ZiQlParserError.SynthaxError,
self.toker.buffer,
token.loc.start,
token.loc.end,
),
},
.expect_right_condition => switch (token.tag) {
.l_paren => {
var sub_filter = try self.parseFilter(struct_name);
filter.addSubFilter(&sub_filter);
@ -447,7 +415,28 @@ pub const Parser = struct {
state = .expect_ANDOR_OR_end;
},
else => return printError(
"Error: Expected ( or member name.",
"Error: Expected ( or condition.",
ZiQlParserError.SynthaxError,
self.toker.buffer,
token.loc.start,
token.loc.end,
),
},
.expect_ANDOR_OR_end => switch (token.tag) {
.r_brace, .r_paren => {
state = .end;
},
.keyword_and => {
try filter.addLogicalOperator(.AND);
state = .expect_condition;
},
.keyword_or => {
try filter.addLogicalOperator(.OR);
state = .expect_condition;
},
else => return printError(
"Error: Expected AND, OR, or }",
ZiQlParserError.SynthaxError,
self.toker.buffer,
token.loc.start,
@ -1001,11 +990,13 @@ fn expectParsingError(source: [:0]const u8, err: ZiQlParserError) !void {
try std.testing.expectError(err, parser.parse());
}
test "New parser filter" {
test "Parse filter" {
try testParseFilter("name = 'Adrien'}");
try testParseFilter("name = 'Adrien' AND age > 11}");
try testParseFilter("name = 'Adrien' AND (age < 11 OR age > 40)}");
try testParseFilter("(name = 'Adrien') AND (age < 11 OR age > 40)}");
try testParseFilter("(name = 'Adrien' OR name = 'Bob') AND (age < 11 OR age > 40)}");
try testParseFilter("(name = 'Adrien' OR name = 'Bob') AND (age < 11 OR age > 40 AND (age != 20))}");
}
fn testParseFilter(source: [:0]const u8) !void {
@ -1021,5 +1012,7 @@ fn testParseFilter(source: [:0]const u8) !void {
var filter = try parser.parseFilter("User");
defer filter.deinit();
std.debug.print("{s}\n", .{source});
filter.debugPrint();
std.debug.print("\n", .{});
}