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

Re: Short loops?



Bart Schaefer wrote:
> misleading.  The /bin/sh manual can get away with `while LIST do LIST done'
> because in /bin/sh the semicolon or newline at the end of a LIST is never
> optional (the definition of LIST *includes* the trailing separator in the
> /bin/sh manuals).

Then the /bin/sh manual is wrong.  if (true) then (echo foo) fi works fine
in sh.  Of course any corrections to the manual are welcome.  The manual
now contains a more or less full formal description of the grammar, but I
agree, that it may be hard to interpret it correctly.  In general, it is
not easy to describe the exact grammar of the shell in such a way that it
is easy to understand for the human readers.  Note that ksh has the same
problems here as zsh.  In sh/ksh the question is when is it possible to
omit the semicolon/newline before `then'.  In zsh the brace syntax
complicates this a bit, but it is really the same problem.  If the
newline/semicolon can be omitted in a while LIST do statement then the
while LIST { ... } syntax will work as well.

> > Zsh has to know that { is not a simple argument
> > to a command, but a reserved word.
>
> That's not a sufficient explanation either!  It has to be not just a
> reserved word, but a reserved word in a spot where that particular word
> doesn't have an alternate meaning -- which means after )) or ]] or ) or },
> but NOT after semicolon or newline.  Which is *not the same* as the rule
> for where `do' can appear, which IMHO should mean that the syntax summary
> should NOT be written `while LIST { LIST }'.

If you interpret LIST as the longest string which is synactically a list
than it is correct.  In while true ; { echo foo } the longest possible list
is true ; { echo foo }.  Zsh just parses the list as long as it can, and
when the list parses sees something that cannot continue a list it returns.

>
> The doc could define a CLOSED construct to be any of (( )) [[ ]] ( ) { },
> and define a CLOSEDLIST to be a LIST ending with a CLOSED but that is NOT
> followed by the optional separator.  Then it could say:
>
> `if CLOSEDLIST { LIST } [ elif CLOSEDLIST { LIST } ] ... [ else { LIST } ]'
> `if CLOSEDLIST SUBLIST'
> `while CLOSEDLIST { LIST }'
> `until CLOSEDLIST { LIST }'
>
> And then I'd be happy.

Yes, but that would make the manual quite verbose repeating the same thing
many times.

> > The { echo } case works and seems to be
> > an exception to this rule but is really a pathologic special case handled
> > explicitely in lex.c and it only works if ignorebraces is not set.
>
> I don't know what you're talking about here at all, I fear.  An exception
> to which rule?  `}' is recognized *everywhere* when ignorebraces is not

} is a reserved word, and it should be recognized only in command position.
But it is recognized in other places as well.

> set.  Which seems bizarre to me anyway -- if `{' is not recognized every-
> where, then `}' ought to be recognized only when an unmatched reserved `{'
> has preceded it.  One more state flag in the lexer could fix that.

{ cannot mean command grouping in echo { ... } just line echo ( ... ) does
not do that.  The later is a syntax error in sh.  And I think it would be
even more confusing if echo } works but it stops working after you put it
into a while loop using { ... }.

Zoltan



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