Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Misc. musings on shell grammar (plus a bug?)



Musing about the grammar documentation, actually, not about the grammar
itself.

The grammar (ignoring redirections) as described by the corresponding
section of the manual is roughly

    simple ::= wordlist | modifier simple
    pipeline ::= simple PIPE pipeline | simple
    coprocess ::= "coproc" pipeline 
    sublist ::= pipeline JOIN sublist | pipeline
    clist ::= sublist SEP clist | sublist
    list ::= clist SEP | <empty>
    complex ::= "(" clist ")" | "{" clist "}" | "[[" exp "]]" |
                if | for | while | until | repeat | case | select | time

    [Grammars of structured commands omitted for brevity.]

I first note the omission of "((math))" here.  There should at least be
a mention of that in the grammar section.

Another note is that the placement of at least "[[exp]]" and "time" is
misleading.  "[[exp]]" behaves like a "list" in that no separator is 
needed when it appears before a keyword in a structured command, and
"time" belongs somewhere between "pipeline" and "sublist".

A more accurate representation of the grammer would be

    simple ::= wordlist | modifier simple
    complex ::= "(" clist ")" | "{" clist "}" | "[[" exp "]]" | math |
                if | for | while | until | repeat | case | select
    statement ::= simple | complex
    pipeline ::= statement PIPE pipeline | statement
    job ::= pipeline | <empty>
    coprocess ::= "coproc" job
    timeline ::= "time" job
    process ::= pipeline | coprocess | timeline
    sublist ::= process JOIN sublist | process
    nonempty ::= sublist SEP nonempty | sublist
    clist ::= nonempty | <empty>
    list ::= clist SEP | complex | <empty>
    math ::= "((" <math expression> "))"

And I have no idea why I just spent more than an hour working that out
except that perhaps it'll give somebody else (or me, when I reread it
later) some ideas for how to improve the documentation.  Even so, it's
still not quite right because some combinations of "time" and "coproc"
that are valid (though not very useful) can't be derived.

Now for the "bug" -- this is 4.0.6, but 4.1.1-testX behaves the same:

schaefer[501] if false & then echo oops & fi
[2] 20011
[2]  + exit 1     false
oops
[2] 20012
[2]  + done       echo oops

I suppose this makes sense -- this test would be false only if "false"
could not be backgrounded, e.g., fork failure?



Messages sorted by: Reverse Date, Date, Thread, Author