Commit bbd1fa8b bbd1fa8b0ad735fda363256cc77a0f6eb32f5697 by Sergey Poznyakoff

sieve: add a locus indicating end of input

The new node type mu_sieve_node_end is introduced to explicitly
mark end of the parse tree.  When generating code, this node
triggers insertion of _mu_i_sv_instr_source/_mu_i_sv_instr_line
before the end of code marker.  This, in turn, ensures that a
correct location is reported for implicit keep, if logging is
enabled.

* libmu_sieve/sieve-priv.h (mu_sieve_node_end): New node type.
(mu_sieve_node_list): New type (from struct node_list in sieve.y)
* libmu_sieve/sieve.y (node_list_add): New function.
(input production): Add mu_sieve_node_end at the end of the tree.
1 parent ee60e76b
......@@ -144,6 +144,7 @@ enum mu_sieve_node_type
mu_sieve_node_anyof,
mu_sieve_node_allof,
mu_sieve_node_not,
mu_sieve_node_end,
};
struct mu_sieve_node
......@@ -171,6 +172,11 @@ struct mu_sieve_node
} v;
};
struct mu_sieve_node_list
{
struct mu_sieve_node *head, *tail;
};
int mu_sieve_yyerror (const char *s);
int mu_sieve_yylex (void);
......
......@@ -33,6 +33,10 @@ static struct mu_sieve_node *sieve_tree;
static struct mu_sieve_node *node_alloc (enum mu_sieve_node_type,
struct mu_locus_range *);
static void node_list_add (struct mu_sieve_node_list *list,
struct mu_sieve_node *node);
#define YYLLOC_DEFAULT(Current, Rhs, N) \
do \
{ \
......@@ -86,10 +90,7 @@ static struct mu_sieve_node *node_alloc (enum mu_sieve_node_type,
size_t first;
size_t count;
} command;
struct node_list
{
struct mu_sieve_node *head, *tail;
} node_list;
struct mu_sieve_node_list node_list;
struct mu_sieve_node *node;
}
......@@ -113,6 +114,11 @@ input : /* empty */
}
| list
{
struct mu_locus_range lr;
lr.beg = lr.end = @1.end;
node_list_add (&$1, node_alloc (mu_sieve_node_end, &lr));
sieve_tree = $1.head;
}
;
......@@ -123,15 +129,7 @@ list : statement
}
| list statement
{
if ($2)
{
$2->prev = $1.tail;
if ($1.tail)
$1.tail->next = $2;
else
$1.head = $2;
$1.tail = $2;
}
node_list_add (&$1, $2);
$$ = $1;
}
;
......@@ -403,6 +401,20 @@ yyerror (const char *s)
return 0;
}
static void
node_list_add (struct mu_sieve_node_list *list, struct mu_sieve_node *node)
{
if (!node)
return;
node->prev = list->tail;
if (list->tail)
list->tail->next = node;
else
list->head = node;
list->tail = node;
}
static struct mu_sieve_node *
node_alloc (enum mu_sieve_node_type type, struct mu_locus_range *lr)
{
......@@ -805,6 +817,21 @@ dump_node_not (mu_stream_t str, struct mu_sieve_node *node, unsigned level,
node_dump (str, node->v.node, level + 1, mach);
}
/* mu_sieve_node_end */
static void
code_node_end (struct mu_sieve_machine *mach, struct mu_sieve_node *node)
{
mu_i_sv_code (mach, (sieve_op_t) (sieve_instr_t) 0);
}
static void
dump_node_end (mu_stream_t str, struct mu_sieve_node *node, unsigned level,
struct mu_sieve_machine *mach)
{
indent (str, level);
mu_stream_printf (str, "END\n");
}
struct node_descr
{
void (*code_fn) (struct mu_sieve_machine *mach, struct mu_sieve_node *node);
......@@ -831,6 +858,7 @@ static struct node_descr node_descr[] = {
free_node_x_of, dump_node_x_of },
[mu_sieve_node_not] = { code_node_not, optimize_node_not,
free_node_not, dump_node_not },
[mu_sieve_node_end] = { code_node_end, NULL, NULL, dump_node_end }
};
static void
......