This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
`for my($k, $v) (%hash)` should not be a syntax error
No-one had thought to test for this explicitly. After all, both
`for my $foo ...` and `for my$foo ...` are valid syntax, so tweaking the
C lexer code to add an optional '(' should work, surely?
The problem was that, *as was*, the lexer code didn't "accept" those two
syntax variants the way the comments would suggest.
`for my $foo ...` was treated as
1) we saw 'my '
2) we saw the dollar sign
3) success!
but `for my$foo ...` was treated as
0) we didn't see 'my ' or 'our '
1) we saw the literal string 'my' which is valid as a package name
2) we saw the dollar sign
3) success!
ie some sort of mangled variant of `for my Dog $spot ...` without 'my'
*but* as the lexer was happy with what it saw, it returned that the input
stream was valid for a "for" token, and control continues to the grammar.
The grammar, of course, didn't make these mistakes, so parsed everything
properly and built the correct optree.
(And, if presented with `for Dog $spot (...)` the grammar wouldn't match,
so all invalid code was correctly rejected)
However, all this came unstuck with `for my($k` because that didn't
mis-tokenise as some crazy package name 'my(', so it reported a syntax error.
Hence rewrite yyl_foreach() to actually tokenise everything correctly.
"Correctly", to be clear, is bug-for-bug compatible with the current emergent
behaviour for various corner cases for "parses and runs" vs "syntax error".
We don't always report identical error messages for certain syntax errors,
where the precise message reported was itself emergent behaviour from the
bugs in the previous implementation.