From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21196 invoked by alias); 4 Aug 2014 18:51:13 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 32955 Received: (qmail 273 invoked from network); 4 Aug 2014 18:51:11 -0000 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 From: Bart Schaefer Message-id: <140804115102.ZM1058@torch.brasslantern.com> Date: Mon, 04 Aug 2014 11:51:02 -0700 In-reply-to: <20140731174208.67f1b392@pwslap01u.europe.root.pri> Comments: In reply to Peter Stephenson "Re: $(...) and <<" (Jul 31, 5:42pm) References: <20140731092711.GA28401@chaz.gmail.com> <140731092023.ZM16680@torch.brasslantern.com> <20140731174208.67f1b392@pwslap01u.europe.root.pri> X-Mailer: OpenZMail Classic (0.9.2 24April2005) To: zsh-workers@zsh.org Subject: Re: $(...) and << MIME-version: 1.0 Content-type: text/plain; charset=us-ascii On Jul 31, 5:42pm, Peter Stephenson wrote: } Subject: Re: $(...) and << } } > } $ zsh -c 'echo $(cat << EOF } > } blah) } > } EOF } > } ); echo test' } > } zsh:4: parse error near `)' } } - Check if it looks like $( ... ) or $(( ... ) ... ) but not $(( ... )) } as before, in other words we have to guess if it's $( ... ) by looking } for a stray ")" that might actually not be the end of the command } substitution but probably implies it's not a $(( ... )) substitution. } A bit icky but we've done worse. } } - Re-enter the parser at this point within the lexer and keep going I tried this a couple of different ways but always ended up with one or more of the "make check" tests failing because I wasn't backtracking properly after discovering that the first ")" wasn't a "))". It's also fairly ugly to discover that the first ")" in "$( ... ) ... )" is NOT closing the expression unless you are already in the parser. What it seems realy needs to happen is to always attempt to parse math at "$((" and if that fails, back up to the second "(" and attempt to parse shell code. But that can require arbitrary lookahead ... which is no worse than attempting to consume everything up to ")" as a string and then parse it, but (as you mentioned) a bit harder to extract the result because it's passing through the parser rather than lexer.