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 ...@@ -144,6 +144,7 @@ enum mu_sieve_node_type
144 mu_sieve_node_anyof, 144 mu_sieve_node_anyof,
145 mu_sieve_node_allof, 145 mu_sieve_node_allof,
146 mu_sieve_node_not, 146 mu_sieve_node_not,
147 mu_sieve_node_end,
147 }; 148 };
148 149
149 struct mu_sieve_node 150 struct mu_sieve_node
...@@ -171,6 +172,11 @@ struct mu_sieve_node ...@@ -171,6 +172,11 @@ struct mu_sieve_node
171 } v; 172 } v;
172 }; 173 };
173 174
175 struct mu_sieve_node_list
176 {
177 struct mu_sieve_node *head, *tail;
178 };
179
174 int mu_sieve_yyerror (const char *s); 180 int mu_sieve_yyerror (const char *s);
175 int mu_sieve_yylex (void); 181 int mu_sieve_yylex (void);
176 182
......
...@@ -33,6 +33,10 @@ static struct mu_sieve_node *sieve_tree; ...@@ -33,6 +33,10 @@ static struct mu_sieve_node *sieve_tree;
33 static struct mu_sieve_node *node_alloc (enum mu_sieve_node_type, 33 static struct mu_sieve_node *node_alloc (enum mu_sieve_node_type,
34 struct mu_locus_range *); 34 struct mu_locus_range *);
35 35
36 static void node_list_add (struct mu_sieve_node_list *list,
37 struct mu_sieve_node *node);
38
39
36 #define YYLLOC_DEFAULT(Current, Rhs, N) \ 40 #define YYLLOC_DEFAULT(Current, Rhs, N) \
37 do \ 41 do \
38 { \ 42 { \
...@@ -86,10 +90,7 @@ static struct mu_sieve_node *node_alloc (enum mu_sieve_node_type, ...@@ -86,10 +90,7 @@ static struct mu_sieve_node *node_alloc (enum mu_sieve_node_type,
86 size_t first; 90 size_t first;
87 size_t count; 91 size_t count;
88 } command; 92 } command;
89 struct node_list 93 struct mu_sieve_node_list node_list;
90 {
91 struct mu_sieve_node *head, *tail;
92 } node_list;
93 struct mu_sieve_node *node; 94 struct mu_sieve_node *node;
94 } 95 }
95 96
...@@ -113,6 +114,11 @@ input : /* empty */ ...@@ -113,6 +114,11 @@ input : /* empty */
113 } 114 }
114 | list 115 | list
115 { 116 {
117 struct mu_locus_range lr;
118
119 lr.beg = lr.end = @1.end;
120
121 node_list_add (&$1, node_alloc (mu_sieve_node_end, &lr));
116 sieve_tree = $1.head; 122 sieve_tree = $1.head;
117 } 123 }
118 ; 124 ;
...@@ -123,15 +129,7 @@ list : statement ...@@ -123,15 +129,7 @@ list : statement
123 } 129 }
124 | list statement 130 | list statement
125 { 131 {
126 if ($2) 132 node_list_add (&$1, $2);
127 {
128 $2->prev = $1.tail;
129 if ($1.tail)
130 $1.tail->next = $2;
131 else
132 $1.head = $2;
133 $1.tail = $2;
134 }
135 $$ = $1; 133 $$ = $1;
136 } 134 }
137 ; 135 ;
...@@ -403,6 +401,20 @@ yyerror (const char *s) ...@@ -403,6 +401,20 @@ yyerror (const char *s)
403 return 0; 401 return 0;
404 } 402 }
405 403
404 static void
405 node_list_add (struct mu_sieve_node_list *list, struct mu_sieve_node *node)
406 {
407 if (!node)
408 return;
409
410 node->prev = list->tail;
411 if (list->tail)
412 list->tail->next = node;
413 else
414 list->head = node;
415 list->tail = node;
416 }
417
406 static struct mu_sieve_node * 418 static struct mu_sieve_node *
407 node_alloc (enum mu_sieve_node_type type, struct mu_locus_range *lr) 419 node_alloc (enum mu_sieve_node_type type, struct mu_locus_range *lr)
408 { 420 {
...@@ -805,6 +817,21 @@ dump_node_not (mu_stream_t str, struct mu_sieve_node *node, unsigned level, ...@@ -805,6 +817,21 @@ dump_node_not (mu_stream_t str, struct mu_sieve_node *node, unsigned level,
805 node_dump (str, node->v.node, level + 1, mach); 817 node_dump (str, node->v.node, level + 1, mach);
806 } 818 }
807 819
820 /* mu_sieve_node_end */
821 static void
822 code_node_end (struct mu_sieve_machine *mach, struct mu_sieve_node *node)
823 {
824 mu_i_sv_code (mach, (sieve_op_t) (sieve_instr_t) 0);
825 }
826
827 static void
828 dump_node_end (mu_stream_t str, struct mu_sieve_node *node, unsigned level,
829 struct mu_sieve_machine *mach)
830 {
831 indent (str, level);
832 mu_stream_printf (str, "END\n");
833 }
834
808 struct node_descr 835 struct node_descr
809 { 836 {
810 void (*code_fn) (struct mu_sieve_machine *mach, struct mu_sieve_node *node); 837 void (*code_fn) (struct mu_sieve_machine *mach, struct mu_sieve_node *node);
...@@ -831,6 +858,7 @@ static struct node_descr node_descr[] = { ...@@ -831,6 +858,7 @@ static struct node_descr node_descr[] = {
831 free_node_x_of, dump_node_x_of }, 858 free_node_x_of, dump_node_x_of },
832 [mu_sieve_node_not] = { code_node_not, optimize_node_not, 859 [mu_sieve_node_not] = { code_node_not, optimize_node_not,
833 free_node_not, dump_node_not }, 860 free_node_not, dump_node_not },
861 [mu_sieve_node_end] = { code_node_end, NULL, NULL, dump_node_end }
834 }; 862 };
835 863
836 static void 864 static void
......