hurricup has asked for the wisdom of the Perl Monks concerning the following question:

Got a problem with proper expressions parsing. In the perlop there is a table with operators precedence. And there are three statements that confuses me.

Named operators (or subs) precedence is following:

As far as I understand this:

Would be really nice to have a clear and unambiguous explanation (or algorythm) how should I do this. PPI doesn't help here.

Replies are listed 'Best First'.
Re: Perl precedence details
by Athanasius (Archbishop) on Jun 20, 2015 at 09:30 UTC

    Hello hurricup,

    A named unary operator is a built-in function which takes exactly one argument. Examples are chdir and rand. See Named Unary Operators.

    The distinction between leftward and rightward list operators is explained in Terms and List Operators (Leftward):

    In the absence of parentheses, the precedence of list operators such as print, sort, or chmod is either very high or very low depending on whether you are looking at the left side or the right side of the operator. For example, in
    @ary = (1, 3, sort 4, 2); print @ary; # prints 1324
    the commas on the right of the sort are evaluated before the sort, but the commas on the left are evaluated after. In other words, list operators tend to gobble up all arguments that follow, and then act like a simple TERM with regard to the preceding expression.

    In other words, the commas on the right of the sort are evaluated first, because the rightward aspect of the list operator sort has a lower precedence than the comma operator. But the list operator sort is evaluated before the commas to its left, because its leftward aspect has a higher precedence than the comma operator. Prototypes have nothing to do with the difference between leftward and rightward here.

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      First, I've read perlop, thank you :)

      Second, guess, You are wrong, it's not built in function:

      use 5.010; use strict; sub mysub($) { printf "Sub called with %s\n", join '', @_; } sub mysub2 { printf "Sub2 called with %s\n", join '', @_; } mysub "test" eq "test"; mysub2 "test" eq "test";
      mysub behaves like named unary op (because of proto i belive) and mysub2 behaves like list operator without parens.

      Again, I need 100% sure explanation (not guesses) and point where I can find the list of named unary built ins without digging all the perldocs.

        Second, guess, You are wrong, it's not built in function:

        Well, yes, you’re right, it’s not only a built-in function, it’s any function, built-in or user-defined, that has a ($) prototype.

        The Camel Book (4th Edition, 2012) has a table listing “all the named unary operators” on page 106. After 88 built-ins, the final entry is:

        any ($) sub

        Hope that helps,

        Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Re: Perl precedence details
by Anonymous Monk on Jun 20, 2015 at 13:28 UTC
    I need 100% sure explanation ... without digging all the perldocs

    That's going to be a problem, IIRC the knowledge on Perl's precedence is split up in a couple of places, the first that come to mind are of course perlop, the beginning of perlfunc, Prototypes in perlsub, with additional explanations in the Camel. Also you can fetch the prototypes of builtins via prototype, although AFAIK not all built-ins have prototypes because they are treated specially by Perl's parser.

    a clear and unambiguous explanation (or algorythm)

    Have you read On Parsing Perl, Perl Cannot Be Parsed: A Formal Proof, and the beginning of the PPI documentation? The following is pieced together from those links, also try running it through perl -MO=Deparse several times:

    BEGIN { eval(time % 2 ? 'sub zany () {}' : 'sub zany {}') } # how to parse the following? does it die or not? zany / 1 ; # / ; die ;

    Perhaps you could explain what you are trying to accomplish with this information?

      Yes, i read all the links above and I know about perl ticks. But it's not what i need.

      I'm working on Perl5 IDEA plugin and currently re-working parser. Need to parse expressions properly in obvious situations. Without eval/regexp tricks or something.

      So i need to know how perl distincts named unary from rightward list calls in obvious situations. And which of built-ins treated as named unary operators.

        This thread already references plenty of good information on the topic, to the point where I'm not sure you're going to find much more, and including PPI, which already does a relatively good job of parsing Perl. It's unclear to me how all this information does or does not fit your needs. Can you perhaps give specific examples of code you or your parser find difficult to parse; maybe that will make explanation easier?

Re: Perl precedence details
by Anonymous Monk on Jun 20, 2015 at 17:56 UTC
    Is there any list of built-ins treated as named unary operators?

    Out of curiosity I tried looking for myself:

    use B::Keywords qw/@Barewords @Functions/; use Pod::Functions '%Type'; # overkill my %all = (%Type, map {$_=>1} @Barewords, @Functions); for my $f (sort keys %all) { my $p = eval { prototype("CORE::$f") }; $p = defined $p ? "($p)" : ''; print "$f $p\n"; }
      Nice.

      -QM
      --
      Quantum Mechanics: The dreams stuff is made of