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);
|
||||
}
|
||||
|
||||
void push(stack_t* stack, void* elt)
|
||||
void stack_push(stack_t* stack, void* elt)
|
||||
{
|
||||
if (stack->cur_size == stack->max_size) {
|
||||
stack->max_size *= 2;
|
||||
@ -33,8 +33,17 @@ void push(stack_t* stack, void* 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];
|
||||
return res;
|
||||
--stack->cur_size;
|
||||
}
|
||||
|
||||
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);
|
||||
void free_stack(stack_t* stack);
|
||||
|
||||
void push(stack_t* stack, void* elt);
|
||||
void* pop(stack_t* stack);
|
||||
void stack_push(stack_t* stack, void* elt);
|
||||
void stack_pop(stack_t* stack);
|
||||
void* stack_peek(stack_t* stack);
|
||||
|
||||
int stack_is_empty(stack_t* stack);
|
||||
|
||||
#endif /* ZMAP_STACK_H */
|
@ -1,6 +1,8 @@
|
||||
#include "expression.h"
|
||||
#include "fieldset.H"
|
||||
#include "fieldset.h"
|
||||
|
||||
|
||||
#include "../lib/stack.h"
|
||||
#include "../lib/xalloc.h"
|
||||
|
||||
/* Static helper functions */
|
||||
@ -83,6 +85,7 @@ node_t* make_field_node(char *fieldname)
|
||||
node_t *node = alloc_node();
|
||||
node->type = FIELD;
|
||||
node->value.field.fieldname = fieldname;
|
||||
node->result = 1;
|
||||
return node;
|
||||
}
|
||||
|
||||
@ -91,6 +94,7 @@ node_t* make_string_node(char *literal)
|
||||
node_t *node = alloc_node();
|
||||
node->type = STRING;
|
||||
node->value.string_literal = literal;
|
||||
node->result = 1;
|
||||
return node;
|
||||
}
|
||||
|
||||
@ -99,6 +103,7 @@ node_t* make_int_node(int literal)
|
||||
node_t *node = alloc_node();
|
||||
node->type = INT;
|
||||
node->value.int_literal = literal;
|
||||
node->result = 1;
|
||||
return node;
|
||||
}
|
||||
|
||||
@ -135,6 +140,88 @@ int evaluate_expression(node_t *root, fieldset_t *fields) {
|
||||
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) {
|
||||
if (!root) return;
|
||||
printf("%s", "( ");
|
||||
|
@ -23,8 +23,8 @@ struct field_id {
|
||||
|
||||
union node_value {
|
||||
struct field_id field;
|
||||
char *string_literal;
|
||||
uint64_t int_literal;
|
||||
char *string_literal;
|
||||
enum operation op;
|
||||
};
|
||||
|
||||
@ -33,6 +33,8 @@ typedef struct node {
|
||||
struct node *right_child;
|
||||
enum node_type type;
|
||||
union node_value value;
|
||||
int evaluated;
|
||||
int result;
|
||||
} node_t;
|
||||
|
||||
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_fast(node_t *root, fieldset_t *fields);
|
||||
|
||||
void print_expression(node_t *root);
|
||||
|
||||
#endif /* ZMAP_TREE_H */
|
Loading…
Reference in New Issue
Block a user