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:
parent
15171f73c6
commit
2a946eafd0
@ -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 std = @import("std");
|
||||||
const ZipponError = @import("errors.zig").ZipponError;
|
const ZipponError = @import("errors.zig").ZipponError;
|
||||||
const DataType = @import("dtype").DataType;
|
const DataType = @import("dtype").DataType;
|
||||||
|
|
||||||
pub const ComparisonOperator = enum {
|
const ComparisonOperator = enum {
|
||||||
equal,
|
equal,
|
||||||
different,
|
different,
|
||||||
superior,
|
superior,
|
||||||
@ -24,7 +34,7 @@ pub const ComparisonOperator = enum {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const LogicalOperator = enum {
|
const LogicalOperator = enum {
|
||||||
AND,
|
AND,
|
||||||
OR,
|
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
|
// 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,
|
condition: Condition,
|
||||||
logical: struct {
|
logical: struct {
|
||||||
operator: LogicalOperator,
|
operator: LogicalOperator,
|
||||||
@ -173,9 +183,8 @@ pub const Filter = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn debugPrint(self: Filter) void {
|
pub fn debugPrint(self: Filter) void {
|
||||||
std.debug.print("\n\n", .{});
|
|
||||||
self.printNode(self.root.*);
|
self.printNode(self.root.*);
|
||||||
std.debug.print("\n\n", .{});
|
std.debug.print("\n", .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn printNode(self: Filter, node: FilterNode) void {
|
fn printNode(self: Filter, node: FilterNode) void {
|
||||||
|
@ -48,8 +48,7 @@ const State = enum {
|
|||||||
expect_comma_OR_r_bracket,
|
expect_comma_OR_r_bracket,
|
||||||
|
|
||||||
// For the filter parser
|
// 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_condition,
|
||||||
expect_right_condition,
|
|
||||||
expect_operation, // Operations are = != < <= > >=
|
expect_operation, // Operations are = != < <= > >=
|
||||||
expect_value,
|
expect_value,
|
||||||
expect_ANDOR_OR_end,
|
expect_ANDOR_OR_end,
|
||||||
@ -390,48 +389,17 @@ pub const Parser = struct {
|
|||||||
|
|
||||||
var keep_next = false;
|
var keep_next = false;
|
||||||
var token = self.toker.next();
|
var token = self.toker.next();
|
||||||
var state: State = .expect_left_condition;
|
var state: State = .expect_condition;
|
||||||
|
|
||||||
while (state != .end) : ({
|
while (state != .end) : ({
|
||||||
token = if (keep_next) token else self.toker.next();
|
token = if (keep_next) token else self.toker.next();
|
||||||
keep_next = false;
|
keep_next = false;
|
||||||
}) {
|
}) {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
.expect_left_condition => switch (token.tag) {
|
.expect_condition => switch (token.tag) {
|
||||||
.r_brace => {
|
.r_brace => {
|
||||||
state = .end;
|
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 => {
|
.l_paren => {
|
||||||
var sub_filter = try self.parseFilter(struct_name);
|
var sub_filter = try self.parseFilter(struct_name);
|
||||||
filter.addSubFilter(&sub_filter);
|
filter.addSubFilter(&sub_filter);
|
||||||
@ -447,7 +415,28 @@ pub const Parser = struct {
|
|||||||
state = .expect_ANDOR_OR_end;
|
state = .expect_ANDOR_OR_end;
|
||||||
},
|
},
|
||||||
else => return printError(
|
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,
|
ZiQlParserError.SynthaxError,
|
||||||
self.toker.buffer,
|
self.toker.buffer,
|
||||||
token.loc.start,
|
token.loc.start,
|
||||||
@ -1001,11 +990,13 @@ fn expectParsingError(source: [:0]const u8, err: ZiQlParserError) !void {
|
|||||||
try std.testing.expectError(err, parser.parse());
|
try std.testing.expectError(err, parser.parse());
|
||||||
}
|
}
|
||||||
|
|
||||||
test "New parser filter" {
|
test "Parse filter" {
|
||||||
try testParseFilter("name = 'Adrien'}");
|
try testParseFilter("name = 'Adrien'}");
|
||||||
try testParseFilter("name = 'Adrien' AND age > 11}");
|
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') 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 {
|
fn testParseFilter(source: [:0]const u8) !void {
|
||||||
@ -1021,5 +1012,7 @@ fn testParseFilter(source: [:0]const u8) !void {
|
|||||||
|
|
||||||
var filter = try parser.parseFilter("User");
|
var filter = try parser.parseFilter("User");
|
||||||
defer filter.deinit();
|
defer filter.deinit();
|
||||||
|
std.debug.print("{s}\n", .{source});
|
||||||
filter.debugPrint();
|
filter.debugPrint();
|
||||||
|
std.debug.print("\n", .{});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user