Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: Surprising parsing result with anonymous functions and for loops
- X-seq: zsh-workers 33242
- From: Peter Stephenson <p.stephenson@xxxxxxxxxxx>
- To: Mikael Magnusson <mikachu@xxxxxxxxx>, zsh workers <zsh-workers@xxxxxxx>
- Subject: Re: Surprising parsing result with anonymous functions and for loops
- Date: Thu, 25 Sep 2014 12:39:06 +0100
- In-reply-to: <CAHYJk3TZat+YOyx6BDTBZHyqppRE=97vKaAw4z0nmu_4nTOB+A@mail.gmail.com>
- List-help: <mailto:zsh-workers-help@zsh.org>
- List-id: Zsh Workers List <zsh-workers.zsh.org>
- List-post: <mailto:zsh-workers@zsh.org>
- Mailing-list: contact zsh-workers-help@xxxxxxx; run by ezmlm
- Organization: Samsung Cambridge Solution Centre
- References: <CAHYJk3SXb_hgz-abLaoLeU=U-Y0zwm=vHv-o+Oeg6=C3CedjUQ@mail.gmail.com> <20140924152625.73dfa6d9@pwslap01u.europe.root.pri> <CAHYJk3TR=EaB2yOTO_ZDGtnxrPatUNoj4CrG2SMy62vooLaUeA@mail.gmail.com> <CAH+w=7ZOaTpcsQY+Kt5hnDr218LOfmz21Xp1-rZqnaD0zbS0Zg@mail.gmail.com> <CAHYJk3TZat+YOyx6BDTBZHyqppRE=97vKaAw4z0nmu_4nTOB+A@mail.gmail.com>
On Thu, 25 Sep 2014 12:02:55 +0200
Mikael Magnusson <mikachu@xxxxxxxxx> wrote:
> Okay, but does anyone at least agree that doing alias expansion at
> that point is highly surprising?
You mean regardless of function behaviour?
% alias foo=bar
% for i in 1; do : ; done foo
zsh: parse error near `bar'
The parser doesn't expect anything there so doesn't make special
arrangements not to treat it as a command word because it doesn't mean
anything anyway, but this one is easy to fix. The cases with standard
keywords are the simple ones as there must be a separator next ---
closing braces are harder because there are so many cases, but I think
loops are unproblematic (this is special to zsh).
Anything similar requires some different ad hoc change. I had a go at
if and there are gotchas:
if (true) { : } else { : }
is valid syntax (again this is annoying zsh-specific stuff I wish we
didn't have to maintain) so we need to be in command position after any
closing braces except after the final "else". We've already got a
reasonable set of tests in this area for the more important non-error
case.
"while" and "repeat" look similar to "for".
The more standard uses of braces for functions are explicitly setting
incmdpos = 1 --- I can't remember why, but I've a vague memory it's
complicated. It looks like I added a special case for anonymous
functions to set incmdpos = 0. So you still get
% alias foo=bar
% foo() { : } foo
zsh: parse error near `bar'
and I'm not sure how much I want to look --- it would be easy to break
something here. If we fix redirections at this point the answer may
become more obvious.
For current shell { ... } this also happens but it's a bit more
understandable as an "always" keyword can follow.
pws
diff --git a/Src/parse.c b/Src/parse.c
index 5f1303f..3633417 100644
--- a/Src/parse.c
+++ b/Src/parse.c
@@ -997,17 +997,20 @@ par_for(int *complex)
par_save_list(complex);
if (tok != DONE)
YYERRORV(oecused);
+ incmdpos = 0;
zshlex();
} else if (tok == INBRACE) {
zshlex();
par_save_list(complex);
if (tok != OUTBRACE)
YYERRORV(oecused);
+ incmdpos = 0;
zshlex();
} else if (csh || isset(CSHJUNKIELOOPS)) {
par_save_list(complex);
if (tok != ZEND)
YYERRORV(oecused);
+ incmdpos = 0;
zshlex();
} else if (unset(SHORTLOOPS)) {
YYERRORV(oecused);
@@ -1186,9 +1189,12 @@ par_if(int *complex)
for (;;) {
xtok = tok;
cmdpush(xtok == IF ? CS_IF : CS_ELIF);
- zshlex();
- if (xtok == FI)
+ if (xtok == FI) {
+ incmdpos = 0;
+ zshlex();
break;
+ }
+ zshlex();
if (xtok == ELSE)
break;
while (tok == SEPER)
@@ -1229,6 +1235,7 @@ par_if(int *complex)
YYERRORV(oecused);
}
ecbuf[pp] = WCB_IF(type, ecused - 1 - pp);
+ /* command word (else) allowed to follow immediately */
zshlex();
incmdpos = 1;
if (tok == SEPER)
@@ -1266,6 +1273,7 @@ par_if(int *complex)
YYERRORV(oecused);
}
}
+ incmdpos = 0;
ecbuf[pp] = WCB_IF(WC_IF_ELSE, ecused - 1 - pp);
zshlex();
cmdpop();
@@ -1296,12 +1304,14 @@ par_while(int *complex)
par_save_list(complex);
if (tok != DONE)
YYERRORV(oecused);
+ incmdpos = 0;
zshlex();
} else if (tok == INBRACE) {
zshlex();
par_save_list(complex);
if (tok != OUTBRACE)
YYERRORV(oecused);
+ incmdpos = 0;
zshlex();
} else if (isset(CSHJUNKIELOOPS)) {
par_save_list(complex);
@@ -1340,12 +1350,14 @@ par_repeat(int *complex)
par_save_list(complex);
if (tok != DONE)
YYERRORV(oecused);
+ incmdpos = 0;
zshlex();
} else if (tok == INBRACE) {
zshlex();
par_save_list(complex);
if (tok != OUTBRACE)
YYERRORV(oecused);
+ incmdpos = 0;
zshlex();
} else if (isset(CSHJUNKIELOOPS)) {
par_save_list(complex);
Messages sorted by:
Reverse Date,
Date,
Thread,
Author