I assume you're referring to the confusing text that includes things
like "else" being a separate command, and "'elsif' must only follow
'if'" which is obviously incorrect. OTOH I think the incorrectness
there is not due to the documentation method, but in errors in the
description. i.e. the description could be corrected.
IMHO, the documentation method asks for such problems. When I first
read the paragraph, it sounded a little odd, but I probably assumed
that it was meant to describe the common "if elsif else" structure.
Later, when I worked on code and tried to find the grammar for the
structure, the mistake became obvious.
if-command = "if" test block *( "elsif" test block ) [ else block ]
is short and (hopefully:) correct.
closer when "else" is quoted :-)
Oops! Thanks for spotting that, the next Exim release will have a
However there's still the issue of extensions: the syntax varies
depending on what extensions are enabled. Each extension can probably
be specified via BNF, but how would you address optional grammar (i.e.
as distinct from grammar that includes optional elements)?
Now I see your point: Each implementation contains the base grammar
plus all extensions, but an implementation that contains new tests
had to add the "test" rule. How about another ABNF extension, e.g.
rule = a
rule /= b
is equivalent to
rule = a / b
The RFC would then contain:
test = address-test / allof-test / anyof-test / exists-test
/ false-test / true-test / header-test / not-test
/ size-test / envelope-test
and extensions could specify:
test /= extension-test
If you took the rules from the RFC plus the rules for all extensions,
you had a correct grammar for the implementation.
(That's not as thorny as self-modifying grammar of course.. a la
typedef in C)
Types are usually checked at the semantic layer, probably for just that
reason. Any set of extensions plus the base grammar yields a constant
grammar, so no problem there. The generic Sieve grammar generates a
larger language than any implementation grammar, but it is only used to
ensure that extensions fit into Sieve.
Do you think that SIEVE is unimplementable based on RFC3028?
I had to ask Tim several times for details. "Unimplementable" is too
strong; I think of it as "incomplete in minor aspects". Two examples
from the same README:
Strings Containing Header Names
RFC 3028 does not specify what happens if a string denoting a header
field does not contain a valid header name, e.g. it contains a colon.
This implementation generates an error instead of ignoring the header
field in order to ease script debugging, which fits in the common
picture of Sieve.
Exists Test With Empty List Of Headers
The "exists" test only suceeds if all specified headers exist. RFC 3028
does not explicitly specify what happens on an empty list of headers.
This implementation evaluates that condition with true, interpreting
the RFC in a strict sense.
The above can but guessed by common sense, but a specification should not
leave anything to guess. These things are clearly semantic, so again
the RFC shows how hard semantics are to describe with natural language
without leaving things out.
That's why I suggest to handle syntactic issues at the syntactic level:
Easy to use formal specifications exist, that don't leave anything
to guess, plus it makes an implementation easier.