List members,
I implemented draft 3, and felt that is was a very tight specification
with very little, if any, ambiguity. I commented on draft 4 that there
was more ambiguity related to "elsif" and "else if", tagged arguments,
and changes to way the language was specified.
Now that draft 5 is out and I am trying to update my draft 3
implementation, I still feel significant ambiguity remains.
Here are some of the issues that Tom tried to address in draft 5
and my comments...
At 04:40 PM 11/6/98 -0500, Tim Showalter wrote:
2a. Can we keep tagged arguments?
2b. Arbitrarily, I allowed tagged arguments to be in any order and freely
interspersed in commands. This was probably a mistake, but I wanted to
preserve wordings like this:
header "From" :contains "tjs"
What do people want? The dominant stated opinion is that they should
only
happen after the keyword, and that's fine with me.
Draft 5 states:
----
2.6
Tagged arguments must appear before positional arguments.
2.7.1
In order to specify what type of match is supposed to happen,
commands that support matching take optional tagged arguments
":matches", ":is", and ":contains". Commands default to using ":is"
matching.
5.5. Test header
Syntax: header <match-keyword> <header-name-list> <key-list>
The "header" test evaluates to true if the any header name matches
any key. How the match is done is described by the second argument,
which is one of the string comparison arguments discussed in section
2.6. The first argument to header, the header-name-list, is a list
of headers to get values from to be searched. The key-list is a list
of keys.
-----
The way I interpret this is the that match-keyword is optional,
therefore it must be tagged and appear before positional arguments.
The syntax in section 5.5 Test header appears to agree.
However, the description following and all the examples show the
match-keyword as the second positional argument. What seems to
be clear, is that the match-keyword is definitely optional.
So this example should be OK:
if header "From" ["coyote(_at_)desert(_dot_)org",
"coyote(_at_)hotmail(_dot_)com"]
discard;
3. Elsif was added because it removes an ambiguity in the grammar, making
"else" yet another command. This is discussed in anything that talks
about writing C parsers; "else if" is an imbiguity, and many languages
have an "elsif" as a result. I have a fairly strong preference for this.
Note that "else if" is illegal in 04.
I don't understand this. I raised the issue that there was no difference
between "elsif" and "else if". You say that "else if" is illegal, but
both draft 4 and draft 5 have examples.
You try to distinguish between them in the draft 5 example...
----
In the following example, both Message A and B are dropped.
Example: if header "from" contains "coyote" {
discard;
} elsif header ["subject"] :contains ["$$$"] {
discard;
} else {
fileinto "INBOX";
}
In the script below, when run over message A, forwards the message to
acm(_at_)frobnitzm(_dot_)edu; message B, to
postmaster(_at_)frobnitzm(_dot_)edu; any other
message is forwarded to field(_at_)frobnitzm(_dot_)edu(_dot_)
Example: if header ["From"] contains ["coyote"] {
forward "acm(_at_)frobnitzm(_dot_)edu";
} else if header "Subject" contains "$$$" {
forward "postmaster(_at_)frobnitzm(_dot_)edu";
} else {
forward "field(_at_)frobnitzm(_dot_)edu";
}
----
In that latter example, I cannot see how more than one command
block would be executed, supposedly, the advantage of "elsif".
4. The formal grammar was a major change from 03, and I have strong
reservations against changing it back. 03 had a grammar that was
over-specified, and under-permissive. Every extension required a grammar
change; this seems likely to lead to a horrible grammar when all is said
and done.
This has probably left considerable ambiguity in some other places in the
draft, but I don't beleive that's a good reason to switch back to the
previous grammar.
I think Tom was responding to my comment about the disconnect between
what formal grammar we do define, for example "string-list", and
the command syntax section, such as:
----
Syntax: header <match-keyword> <header-name-list> <key-list>
----
It is never explicitly stated that <header-name-list> and
<key-list> are in fact "string-list".
This creates ambiguity, for example from draft 5...
----
In this document, only the "if" control structure is provided. There
are three pieces to if: "if", "elsif", and "else".
Syntax: if <test> <block>
Syntax: elsif <test> <block>
Syntax: else <block>
----
In formal grammar section....
----
block = "{" commands "}"
----
If these are referring to the same "block", the it must be enclosed
by brackets { .... }. Thus daft 5 examples like:
----
4.4
Example: if size :under 1M keep; else discard;
4.7
Example: if header ["from"] contains ["idiot(_at_)frobnitzm(_dot_)edu"]
discard;
----
... are both invalid! I guess the churn in the sieve syntax
has created bugs in the specification, which make it difficult
to determine what is valid sieve and what is not.
Is this why Tom says... "Note that "else if" is illegal in 04."?
It must be written like:
Example: if header ["From"] contains ["coyote"] {
forward "acm(_at_)frobnitzm(_dot_)edu";
} else {
if header "Subject" contains "$$$" {
forward "postmaster(_at_)frobnitzm(_dot_)edu";
} else {
forward "field(_at_)frobnitzm(_dot_)edu";
}
}
I guess we are really trying the discourage the use of "else if".
Greg Sereda