Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why perl parses regex

Tags:

perl

Perl misses my DWIM (ternary ?:) and forces regex.

perl -e "print $bool ?'T' :'F'"
Use of ?PATTERN? without explicit operator is deprecated at -e line 1.
Search pattern not terminated or ternary operator parsed as search pattern at -e
 line 1.

Why is that so? Following two examples have correctly parsed ternary operator,

perl -e "print $bool ? 'T' :'F'"
perl -e "print [] ?'T' :'F'"

This is on windows, but almost same thing on *nix

perl -e 'print $bool ?"T" :"F"'

so it doesn't look like shell related.

like image 531
mpapec Avatar asked Nov 24 '25 08:11

mpapec


2 Answers

The ?...? is an operator, as seen here, and the problem here is one of ambiguity. The compiler does not know if it is seeing a pattern or a ternary operator (as the subsequent warning says), so it guesses, and guesses wrong.

I think it has something to do with print() setting it up for a fall, in that print() has the syntax:

print FILEHANDLE LIST

So, it pre-determines $bool as a file handle, and ?'.... as a statement. Then it notices that $bool is not a file handle, but the ternary is already cast in its faulty role. You will notice that the following works as intended:

perl -e"print STDOUT $bool ?'t' :'f'"
like image 105
TLP Avatar answered Nov 28 '25 02:11

TLP


Perl syntax has ambiguities.

print $bool ?...

can be parsed as

print FILEHANDLE LIST

  +----------------- print
  |     +----------- FILEHANDLE
  |     |    +------ LIST (A regex match ?...?)
  |     |    |       
_____ _____ ____
print $bool ?...

or as

print LIST

  +----------------- print
  |       +--------- LIST (A conditional operator ...?...:...)
  |       |         
_____ __________
print $bool ?...

Without looking too far ahead, perl incorrectly guesses that you meant the first one, but lets you know that it guessed.

Search pattern not terminated or ternary operator parsed as search pattern

Workarounds:

  • Adding a space after the ? (print $bool ? 'T' :'F';) makes it guess correctly (since it no longer looks as much like ?...?).

  • Adding a + before the file handle (print +$bool ?'T' :'F';) makes it guess correctly (since it's no longer a valid file handle expression).

  • Remove the space before the ? (print $bool?'T' :'F';) makes it guess correctly (since it's no longer a valid file handle expression).

  • Adding a file handle (print STDOUT $bool ?'T' :'F';) makes it guess correctly (since $bool must now be the start of the argument list).

like image 37
ikegami Avatar answered Nov 28 '25 02:11

ikegami



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!