From: segal@morgan.com (Morris M. Siegel)
To: Zoltan Hidvegi <hzoli@cs.elte.hu>,
schaefer@nbn.com, zsh-users@math.gatech.edu
Subject: Re: Bug in case stmt with '('
Date: Sun, 21 Jul 1996 18:53:36 -0400 [thread overview]
Message-ID: <9607211853.ZM979@morgan.com> (raw)
In-Reply-To: Zoltan Hidvegi <hzoli@cs.elte.hu> "Re: Bug in case stmt with '('" (Jul 19, 6:00pm)
Greetings:--
I don't have the time to examine how zsh's lex.c and parse.c work,
so I can't comment technically on Bart Schaefer and Zoltan Hidvegi's
respective patches. However, the thought occurred to me that the
lexer and/or parser might be simplified if we revise our outlook on
the case-statement grammar. Instead of the syntax of each case-
clause's prefix being
{A} [(] pat-1 | ... | pat-n )
(which requires the troublesome analysis of deciding whether an
initial '(' is the optional '(' of the case-clause syntax or simply
a glob-type '(' belonging to pat-1 proper), why not extend the syntax
to be
{B1} pat-1 | ... | pat-n [)]
? Thus (presuming that normal zsh globbing is in effect), an
initial '(' would _always_ be a glob-type parenthesis (making
the entire case-clause prefix into one big grouped pat-1 that
is not followed by the optional trailing ')').
This should not break existing code, since currently a trailing
')' is always required. Moreover, sh, ksh, and zsh all disallow
blanks in any pat-i, as the following console listing demonstrates,
so there is no valid case-clause (of the form, say, 'a b) c;;')
such that omitting the ')' would result in an ambiguous or misparsed
case-clause (such as 'a b c;;').
If one were reluctant to depart so far from traditional case-statement
syntax as {B1} does, one could make the trailing ')' optional only
when pat-n itself ends in ')', and to stay even more compatible with
POSIX syntax, additionally require that n = 1. However, zsh already has
so many extensions that I don't seem the harm in letting the trailing
')' always be optional: each pat-i would be unambiguously terminated by
(possibly optional whitespace preceding) '|', ')', or the first token
of the case-clause body (which cannot be '|' or ')' in any case).
The above all presumes that '(' is a globbing character, which is
normally so. If it isn't (such as when the NO_GLOB [or SH_GLOB ?]
option is in effect), then {B1}, although still necessary, is
insufficient, and must obviously be supplemented with the alternative
{B2} ( pat-1 | ... | pat-n )
. In this case, the ')' is mandatory: traditional case-clause syntax
requires us to tolerate an unmatched trailing ')', but there is no
reason to allow an unmatched leading '('.
The only remaining issue is how to describe case-prefix syntax in
the zshmisc man pages. It is unnecessary to mention the
implementation detail that when '(' is a globbing character,
the lexer or parser treats {B2} as a special case of {B1}.
To be rigorous, one could state that the case-prefix syntax
is {B1} | {B2}. However, this is somewhat tedious, and instead
it might be preferable to present the syntax simply as
{C} [(] pat-1 | ... | pat-n [)]
and mention in the accompanying English-language text that if the
leading '(' is supplied then the trailing ')' is required as well.
__________________________________
By the way, my previous posting shows that with the buggy behavior
of zsh-3.0-pre{1,3}, when executing ". case3let.ksh", the interpreter
erroneously falls through to the next case-clause instead of exiting
the entire case-statement (see lines 68-75 of that posting's console
listing). In addition, when executing "zsh case3let.ksh", version
3.0-pre3 (but not -pre1) gets a segmentation fault (see lines 62-67).
These would seem to be problems aside from the incorrect parsing
of the case-clause prefix.
-- Morrie Siegel
__________________________________
$(0) 13:08:37 {5} head case[45]sp.ksh
==> case4sp.ksh <==
case 'a z' in
#a z ) echo 'a z )' ;;
a\ z ) echo 'a\\ z )' ;;
a[ ]z ) echo 'a[ ]z )' ;;
a* ) echo 'a* )' ;;
* ) echo '* )' ;;
esac
==> case5sp.ksh <==
case 'a z' in
a z ) echo 'a z )' ;;
a\ z ) echo 'a\\ z )' ;;
a[ ]z ) echo 'a[ ]z )' ;;
a* ) echo 'a* )' ;;
* ) echo '* )' ;;
esac
$(0) 13:08:53 {6} /bin/sh case4sp.ksh
case4sp.ksh: syntax error at line 4: `]z' unexpected
zsh: 17070 exit 2 /bin/sh case4sp.ksh
$(2) 13:09:15 {7} r 4=5
/bin/sh case5sp.ksh
case5sp.ksh: syntax error at line 2: `z' unexpected
zsh: 17071 exit 2 /bin/sh case5sp.ksh
$(2) 13:09:22 {8} /bin/ksh case4sp.ksh
case4sp.ksh: syntax error at line 4 : `]z' unexpected
zsh: 17072 exit 2 /bin/ksh case4sp.ksh
$(2) 13:09:36 {9} r 4=5
/bin/ksh case5sp.ksh
case5sp.ksh: syntax error at line 2 : `z' unexpected
zsh: 17074 exit 2 /bin/ksh case5sp.ksh
$(2) 13:09:42 {10} zsh3p1 case4sp.ksh
case4sp.ksh: parse error near `]z' [4]
case4sp.ksh: parse error near `)' [5]
case4sp.ksh: parse error near `)' [6]
case4sp.ksh: parse error near `esac' [7]
$(0) 13:10:08 {11} r 4=5
zsh3p1 case5sp.ksh
case5sp.ksh: parse error near `z' [2]
case5sp.ksh: parse error near `)' [3]
case5sp.ksh: parse error near `)' [4]
case5sp.ksh: parse error near `)' [5]
case5sp.ksh: parse error near `)' [6]
case5sp.ksh: parse error near `esac' [7]
$(0) 13:10:44 {12} exit
__________________________________
next prev parent reply other threads:[~1996-07-21 22:59 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
1996-07-17 21:01 Morris M. Siegel
1996-07-18 18:27 ` Bart Schaefer
1996-07-18 23:43 ` Zoltan Hidvegi
1996-07-19 2:23 ` Bart Schaefer
1996-07-19 16:00 ` Zoltan Hidvegi
1996-07-21 22:53 ` Morris M. Siegel [this message]
1996-07-22 6:31 ` Bart Schaefer
[not found] ` <schaefer@candle.brasslantern.com>
1996-07-22 19:26 ` Morris M. Siegel
1996-07-22 19:51 ` Zoltan Hidvegi
1996-07-22 20:48 ` Morris M. Siegel
1996-07-22 21:27 ` Zefram
1996-07-22 21:56 ` Morris M. Siegel
1996-07-22 21:51 ` Bart Schaefer
1996-07-22 21:23 ` Zefram
1996-07-22 22:31 ` Morris M. Siegel
1996-07-22 23:37 ` Bart Schaefer
1996-07-24 16:07 ` Morrie is off for July 25 Morris M. Siegel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=9607211853.ZM979@morgan.com \
--to=segal@morgan.com \
--cc=hzoli@cs.elte.hu \
--cc=schaefer@nbn.com \
--cc=zsh-users@math.gatech.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).