compilation - Perl 6 中后缀或后缀前的点是什么意思?

标签 compilation grammar raku postfix-operator

在 Perl 文档中,有一节关于 .postfix/.postcircumfix ,它说

In most cases, a dot may be placed before a postfix or postcircumfix:


my @a;
@a[1, 2, 3];
@a.[1, 2, 3]; # Same

Technically, not a real operator; it's syntax special-cased in the compiler.



我自己试过:
> my @a = 1,2,3,4,5
> @a[1]  # 2
> @a.[1] # 2

> my %a = Perl => 6, Python => 3, PHP => 7
> %a<Perl>  #6
> %a.<Perl> #6

> my @weekdays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
> @weekdays.antipairs.hash{'Sunday'}  # 6, I expected it to be syntax wrong, but it did work!
> @weekdays.antipairs.hash.{'Sunday'} # 6, seems visual clarity or brevity

那么,Perl 6 中后缀或后缀前的点是什么意思?它到底是怎么做到的?我对此很好奇。谢谢。

最佳答案

Perl 6 中的表达式被解析为 termishinfixish 的事情他们之间的事情。一个 termish依次定义为零个或多个 prefixish事物,然后是术语本身,然后是零个或多个 postfixish事物。 postfixish包含所有:

  • 方法调用(如 .foo)
  • 后缀运算符(如 ++ )
  • 后缀运算符(如 [42] 中的 @a[42])
  • 对这些执行 hyper ( >> ) 以将它们分布在数据结构中

  • 由于它只查找零个或多个,因此您可以自由地交错方法调用以及散列和数组索引。这解释了为什么@weekdays.antipairs.hash{'Sunday'}解析很好(以及为什么 @weekdays.antipairs.hash<Sunday> 也可以工作,甚至 @weekdays.antipairs.hash<Sunday>.say 也很好)。

    至于. ,语法简单地接受并忽略 .之前 postfixpostcircumfix .这是解析器的一个稍微简化的版本,我已经注释了一些以解释这些部分是什么。
    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 运算符也都在一个dotty 术语之后工作,在 $_ 上运行。 .因此:
    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少一点惊喜。
    . 提供的额外空间也可能有助于清晰,特别是如果要堆叠多个后缀,甚至可以 - 如果语言扩展出于某种原因决定定义一些“有趣的”术语或后缀运算符 - 作为消除歧义的一种手段。

    关于compilation - Perl 6 中后缀或后缀前的点是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50189205/

    相关文章:

    GCC——针对 HP-UX 的目标三元组

    java - 乘法/移位优化是否应该在 Java 字节码中可见

    javascript - 用于 JavaScript/ECMAScript 数组文字生成的 LOOKAHEAD

    parsing - 从句子中找到有意义的子句子

    c++ - C++ 是上下文无关的还是上下文敏感的?

    python - 为什么整数除法在许多脚本语言中舍入?

    c - RabbitMQ-C 构建错误(使用 openSSL)

    c - 如何在 QuickTime SDK for Windows 中使用 CoreFoundation?

    raku - Perl 6 中嵌套列表的赋值

    raku - 如何在 Perl 6 中删除变音符号