只有“perl6”可以解析Perl 6吗?

39

有一个(相对)著名的Perl格言:“只有Perl可以解析Perl。” 我在想,对于Perl 6,这个说法是否仍然成立?

扩展讨论...我想到了这个问题,是考虑到PyPy最近的更新。 Perl独特的可解析性是否会妨碍类似的努力?在Perl代码的受限静态视图(如PPI)中有多少价值? Perl 6能否拥有JIT编译器?*

* 我不确定这些概念是否相关。它们相关吗?


6
请问需要翻译成什么语言呢? - friedo
7
公理是“只有 Perl 能解析 Perl”。大写字母 P 的 Perl 是指这种编程语言,小写字母 p 的 perl 是指其解释器。 - Chris Lutz
抱歉,大写字母的疏忽。=) - Mark Canlas
MoarVM是Rakudo(Perl 6最常用的实现)所针对的主要虚拟机,其在运行时优化中包含JIT编译。https://www.moarvm.org/features.html - daotoad
说实话,“公理”并不完全正确。正如在这里所说的那样:(https://en.wikipedia.org/wiki/Perl#Implementation)*因为Perl解释器可以在编译阶段模拟图灵机,所以它需要解决停机问题才能在每种情况下完成解析。* 因此,即使是Perl也无法始终解析Perl。 - jjj
5个回答

37
没有Perl6,但有许多Perl 6编译器。Perl 6有一个语法,尽管它是用Perl 6编写的,所以只要你能理解它,它就会告诉你所有你需要知道的。
我刚刚在圣保罗Perl研讨会与Larry共进午餐时问了他这个问题。他说现在是“只有Perl 6可以解析Perl 6”,两个Perl都要大写,这意味着与原始声明不同。
不过,你并不需要特定的程序来做到这一点,因为Perl 6的目标是一个标准和许多实现。没有“perl6”,尽管Larry将其别名为他今天的Rakudo演讲,即使他在示例中使用了几种不同的实现。

10

在我上次查看时,Perl 6继承了Perl 5的/字符,当期望一个项时它可以表示“正则表达式的开头”,而当期望一个操作符时,则表示“除法”。由此可见,对于静态记号化,Perl 6至少与Perl 5位于同一阵营,并具有原型。仅有运行Perl 6解释器的Perl 6编译器才能对Perl 6程序进行标记化处理。再次深入探索,无止境。


但是,JavaScript 是否也有 / 字符用作注释、除法或正则表达式呢?不同之处在于 JavaScript 语法不会产生歧义。 - Konrad Borowski
JavaScript没有类似于Perl的原型,因此每个标识符对解析器状态和词法分析器状态都有明显的影响。Perl必须运行BEGIN/use代码以正确加载在其中定义的所有可选原型。 - Randal Schwartz
5
虽然我有些晚了,但无论如何,这在Perl6中并不是一个问题,因为“/”是一个中缀运算符,你永远不会在期望中缀运算符的地方开 始一个正则表达式。但是,如果你同时定义前缀:</>和后缀:</>,那么以前是正则表达式的/1+1/可以被解释为1和1的总和。然而,解析器会知道这一点,并相应地进行更正。没有必要在编译时运行任何代码来确保这一点。 - timotimo

9
这个格言是“只有perl可以解析Perl”,其中“perl”是解释器二进制文件,“Perl”是语言。这主要是因为在解析文件时,解析规则可以发生变化。在Perl 5中,这源于具有原型的子例程声明、各种操作指令和源过滤器。
我认为,在Perl 6中,这个问题只会变得更加严重。在Perl 5中,解析器规则可能会发生变化的地方有限,而在Perl 6中,它们是广泛而多样的。除了Perl 5中的所有内容外,Perl 6还允许您定义自己的运算符,并且由于此定义是用Perl代码完成的,因此需要Perl解释器来理解它。
据我所知,尚未有实现支持它,但Perl 6规范还包括真正的语言级别宏,可以通过文本或操作AST重新构造Perl 6代码。这两者都需要存在Perl解释器才能执行其魔法。
因此,总之,我有一种感觉,Perl 6将使该公理比Perl 5更加强大(并且对于语法突出显示器的作者来说将会是更大的噩梦:))。当然,这都是为了增加语言的表达力,所以我对这个让步表示赞成。
上述让步的一个推论是,与Perl 5不同,Perl 6具有正式的规范,因此该公理可能必须改为“只有实现Perl 6规范的解释器才能解析Perl 6”,但这有点吹毛求疵。
根据更新:
我不认为上述内容排除了 JIT 编译器对 Perl 6 的想法,因为按定义,这种编译器也必须包含 Perl 6 解释器。就静态编译而言,可能是可行的,但它将严重限制语言的运行时功能,因为任何涉及 eval 的结构都将无法工作。
在Perl 5领域中,PPI很有用,因为perl解释器没有提供许多富有且易于使用的AST接口。在Perl 6中,内省级别更高,因此解释器本身可能提供所有必要的工具。

4
@Eric Strom,是的,他们谈论“语法分析规则可能发生变化的位置数量”,以及定义运算符、宏等的能力。但这些都不相关。例如,它们都适用于C++,但C++解析器不需要运行任意C++代码来编译C++程序。 - ikegami
4
这是一个需要解析Perl5的perl5示例:BEGIN { if (rand()<.5) { *f = sub(){ 3 }; } else { *f = sub { 3 }; } } print f + 1。运行任意Perl代码是必要的,以确定该产品是否等效于print(f()+1)print(f(+1)) - ikegami
11
@Eric Storm,你的论点很有力,但我不完全认同。Perl5仅解析Perl 5的问题是Perl 6开发人员非常熟悉的,并且是设计目标之一。与Perl 5不同,Perl 6语言扩展是以Perl 6语法为基础定义的,这是一个单独、更小的规范。至于运算符的问题,您可以定义新的运算符,但不能定义新的运算符类型。也就是说,原始语法可以看到它具有一个中缀运算符,而无需知道它是否存在。最后,如果运算符只能在编译时定义,这个问题就会消失,我正在验证这一点。 - Schwern
5
无法在运行时定义适用于已编译代码的新运算符。因此,if condition { eval "...define a new op or macro..." } 对解析没有影响。另外,在条件语句中定义新运算符也没有实际意义。if condition { multi sub postfix:... } 无法达到预期效果。 - Schwern
10
这是一个极为无知的回答,被一些完全不了解情况的人点赞。 - brian d foy
显示剩余6条评论

6

Perl 6是一种规范,任何遵循该规范的程序都可以被称为Perl 6,就像大多数其他语言一样。目前有许多Perl 6实现正在进行中。


1
换句话说,除了假设的Perl6之外,其他东西也可以解析Perl 6. :) - brian d foy

4
Perl6可以有JIT编译器吗?

您认为Perl5无法进行JIT编译是基于“只有perl可以解析Perl5”,但这并不正确。尽管每次运行Perl5程序可能会有不同的编译方式,但这并不妨碍它进行JIT编译。

因此,如果Perl5 - 最松散定义的语言之一 - 可以进行JIT编译,为什么Perl6不能呢。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接