diff options
Diffstat (limited to 'libsieve/sieve.y')
-rw-r--r-- | libsieve/sieve.y | 115 |
1 files changed, 102 insertions, 13 deletions
diff --git a/libsieve/sieve.y b/libsieve/sieve.y index 1341a5c0c..0fb8408d7 100644 --- a/libsieve/sieve.y +++ b/libsieve/sieve.y @@ -3,16 +3,16 @@ Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by + it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + GNU Lesser General Public License for more details. - You should have received a copy of the GNU General Public License + You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ @@ -20,13 +20,32 @@ # include <config.h> #endif #include <stdio.h> +#include <stdlib.h> #include <assert.h> #include <sieve.h> - %} -%token IDENT TAG NUMBER STRING MULTILINE -%token REQUIRE IF ELSIF ELSE ANYOF ALLOF TRUE FALSE NOT +%union { + char *string; + long number; + sieve_instr_t instr; + sieve_value_t *value; + list_t list; + struct { + char *ident; + list_t args; + } command; +} + +%token <string> IDENT TAG +%token <number> NUMBER +%token <string> STRING MULTILINE +%token REQUIRE IF ELSIF ELSE ANYOF ALLOF NOT + +%type <value> arg +%type <list> slist stringlist arglist maybe_arglist +%type <command> command + %% input : /* empty */ @@ -38,6 +57,10 @@ list : statement ; statement : REQUIRE stringlist ';' + { + sieve_require ($2); + sieve_slist_destroy ($2); + } | action ';' | IF cond block maybe_elsif maybe_else ; @@ -58,8 +81,8 @@ block : '{' list '}' ; -testlist : test - | testlist ',' test +testlist : cond + | testlist ',' cond ; cond : test @@ -68,37 +91,101 @@ cond : test | NOT cond ; -test : FALSE - | TRUE - | command +test : command + { + sieve_register_t *reg = sieve_test_lookup ($1.ident); + if (!reg) + sieve_error ("%s:%d: unknown test: %s", + sieve_filename, sieve_line_num, + $1.ident); + else if (!reg->required) + sieve_error ("%s:%d: test `%s' has not been required", + sieve_filename, sieve_line_num, + $1.ident); + /*free unneeded memory */ + } ; command : IDENT maybe_arglist + { + $$.ident = $1; + $$.args = $2; + } ; action : command + { + sieve_register_t *reg = sieve_action_lookup ($1.ident); + if (!reg) + sieve_error ("%s:%d: unknown action: %s", + sieve_filename, sieve_line_num, + $1.ident); + else if (!reg->required) + sieve_error ("%s:%d: action `%s' has not been required", + sieve_filename, sieve_line_num, + $1.ident); + /*free unneeded memory */ + } ; maybe_arglist: /* empty */ + { + $$ = NULL; + } | arglist ; arglist : arg + { + list_create (&$$); + list_append ($$, &$1); + } | arglist arg + { + list_append ($1, &$2); + $$ = $1; + } ; arg : stringlist + { + $$ = sieve_value_create (SVT_STRING_LIST, $1); + } | MULTILINE + { + $$ = sieve_value_create (SVT_STRING, $1); + } | NUMBER + { + $$ = sieve_value_create (SVT_NUMBER, &$1); + } | TAG + { + $$ = sieve_value_create (SVT_TAG, $1); + } ; stringlist : STRING + { + list_create (&$$); + list_append ($$, $1); + } | '[' slist ']' + { + $$ = $2; + } ; slist : STRING + { + list_create (&$$); + list_append ($$, $1); + } | slist ',' STRING + { + list_append ($1, $3); + $$ = $1; + } ; %% @@ -106,13 +193,15 @@ slist : STRING int yyerror (char *s) { - fprintf (stderr, "%s:%d: ", sieve_filename, sieve_line_num); - fprintf (stderr, "%s\n", s); + sieve_error ("%s:%d: %s", sieve_filename, sieve_line_num, s); + return 0; } int sieve_parse (const char *name) { + sieve_register_standard_actions (); + sieve_register_standard_tests (); sieve_open_source (name); return yyparse (); } |