Fixed grammar. Added union, types and the basic actions.
Showing
2 changed files
with
236 additions
and
32 deletions
... | @@ -3,16 +3,16 @@ | ... | @@ -3,16 +3,16 @@ |
3 | Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. | 3 | Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published by | 6 | it under the terms of the GNU Lesser General Public License as published by |
7 | the Free Software Foundation; either version 2, or (at your option) | 7 | the Free Software Foundation; either version 2, or (at your option) |
8 | any later version. | 8 | any later version. |
9 | 9 | ||
10 | This program is distributed in the hope that it will be useful, | 10 | This program is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | GNU General Public License for more details. | 13 | GNU Lesser General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU General Public License | 15 | You should have received a copy of the GNU Lesser General Public License |
16 | along with this program; if not, write to the Free Software | 16 | along with this program; if not, write to the Free Software |
17 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | 17 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ |
18 | 18 | ||
... | @@ -25,15 +25,25 @@ | ... | @@ -25,15 +25,25 @@ |
25 | #include <unistd.h> | 25 | #include <unistd.h> |
26 | #include <sys/file.h> | 26 | #include <sys/file.h> |
27 | #include <sys/stat.h> | 27 | #include <sys/stat.h> |
28 | #include <errno.h> | 28 | #include <errno.h> |
29 | #include <string.h> | ||
29 | #include <sieve.h> | 30 | #include <sieve.h> |
30 | #include <sieve-gram.h> | 31 | #include <sieve-gram.h> |
31 | 32 | ||
32 | |||
33 | char *sieve_filename; | 33 | char *sieve_filename; |
34 | int sieve_line_num; | 34 | int sieve_line_num; |
35 | ino_t sieve_source_inode; | 35 | ino_t sieve_source_inode; |
36 | 36 | ||
37 | static list_t string_list; | ||
38 | |||
39 | static int number __P ((void)); | ||
40 | static int string __P ((void)); | ||
41 | static void multiline_begin __P ((void)); | ||
42 | static void multiline_add __P ((void)); | ||
43 | static void multiline_finish __P ((void)); | ||
44 | static void ident __P((const char *text)); | ||
45 | static void sieve_include __P((void)); | ||
46 | |||
37 | #ifdef FLEX_SCANNER | 47 | #ifdef FLEX_SCANNER |
38 | #define xinput() (yyin ? getc(yyin) : EOF) | 48 | #define xinput() (yyin ? getc(yyin) : EOF) |
39 | #undef YY_INPUT | 49 | #undef YY_INPUT |
... | @@ -185,7 +195,7 @@ struct buffer_ctx { | ... | @@ -185,7 +195,7 @@ struct buffer_ctx { |
185 | static struct buffer_ctx *context_stack; | 195 | static struct buffer_ctx *context_stack; |
186 | 196 | ||
187 | static struct buffer_ctx *ctx_lookup __P((ino_t ino)); | 197 | static struct buffer_ctx *ctx_lookup __P((ino_t ino)); |
188 | static int push_source __P((char *name)); | 198 | static int push_source __P((const char *name)); |
189 | static int pop_source __P((void)); | 199 | static int pop_source __P((void)); |
190 | 200 | ||
191 | struct buffer_ctx * | 201 | struct buffer_ctx * |
... | @@ -200,7 +210,7 @@ ctx_lookup (ino_t ino) | ... | @@ -200,7 +210,7 @@ ctx_lookup (ino_t ino) |
200 | } | 210 | } |
201 | 211 | ||
202 | int | 212 | int |
203 | push_source (char *name) | 213 | push_source (const char *name) |
204 | { | 214 | { |
205 | FILE *fp; | 215 | FILE *fp; |
206 | struct buffer_ctx *ctx; | 216 | struct buffer_ctx *ctx; |
... | @@ -300,6 +310,7 @@ pop_source () | ... | @@ -300,6 +310,7 @@ pop_source () |
300 | 310 | ||
301 | WS [ \t][ \t]* | 311 | WS [ \t][ \t]* |
302 | IDENT [a-zA-Z_][a-zA-Z_0-9]+ | 312 | IDENT [a-zA-Z_][a-zA-Z_0-9]+ |
313 | SIZESUF [kKmMgG] | ||
303 | 314 | ||
304 | %% | 315 | %% |
305 | /* C-style comments */ | 316 | /* C-style comments */ |
... | @@ -320,18 +331,20 @@ elsif return ELSIF; | ... | @@ -320,18 +331,20 @@ elsif return ELSIF; |
320 | else return ELSE; | 331 | else return ELSE; |
321 | anyof return ANYOF; | 332 | anyof return ANYOF; |
322 | allof return ALLOF; | 333 | allof return ALLOF; |
323 | true return TRUE; | ||
324 | false return FALSE; | ||
325 | not return NOT; | 334 | not return NOT; |
326 | /* Other tokens */ | 335 | /* Other tokens */ |
327 | {IDENT} return IDENT; | 336 | {IDENT} { ident (yytext); return IDENT; } |
328 | :{IDENT} { return TAG; } | 337 | :{IDENT} { ident (yytext + 1); return TAG; } |
329 | 0[0-7]* { return NUMBER; } | 338 | 0[0-7]*{SIZESUF}* { return number (); } |
330 | 0x[0-9a-fA-F][0-9a-fA-F]+ { return NUMBER; } | 339 | 0x[0-9a-fA-F][0-9a-fA-F]+{SIZESUF}* { return number (); } |
331 | [1-9][0-9]* { return NUMBER; } | 340 | [1-9][0-9]*{SIZESUF}* { return number (); } |
332 | \"[^"\n]*\" { return STRING; } | 341 | \"[^"\n]*\" { return string (); } |
333 | text: { BEGIN(ML); } | 342 | text: { BEGIN(ML); multiline_begin (); } |
334 | <ML>.[ \t]*\n { BEGIN(INITIAL); sieve_line_num++; return MULTILINE; } | 343 | <ML>.[ \t]*\n { BEGIN(INITIAL); |
344 | sieve_line_num++; | ||
345 | multiline_add (); | ||
346 | multiline_finish (); | ||
347 | return MULTILINE; } | ||
335 | <ML>.*\n { sieve_line_num++; } | 348 | <ML>.*\n { sieve_line_num++; } |
336 | {WS} ; | 349 | {WS} ; |
337 | \n { sieve_line_num++; } | 350 | \n { sieve_line_num++; } |
... | @@ -394,5 +407,107 @@ sieve_open_source (const char *name) | ... | @@ -394,5 +407,107 @@ sieve_open_source (const char *name) |
394 | return push_source (name); | 407 | return push_source (name); |
395 | } | 408 | } |
396 | 409 | ||
410 | int | ||
411 | number () | ||
412 | { | ||
413 | char *p; | ||
414 | yylval.number = strtol (yytext, &p, 0); | ||
415 | switch (*p) | ||
416 | { | ||
417 | case 'k': | ||
418 | case 'K': | ||
419 | yylval.number *= 1024L; | ||
420 | break; | ||
421 | |||
422 | case 'm': | ||
423 | case 'M': | ||
424 | yylval.number *= 1024*1024L; | ||
425 | break; | ||
426 | |||
427 | case 'g': | ||
428 | case 'G': | ||
429 | yylval.number *= 1024*1024*1024L; | ||
430 | } | ||
431 | return NUMBER; | ||
432 | } | ||
433 | |||
434 | int | ||
435 | string () | ||
436 | { | ||
437 | yylval.string = sieve_alloc (yyleng - 1); | ||
438 | memcpy (yylval.string, yytext + 1, yyleng - 2); | ||
439 | yylval.string[yyleng - 2] = 0; | ||
440 | return STRING; | ||
441 | } | ||
442 | |||
443 | void | ||
444 | multiline_add () | ||
445 | { | ||
446 | char *s = strdup (yytext); | ||
447 | if (!s) | ||
448 | { | ||
449 | yyerror ("not enough memory"); | ||
450 | exit (1); | ||
451 | } | ||
452 | list_append (string_list, s); | ||
453 | } | ||
454 | |||
455 | void | ||
456 | multiline_begin () | ||
457 | { | ||
458 | int status; | ||
459 | |||
460 | if (string_list) | ||
461 | sieve_slist_destroy (&string_list); | ||
462 | status = list_create (&string_list); | ||
463 | if (status) | ||
464 | { | ||
465 | sieve_error ("list_create: %s", mu_errstring (status)); | ||
466 | exit (1); | ||
467 | } | ||
468 | } | ||
469 | |||
470 | void | ||
471 | multiline_finish () | ||
472 | { | ||
473 | iterator_t itr; | ||
474 | int length = 0; | ||
475 | char *p; | ||
397 | 476 | ||
477 | if (!string_list || iterator_create (&itr, string_list)) | ||
478 | return; | ||
398 | 479 | ||
480 | /* Count number of characters in the multiline */ | ||
481 | for (iterator_first (itr); !iterator_is_done (itr); iterator_next (itr)) | ||
482 | { | ||
483 | char *s; | ||
484 | iterator_current (itr, (void **)&s); | ||
485 | length += strlen (s); | ||
486 | } | ||
487 | |||
488 | /* Copy the contents */ | ||
489 | yylval.string = sieve_alloc (length + 1); | ||
490 | p = yylval.string; | ||
491 | for (iterator_first (itr); !iterator_is_done (itr); iterator_next (itr)) | ||
492 | { | ||
493 | char *s; | ||
494 | iterator_current (itr, (void **)&s); | ||
495 | strcpy (p, s); | ||
496 | p += strlen (s); | ||
497 | free (s); | ||
498 | } | ||
499 | *p = 0; | ||
500 | iterator_destroy (&itr); | ||
501 | list_destroy (&string_list); | ||
502 | } | ||
503 | |||
504 | void | ||
505 | ident (const char *text) | ||
506 | { | ||
507 | yylval.string = strdup (text); | ||
508 | if (!yylval.string) | ||
509 | { | ||
510 | yyerror ("not enough memory"); | ||
511 | exit (1); | ||
512 | } | ||
513 | } | ... | ... |
... | @@ -3,16 +3,16 @@ | ... | @@ -3,16 +3,16 @@ |
3 | Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. | 3 | Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published by | 6 | it under the terms of the GNU Lesser General Public License as published by |
7 | the Free Software Foundation; either version 2, or (at your option) | 7 | the Free Software Foundation; either version 2, or (at your option) |
8 | any later version. | 8 | any later version. |
9 | 9 | ||
10 | This program is distributed in the hope that it will be useful, | 10 | This program is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | GNU General Public License for more details. | 13 | GNU Lesser General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU General Public License | 15 | You should have received a copy of the GNU Lesser General Public License |
16 | along with this program; if not, write to the Free Software | 16 | along with this program; if not, write to the Free Software |
17 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | 17 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ |
18 | 18 | ||
... | @@ -20,13 +20,32 @@ | ... | @@ -20,13 +20,32 @@ |
20 | # include <config.h> | 20 | # include <config.h> |
21 | #endif | 21 | #endif |
22 | #include <stdio.h> | 22 | #include <stdio.h> |
23 | #include <stdlib.h> | ||
23 | #include <assert.h> | 24 | #include <assert.h> |
24 | #include <sieve.h> | 25 | #include <sieve.h> |
25 | |||
26 | %} | 26 | %} |
27 | 27 | ||
28 | %token IDENT TAG NUMBER STRING MULTILINE | 28 | %union { |
29 | %token REQUIRE IF ELSIF ELSE ANYOF ALLOF TRUE FALSE NOT | 29 | char *string; |
30 | long number; | ||
31 | sieve_instr_t instr; | ||
32 | sieve_value_t *value; | ||
33 | list_t list; | ||
34 | struct { | ||
35 | char *ident; | ||
36 | list_t args; | ||
37 | } command; | ||
38 | } | ||
39 | |||
40 | %token <string> IDENT TAG | ||
41 | %token <number> NUMBER | ||
42 | %token <string> STRING MULTILINE | ||
43 | %token REQUIRE IF ELSIF ELSE ANYOF ALLOF NOT | ||
44 | |||
45 | %type <value> arg | ||
46 | %type <list> slist stringlist arglist maybe_arglist | ||
47 | %type <command> command | ||
48 | |||
30 | %% | 49 | %% |
31 | 50 | ||
32 | input : /* empty */ | 51 | input : /* empty */ |
... | @@ -38,6 +57,10 @@ list : statement | ... | @@ -38,6 +57,10 @@ list : statement |
38 | ; | 57 | ; |
39 | 58 | ||
40 | statement : REQUIRE stringlist ';' | 59 | statement : REQUIRE stringlist ';' |
60 | { | ||
61 | sieve_require ($2); | ||
62 | sieve_slist_destroy ($2); | ||
63 | } | ||
41 | | action ';' | 64 | | action ';' |
42 | | IF cond block maybe_elsif maybe_else | 65 | | IF cond block maybe_elsif maybe_else |
43 | ; | 66 | ; |
... | @@ -58,8 +81,8 @@ block : '{' list '}' | ... | @@ -58,8 +81,8 @@ block : '{' list '}' |
58 | ; | 81 | ; |
59 | 82 | ||
60 | 83 | ||
61 | testlist : test | 84 | testlist : cond |
62 | | testlist ',' test | 85 | | testlist ',' cond |
63 | ; | 86 | ; |
64 | 87 | ||
65 | cond : test | 88 | cond : test |
... | @@ -68,37 +91,101 @@ cond : test | ... | @@ -68,37 +91,101 @@ cond : test |
68 | | NOT cond | 91 | | NOT cond |
69 | ; | 92 | ; |
70 | 93 | ||
71 | test : FALSE | 94 | test : command |
72 | | TRUE | 95 | { |
73 | | command | 96 | sieve_register_t *reg = sieve_test_lookup ($1.ident); |
97 | if (!reg) | ||
98 | sieve_error ("%s:%d: unknown test: %s", | ||
99 | sieve_filename, sieve_line_num, | ||
100 | $1.ident); | ||
101 | else if (!reg->required) | ||
102 | sieve_error ("%s:%d: test `%s' has not been required", | ||
103 | sieve_filename, sieve_line_num, | ||
104 | $1.ident); | ||
105 | /*free unneeded memory */ | ||
106 | } | ||
74 | ; | 107 | ; |
75 | 108 | ||
76 | command : IDENT maybe_arglist | 109 | command : IDENT maybe_arglist |
110 | { | ||
111 | $$.ident = $1; | ||
112 | $$.args = $2; | ||
113 | } | ||
77 | ; | 114 | ; |
78 | 115 | ||
79 | action : command | 116 | action : command |
117 | { | ||
118 | sieve_register_t *reg = sieve_action_lookup ($1.ident); | ||
119 | if (!reg) | ||
120 | sieve_error ("%s:%d: unknown action: %s", | ||
121 | sieve_filename, sieve_line_num, | ||
122 | $1.ident); | ||
123 | else if (!reg->required) | ||
124 | sieve_error ("%s:%d: action `%s' has not been required", | ||
125 | sieve_filename, sieve_line_num, | ||
126 | $1.ident); | ||
127 | /*free unneeded memory */ | ||
128 | } | ||
80 | ; | 129 | ; |
81 | 130 | ||
82 | maybe_arglist: /* empty */ | 131 | maybe_arglist: /* empty */ |
132 | { | ||
133 | $$ = NULL; | ||
134 | } | ||
83 | | arglist | 135 | | arglist |
84 | ; | 136 | ; |
85 | 137 | ||
86 | arglist : arg | 138 | arglist : arg |
139 | { | ||
140 | list_create (&$$); | ||
141 | list_append ($$, &$1); | ||
142 | } | ||
87 | | arglist arg | 143 | | arglist arg |
144 | { | ||
145 | list_append ($1, &$2); | ||
146 | $$ = $1; | ||
147 | } | ||
88 | ; | 148 | ; |
89 | 149 | ||
90 | arg : stringlist | 150 | arg : stringlist |
151 | { | ||
152 | $$ = sieve_value_create (SVT_STRING_LIST, $1); | ||
153 | } | ||
91 | | MULTILINE | 154 | | MULTILINE |
155 | { | ||
156 | $$ = sieve_value_create (SVT_STRING, $1); | ||
157 | } | ||
92 | | NUMBER | 158 | | NUMBER |
159 | { | ||
160 | $$ = sieve_value_create (SVT_NUMBER, &$1); | ||
161 | } | ||
93 | | TAG | 162 | | TAG |
163 | { | ||
164 | $$ = sieve_value_create (SVT_TAG, $1); | ||
165 | } | ||
94 | ; | 166 | ; |
95 | 167 | ||
96 | stringlist : STRING | 168 | stringlist : STRING |
169 | { | ||
170 | list_create (&$$); | ||
171 | list_append ($$, $1); | ||
172 | } | ||
97 | | '[' slist ']' | 173 | | '[' slist ']' |
174 | { | ||
175 | $$ = $2; | ||
176 | } | ||
98 | ; | 177 | ; |
99 | 178 | ||
100 | slist : STRING | 179 | slist : STRING |
180 | { | ||
181 | list_create (&$$); | ||
182 | list_append ($$, $1); | ||
183 | } | ||
101 | | slist ',' STRING | 184 | | slist ',' STRING |
185 | { | ||
186 | list_append ($1, $3); | ||
187 | $$ = $1; | ||
188 | } | ||
102 | ; | 189 | ; |
103 | 190 | ||
104 | %% | 191 | %% |
... | @@ -106,13 +193,15 @@ slist : STRING | ... | @@ -106,13 +193,15 @@ slist : STRING |
106 | int | 193 | int |
107 | yyerror (char *s) | 194 | yyerror (char *s) |
108 | { | 195 | { |
109 | fprintf (stderr, "%s:%d: ", sieve_filename, sieve_line_num); | 196 | sieve_error ("%s:%d: %s", sieve_filename, sieve_line_num, s); |
110 | fprintf (stderr, "%s\n", s); | 197 | return 0; |
111 | } | 198 | } |
112 | 199 | ||
113 | int | 200 | int |
114 | sieve_parse (const char *name) | 201 | sieve_parse (const char *name) |
115 | { | 202 | { |
203 | sieve_register_standard_actions (); | ||
204 | sieve_register_standard_tests (); | ||
116 | sieve_open_source (name); | 205 | sieve_open_source (name); |
117 | return yyparse (); | 206 | return yyparse (); |
118 | } | 207 | } | ... | ... |
-
Please register or sign in to post a comment