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 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 {
|
||||
|
@ -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", .{});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user