Re: I-D ACTION:draft-ietf-sieve-3028bis-04.txt

Michael Haardt <michael@freenet-ag.de> Fri, 22 July 2005 08:34 UTC

Received: from above.proper.com (localhost.vpnc.org [127.0.0.1]) by above.proper.com (8.12.11/8.12.9) with ESMTP id j6M8Yp1C027834; Fri, 22 Jul 2005 01:34:51 -0700 (PDT) (envelope-from owner-ietf-mta-filters@mail.imc.org)
Received: (from majordom@localhost) by above.proper.com (8.12.11/8.12.9/Submit) id j6M8YpSq027833; Fri, 22 Jul 2005 01:34:51 -0700 (PDT)
X-Authentication-Warning: above.proper.com: majordom set sender to owner-ietf-mta-filters@mail.imc.org using -f
Received: from mout0.freenet.de (mout0.freenet.de [194.97.50.131]) by above.proper.com (8.12.11/8.12.9) with ESMTP id j6M8YnlH027819 for <ietf-mta-filters@imc.org>; Fri, 22 Jul 2005 01:34:50 -0700 (PDT) (envelope-from michael@freenet-ag.de)
Received: from [194.97.50.138] (helo=mx0.freenet.de) by mout0.freenet.de with esmtpa (Exim 4.52) id 1DvszZ-0000JQ-E8 for ietf-mta-filters@imc.org; Fri, 22 Jul 2005 10:34:49 +0200
Received: from nostromo.freenet-ag.de ([194.97.7.6]) by mx0.freenet.de with esmtps (TLSv1:AES256-SHA:256) (Exim 4.52 #3) id 1DvszZ-0001Xm-83 for ietf-mta-filters@imc.org; Fri, 22 Jul 2005 10:34:49 +0200
Received: from michael by nostromo.freenet-ag.de with local (ID michael) (Exim 4.52 #9) id 1DvszW-0002Ws-Sb for ietf-mta-filters@imc.org; Fri, 22 Jul 2005 10:34:46 +0200
Date: Fri, 22 Jul 2005 10:34:46 +0200
From: Michael Haardt <michael@freenet-ag.de>
To: ietf-mta-filters@imc.org
Subject: Re: I-D ACTION:draft-ietf-sieve-3028bis-04.txt
Message-ID: <20050722083446.GC9588@nostromo.freenet-ag.de>
References: <E1DvWPE-0001o1-Ca@nostromo.freenet-ag.de> <42DFD537.6070904@psaux.com> <01LQW3139DEO000092@mauve.mrochek.com>
Mime-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Disposition: inline
In-Reply-To: <01LQW3139DEO000092@mauve.mrochek.com>
User-Agent: Mutt/1.5.6i
Sender: owner-ietf-mta-filters@mail.imc.org
Precedence: bulk
List-Archive: <http://www.imc.org/ietf-mta-filters/mail-archive/>
List-ID: <ietf-mta-filters.imc.org>
List-Unsubscribe: <mailto:ietf-mta-filters-request@imc.org?body=unsubscribe>

On Thu, Jul 21, 2005 at 02:43:13PM -0700, Ned Freed wrote:
> As to the idea of actually using formal grammar for this sort of thing, been
> there, done that, bad idea. Having been on the receiving end of questions 
> for
> RFC 1521 issues, I can tell you that using subgrammars (or whatever the 
> correct
> term for this is) creates about 10X more confusion than clarity.

Too bad, but I guess a paragraph like

  All Sieve commands, including extensions, MUST be words of the following
  generic grammar with the start symbol "start".  They SHOULD be specified   
  using a specific grammar, though.

is not going to help most people a lot, despite specifying *exactly*
the same as RFC 3028.

> The simple fact of the matter is that people just aren't that good at
> extracting usage information from ABNF. THis isn't to say we should not 
> have a
> precise definition of the overall syntax in ABNF - implementors at the very
> least need it - but using ABNF to provide usage information' goes too far. 

I built a full ABNF for my implementation to move as much as possible
from semantic analysis to syntactic analysis, but that is just one
possible approach.  I append my implementation notes, but they are
not meant as suggested change to the draft, but to illustrate the step
between RFC 3028 and actual code.  The { } specification is pretty
weak and just "worked for me".

I am pretty sure others use the generic ABNF for syntactic analysis,
following straightforward RFC 3028.  That is well possible and it does
not need a specific grammar.

> The
> form we use now is simple, easy to read, and gets the job done.

Once "Syntax" is replaced by "Usage", it is fine with me and I shall
agree to the next released draft.

Michael
----------------------------------------------------------------------
The grammar is specified in ABNF with two extensions to describe tagged
arguments that can be reordered and grammar extensions: { } denotes a
sequence of symbols that may appear in any order.  Example:

  options = a b c
  start =  { options }

is equivalent to:

  start =  ( a b c ) / ( a c b ) / ( b a c ) / ( b c a ) / ( c a b ) / ( c b a )

The symbol =) is used to append to a rule:

  start =  a
  start =) b

is equivalent to

  start =  a b

All Sieve commands, including extensions, MUST be words of the following
generic grammar with the start symbol "start".  They SHOULD be specified
using a specific grammar, though.

   argument        = string-list / number / tag
   arguments       = *argument [test / test-list]
   block           = "{" commands "}"
   commands        = *command
   string          = quoted-string / multi-line
   string-list     = "[" string *("," string) "]" / string
   test            = identifier arguments
   test-list       = "(" test *("," test) ")"
   command         = identifier arguments ( ";" / block )
   start           = command

The basic Sieve commands are specified using the following grammar, which
language is a subset of the generic grammar above.  The start symbol is
"start".

  address-part     =  ":localpart" / ":domain" / ":all"
  comparator       =  ":comparator" string
  match-type       =  ":is" / ":contains" / ":matches"
  string           =  quoted-string / multi-line
  string-list      =  "[" string *("," string) "]" / string
  address-test     =  "address" { [address-part] [comparator] [match-type] }
                      string-list string-list
  test-list        =  "(" test *("," test) ")"
  allof-test       =  "allof" test-list
  anyof-test       =  "anyof" test-list
  exists-test      =  "exists" string-list
  false-test       =  "false"
  true=test        =  "true"
  header-test      =  "header" { [comparator] [match-type] }
                      string-list string-list
  not-test         =  "not" test
  relop            =  ":over" / ":under"
  size-test        =  "size" relop number
  block            =  "{" commands "}"
  if-command       =  "if" test block *( "elsif" test block ) [ "else" block ]
  stop-command     =  "stop" { stop-options } ";"
  stop-options     =
  keep-command     =  "keep" { keep-options } ";"
  keep-options     =
  discard-command  =  "discard" { discard-options } ";"
  discard-options  =
  redirect-command =  "redirect" { redirect-options } string ";"
  redirect-options =
  require-command  =  "require" { require-options } string-list ";"
  require-options  =
  test             =  address-test / allof-test / anyof-test / exists-test
                      / false-test / true-test / header-test / not-test
                      / size-test
  command          =  if-command / stop-command / keep-command
                      / discard-command / redirect-command
  commands         =  *command
  start            =  *require-command commands

The extensions "envelope" and "fileinto" are specified using the following
grammar extension.

  envelope-test    =  "envelope" { [comparator] [address-part] [match-type] }
                      string-list string-list
  test             =/ envelope-test

  fileinto-command =  "fileinto" { fileinto-options } string ";"
  fileinto-options =
  command          =/ fileinto-command

The extension "copy" is specified as:

  fileinto-options =) ":copy"
  redirect-options =) ":copy"

And so on ...