8

From the syntax doc:

A closing curly brace followed by a newline character implies a statement separator, which is why you don't need to write a semicolon after an if statement block.

if True {
    say "Hello";
}
say "world";

That's fine and what was going on with Why is this Perl 6 feed operator a “bogus statement”?.

However, how does this rule work for an uncuddled else? Is this a special case?

if True {
    say "Hello";
}
else {
    say "Something else";
}
say "world";

Or, how about the with-orwith example:

my $s = "abc";
with   $s.index("a") { say "Found a at $_" }
orwith $s.index("b") { say "Found b at $_" }
orwith $s.index("c") { say "Found c at $_" }
else                 { say "Didn't find a, b or c" }
brian d foy
  • 129,424
  • 31
  • 207
  • 592

1 Answers1

4

The documentation you found was not completely correct. The documentation has been updated and is now correct. It now reads:

Complete statements ending in bare blocks can omit the trailing semicolon, if no additional statements on the same line follow the block's closing curly brace }.

...

For a series of blocks that are part of the same if/elsif/else (or similar) construct, the implied separator rule only applies at the end of the last block of that series.


Original answer:

Looking at the grammar for if in nqp and Rakudo, it seems that an if/elsif/else set of blocks gets parsed out together as one control statement.

Rule for if in nqp

rule statement_control:sym<if> {
    <sym>\s
    <xblock>
    [ 'elsif'\s <xblock> ]*
    [ 'else'\s <else=.pblock> ]?
}

(https://github.com/perl6/nqp/blob/master/src/NQP/Grammar.nqp#L243, as of August 5, 2017)

Rule for if in Rakudo

rule statement_control:sym<if> {
    $<sym>=[if|with]<.kok> {}
    <xblock(so ~$<sym>[0] ~~ /with/)>
    [
        [
        | 'else'\h*'if' <.typed_panic: 'X::Syntax::Malformed::Elsif'>
        | 'elif' { $/.typed_panic('X::Syntax::Malformed::Elsif', what => "elif") }
        | $<sym>='elsif' <xblock>
        | $<sym>='orwith' <xblock(1)>
        ]
    ]*
    {}
    [ 'else' <else=.pblock(so ~$<sym>[-1] ~~ /with/)> ]?
}

(https://github.com/rakudo/rakudo/blob/nom/src/Perl6/Grammar.nqp#L1450 as of August 5, 2017)

Christopher Bottoms
  • 11,218
  • 8
  • 50
  • 99
  • That's an unfortunate special case. – brian d foy Aug 06 '17 at 00:22
  • Why is it "unfortunate"? – Christopher Bottoms Aug 07 '17 at 11:21
  • 1
    While this isn't *strictly* a case of longest token matching, it does follow the general Perl 6 parsing principle that the interpretation matching the most things will tend to be the winner. – Jonathan Worthington Aug 07 '17 at 12:40
  • 1
    It's unfortunate because it's an exception to the rule that starts my question. – brian d foy Aug 07 '17 at 14:10
  • 2
    Now I can think more clearly about it: actually it's not a special case, because the rule about where you don't need `;` is a rule about the end of a statement, but an if/elsif/else sequence is actually a single statement. – Jonathan Worthington Aug 07 '17 at 17:50
  • 1
    This means that the rule in the docs is wrong though. It's not about the } and vertical whitespace. And, it means that there can be no rule because people cannot ahead of time guess what is or isn't a statement without knowing how the Perl 6 grammar will parse it. This unguessability from Perl 5 was supposed to go away. – brian d foy Aug 24 '17 at 12:33
  • @briandfoy You could view it as `}␤` terminating the statement; which causes the `else` to fail to parse, so it it backtracks and tries to see if it would parse if it didn't terminate the statement. Basically this is a case of do what I meant, instead of do what I said. Since in this case it is obvious what was meant as it would otherwise be a parse failure it isn't likely to be a problem. Note that `else`&co are already very special as there are very few things that can hang off of an `if`-like statement, and they can't hang off of other `if`-like statements such as `given`. – Brad Gilbert Mar 20 '18 at 16:55