Выражение в Perl 6 анализируется как termish
вещи с infixish
вещами между ними. termish
в свою очередь определяется как ноль или более prefixish
вещей, за которыми следует сам термин, за которым следует ноль или более postfixish
вещей. postfixish
принимает все:
- вызовы методов (например,
.foo
)
- Операторы постфикса (например,
++
)
- Операторы Postcircumfix (например,
[42]
in @a[42]
)
- Выполнение гипер (
>>
) над ними для распределения их по структуре данных
Поскольку он просто ищет ноль или более из них, вы можете свободно чередовать вызовы методов и индексы хешей и массивов. Это объясняет, почему @weekdays.antipairs.hash{'Sunday'}
хорошо анализирует (и почему @weekdays.antipairs.hash<Sunday>
также будет работать, и даже @weekdays.antipairs.hash<Sunday>.say
тоже хорошо).
Что касается .
, грамматика просто принимает и игнорирует .
перед postfix
или postcircumfix
. Вот немного урезанная версия синтаксического анализатора, которую я немного аннотировал, чтобы объяснить, что такое части.
token postfixish {
<!stdstopper>
# If we're not in a string interpolation, allow unspace (that's
# where you write `\ ++`, for example, allowing spreading
# postfixish things over multiple lines).
[ <!{ $*QSIGIL }> [ <.unsp> | '\\' ] ]?
# Here we match the >> for doing a hyper. Note that it accepts
# but disregards a '.' before it. It's not captured at all and
# doesn't affect the code that is compiled.
[ ['.' <.unsp>?]? <postfix_prefix_meta_operator> <.unsp>?]**0..1
[
| <OPER=postfix>
# When there'd be no confusion with a method call, a '.' is
# also accepted and disregarded before a postfix operator
| '.' <?before \W> <OPER=postfix> ## dotted form of postfix operator (non-wordy only)
| <OPER=postcircumfix>
# Ditto here for recognized postcircumfixes
| '.' <?[ [ { < ]> <OPER=postcircumfix>
| <OPER=dotty>
| <OPER=privop>
]
}
Таким образом, .
ничего не значит в этом контексте. Синтаксический анализатор просто принимает его, а затем переходит к поиску того, что ему действительно нужно в тот момент.
Еще одна вещь, на которую стоит обратить внимание, - это то, что операторы postfix и postcircumfix тоже работают после точечного термина и работают на $_
. Таким образом:
my @xs = 1..10;
.++ for @xs;
say @xs;
Будет производить:
[2 3 4 5 6 7 8 9 10 11]
Вот пример postcircumfix:
my %h = a => 1, b => 2, c => 3;
say .<a> + .<c> given %h;
Который производит 4
.
Синтаксис Perl 6 обычно предназначен для того, чтобы упростить перенос кода из одной формы в другую, и принятие .
в местах, даже если это не является строго необходимым, немного облегчает (так что можно изменить рефакторинг на say %h1.<a> + %h2.<b>;
и с парсером все будет в порядке). Для целей обучения также может быть полезно считать %h<a>
сокращенным от %h.<a>
, что, в свою очередь, сделает .<a> given %h
немного менее неожиданным.
Дополнительное пространство, предоставляемое .
, также может помочь ясности, особенно если нужно было сложить несколько постфиксов, и даже может - если расширение языка по какой-то причине решит определить некоторые «интересные» термины или операторы постфикса - служить как средство устранения неоднозначности.