Untested iterative implementation of evaluate
This commit is contained in:
parent
2453404604
commit
f2ba9d7621
17
lib/stack.c
17
lib/stack.c
@ -24,7 +24,7 @@ void free_stack(stack_t* stack)
|
|||||||
xfree(stack);
|
xfree(stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
void push(stack_t* stack, void* elt)
|
void stack_push(stack_t* stack, void* elt)
|
||||||
{
|
{
|
||||||
if (stack->cur_size == stack->max_size) {
|
if (stack->cur_size == stack->max_size) {
|
||||||
stack->max_size *= 2;
|
stack->max_size *= 2;
|
||||||
@ -33,8 +33,17 @@ void push(stack_t* stack, void* elt)
|
|||||||
stack->arr[stack->cur_size++] = elt;
|
stack->arr[stack->cur_size++] = elt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* pop(stack_t* stack)
|
void stack_pop(stack_t* stack)
|
||||||
{
|
{
|
||||||
void* res = stack->arr[--stack->cur_size];
|
--stack->cur_size;
|
||||||
return res;
|
}
|
||||||
|
|
||||||
|
void* stack_peek(stack_t* stack)
|
||||||
|
{
|
||||||
|
return stack->arr[stack->cur_size - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
int stack_is_empty(stack_t* stack)
|
||||||
|
{
|
||||||
|
return (stack->cur_size == 0);
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,10 @@ typedef struct stack stack_t;
|
|||||||
stack_t* alloc_stack(size_t size);
|
stack_t* alloc_stack(size_t size);
|
||||||
void free_stack(stack_t* stack);
|
void free_stack(stack_t* stack);
|
||||||
|
|
||||||
void push(stack_t* stack, void* elt);
|
void stack_push(stack_t* stack, void* elt);
|
||||||
void* pop(stack_t* stack);
|
void stack_pop(stack_t* stack);
|
||||||
|
void* stack_peek(stack_t* stack);
|
||||||
|
|
||||||
|
int stack_is_empty(stack_t* stack);
|
||||||
|
|
||||||
#endif /* ZMAP_STACK_H */
|
#endif /* ZMAP_STACK_H */
|
@ -1,6 +1,8 @@
|
|||||||
#include "expression.h"
|
#include "expression.h"
|
||||||
#include "fieldset.H"
|
#include "fieldset.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "../lib/stack.h"
|
||||||
#include "../lib/xalloc.h"
|
#include "../lib/xalloc.h"
|
||||||
|
|
||||||
/* Static helper functions */
|
/* Static helper functions */
|
||||||
@ -83,6 +85,7 @@ node_t* make_field_node(char *fieldname)
|
|||||||
node_t *node = alloc_node();
|
node_t *node = alloc_node();
|
||||||
node->type = FIELD;
|
node->type = FIELD;
|
||||||
node->value.field.fieldname = fieldname;
|
node->value.field.fieldname = fieldname;
|
||||||
|
node->result = 1;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,6 +94,7 @@ node_t* make_string_node(char *literal)
|
|||||||
node_t *node = alloc_node();
|
node_t *node = alloc_node();
|
||||||
node->type = STRING;
|
node->type = STRING;
|
||||||
node->value.string_literal = literal;
|
node->value.string_literal = literal;
|
||||||
|
node->result = 1;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,6 +103,7 @@ node_t* make_int_node(int literal)
|
|||||||
node_t *node = alloc_node();
|
node_t *node = alloc_node();
|
||||||
node->type = INT;
|
node->type = INT;
|
||||||
node->value.int_literal = literal;
|
node->value.int_literal = literal;
|
||||||
|
node->result = 1;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,6 +140,88 @@ int evaluate_expression(node_t *root, fieldset_t *fields) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int evaluate_expression_fast(node_t *root, fieldset_t *fields) {
|
||||||
|
stack_t* s;
|
||||||
|
node_t* node;
|
||||||
|
if (!root) return 1;
|
||||||
|
s = alloc_stack(16); /* XXX Find a way to guess/know this better */
|
||||||
|
root->evaluated = 0;
|
||||||
|
stack_push(s, root);
|
||||||
|
int result = 1;
|
||||||
|
while (!stack_is_empty(s) && result) {
|
||||||
|
node = (node_t *) stack_peek(s);
|
||||||
|
if (node->type != OP) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (node->value.op == AND) {
|
||||||
|
if (!node->right_child->evaluated) {
|
||||||
|
stack_push(s, node->right_child);
|
||||||
|
}
|
||||||
|
if (!node->left_child->evaluated) {
|
||||||
|
stack_push(s, node->left_child);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
stack_pop(s);
|
||||||
|
if (!(node->left_child->result && node->right_child->result)) {
|
||||||
|
node->evaluated = 1;
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
node->left_child->evaluated = 0;
|
||||||
|
node->right_child->evaluated = 0;
|
||||||
|
} else if (node->value.op == OR) {
|
||||||
|
if (!node->right_child->evaluated) {
|
||||||
|
stack_push(s, node->right_child);
|
||||||
|
}
|
||||||
|
if (!node->left_child->evaluated) {
|
||||||
|
stack_push(s, node->left_child);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
stack_pop(s);
|
||||||
|
if (!(node->left_child->result || node->right_child->result)) {
|
||||||
|
node->evaluated = 1;
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
node->left_child->evaluated = 0;
|
||||||
|
node->right_child->evaluated = 0;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
stack_pop(s);
|
||||||
|
switch (node->value.op) {
|
||||||
|
case GT:
|
||||||
|
node->result = eval_gt_node(node, fields);
|
||||||
|
break;
|
||||||
|
case LT:
|
||||||
|
node->result = eval_lt_node(node, fields);
|
||||||
|
break;
|
||||||
|
case EQ:
|
||||||
|
node->result = eval_eq_node(node, fields);
|
||||||
|
break;
|
||||||
|
case NEQ:
|
||||||
|
node->result = !(eval_eq_node(node, fields));
|
||||||
|
break;
|
||||||
|
case LT_EQ:
|
||||||
|
node->result = eval_lt_eq_node(node, fields);
|
||||||
|
break;
|
||||||
|
case GT_EQ:
|
||||||
|
node->result = eval_gt_eq_node(node, fields);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
exit(-1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
node->evaluated = 1;
|
||||||
|
if (stack_is_empty(s)) {
|
||||||
|
result = node->result;
|
||||||
|
node->evaluated = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free_stack(s);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void print_expression(node_t *root) {
|
void print_expression(node_t *root) {
|
||||||
if (!root) return;
|
if (!root) return;
|
||||||
printf("%s", "( ");
|
printf("%s", "( ");
|
||||||
|
@ -23,8 +23,8 @@ struct field_id {
|
|||||||
|
|
||||||
union node_value {
|
union node_value {
|
||||||
struct field_id field;
|
struct field_id field;
|
||||||
char *string_literal;
|
|
||||||
uint64_t int_literal;
|
uint64_t int_literal;
|
||||||
|
char *string_literal;
|
||||||
enum operation op;
|
enum operation op;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -33,6 +33,8 @@ typedef struct node {
|
|||||||
struct node *right_child;
|
struct node *right_child;
|
||||||
enum node_type type;
|
enum node_type type;
|
||||||
union node_value value;
|
union node_value value;
|
||||||
|
int evaluated;
|
||||||
|
int result;
|
||||||
} node_t;
|
} node_t;
|
||||||
|
|
||||||
node_t* make_op_node(enum operation op);
|
node_t* make_op_node(enum operation op);
|
||||||
@ -45,6 +47,8 @@ node_t* make_int_node(int literal);
|
|||||||
|
|
||||||
int evaluate_expression(node_t *root, fieldset_t *fields);
|
int evaluate_expression(node_t *root, fieldset_t *fields);
|
||||||
|
|
||||||
|
int evaluate_expression_fast(node_t *root, fieldset_t *fields);
|
||||||
|
|
||||||
void print_expression(node_t *root);
|
void print_expression(node_t *root);
|
||||||
|
|
||||||
#endif /* ZMAP_TREE_H */
|
#endif /* ZMAP_TREE_H */
|
Loading…
Reference in New Issue
Block a user