From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from euclid.skiles.gatech.edu (list@euclid.skiles.gatech.edu [130.207.146.50]) by coral.primenet.com.au (8.7.5/8.7.3) with ESMTP id IAA09833 for ; Mon, 22 Jul 1996 08:59:45 +1000 (EST) Received: (from list@localhost) by euclid.skiles.gatech.edu (8.7.3/8.7.3) id SAA15564; Sun, 21 Jul 1996 18:57:05 -0400 (EDT) Resent-Date: Sun, 21 Jul 1996 18:55:22 -0400 (EDT) From: segal@morgan.com (Morris M. Siegel) Date: Sun, 21 Jul 1996 18:53:36 -0400 Message-Id: <9607211853.ZM979@morgan.com> In-Reply-To: Zoltan Hidvegi "Re: Bug in case stmt with '('" (Jul 19, 6:00pm) References: <199607191600.SAA08613@bolyai.cs.elte.hu> X-Mailer: Z-Mail (3.2.1 10oct95) To: Zoltan Hidvegi , schaefer@nbn.com, zsh-users@math.gatech.edu Subject: Re: Bug in case stmt with '(' Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Resent-Message-ID: <"xRTxD1.0.bo3.QLhyn"@euclid> Resent-From: zsh-users@math.gatech.edu X-Mailing-List: archive/latest/317 X-Loop: zsh-users@math.gatech.edu X-Loop: zsh-workers@math.gatech.edu Precedence: list Resent-Sender: zsh-workers-request@math.gatech.edu 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 __________________________________