【问题标题】:Can only 'perl6' parse Perl 6?只能“perl6”解析 Perl 6 吗?
【发布时间】:2011-08-20 10:43:17
【问题描述】:

有一个(相对)众所周知的 Perl 公理,“只有 perl 可以解析 Perl”。我想知道,对于 Perl 6 是否仍然如此?

扩大讨论...鉴于 PyPy 的最新更新,我想到了这个问题。 Perl 独特的可解析性是否会阻止它进行类似的努力? Perl 代码 (PPI?) 的受限静态视图有多大价值? Perl 6 可以有 JIT 编译器吗?*

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

【问题讨论】:

  • 投票重新打开这个。 Perl6 的可解析性及其规范是有效的问题。
  • 公理是“只有 perl 才能解析 Perl”。大写-P Perl 是语言。 perl 小写-p 是解释器。
  • 对大小写疏忽致歉。 =)
  • MoarVM,Rakudo(Perl 6 最常用的实现)所针对的主要 VM,将 JIT 编译作为其运行时优化的一部分。 moarvm.org/features.html
  • 有点迂腐,“公理”并不完全正确。正如here: 所说,因为 Perl 解释器可以在编译阶段模拟图灵机,所以它需要确定停机问题才能在每种情况下完成解析。 所以即使 perl 也不能总是解析 Perl。

标签: perl parsing jit raku


【解决方案1】:

公理“只有 perl 可以解析 Perl”,其中“perl”是解释器二进制文件,“Perl”是语言,很大程度上源于这样一个事实,即在解析文件时解析规则可能会发生变化。在 Perl 5 中,这来自原型子例程声明、各种 pragma 和源过滤器。

在我看来,这只会在 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”,但这有点迂腐.

根据更新:

我不认为以上内容排除了 Perl 6 的 JIT 编译器的想法,因为根据定义,这样的编译器还必须包含 Perl 6 解释器。就静态编译而言,它可能是可能的,但它会严重限制语言的运行时能力,因为任何涉及 eval 的构造都不起作用。

PPI 在 Perl 5 领域很有用,因为 perl 解释器没有为其 AST 提供许多丰富且易于使用的接口。在 Perl 6 中,自省的级别要高得多,因此解释器本身可以提供所有必要的工具。

【讨论】:

  • @Eric Strom,是的,他们谈到了“解析器规则可以改变的地方的数量”,定义运算符、宏等的能力。这些都不相关。例如,它们都适用于 C++,但 C++ 解析器不需要运行任意 C++ 代码来编译 C++ 程序。
  • 这是解析 Perl5 所需的 perl5 示例:BEGIN { if (rand()<.5) { *f = sub(){ 3 }; } else { *f = sub { 3 }; } } print f + 1。需要运行任意 Perl 代码来确定产品是否等同于 print(f()+1)print(f(+1))
  • @Eric Storm 你提出了强有力的论据,但我并不完全认同。 perl5 只解析 Perl 5 的问题对于 Perl 6 的人来说是众所周知的,并且是设计目标之一。与 Perl 5 不同,Perl 6 语言扩展是根据 Perl 6 语法定义的,这是一个单独的、较小的规范。至于算子的问题,可以定义新的操作,但不能定义新的操作types。也就是说,stock 语法可以看到它有一个中缀运算符,而不需要知道它是否存在。最后,如果 ops 只能在编译时定义,这一切都会消失,我正在检查。
  • 是的,您不能在运行时定义适用于已编译代码的新运算符。所以if condition { eval "...define a new op or macro..." }对解析没有影响。此外,您无法在条件中有效地定义新运算符。 if condition { multi sub postfix:... } 没有达到预期的效果。
  • 这是一个令人难以置信的无知答案,被不知道发生了什么的人所支持。
【解决方案2】:

Perl 6 是一个规范,任何遵循该规范的程序都是 Perl 6,就像大多数其他语言一样。有许多 Perl 6 实现正在开发中。

【讨论】:

  • 换个说法,除了假设的 perl6 之外的其他东西都可以解析 Perl 6。:)
【解决方案3】:
Perl6 可以有 JIT 编译器吗?

您暗示 Perl5 不能基于“只有 perl 可以解析 Perl5”进行 JITted,但事实并非如此。即使 Perl5 程序每次运行时都可以进行不同的编译,但这并不妨碍它进行 JITted。

所以,如果 Perl5(定义最松散的语言之一)可以 JITted,为什么 Perl6 不能。

【讨论】:

    【解决方案4】:

    没有 perl6,有很多 Perl 6 编译器。 Perl 6 has a grammar, although it's written in Perl 6,只要你能理解,它就会告诉你你需要知道的一切。

    我刚刚问了拉里这个问题,因为我在São Paulo Perl Workshop 吃午饭时坐在他对面。他说现在是“只有 Perl 6 可以解析 Perl 6”,两个 Perl 上都有大写字母,这意味着与原来的说法不同。

    虽然 Perl 6 的目标是一个标准和多个实现,但您不需要特定的程序来执行此操作。没有“perl6”,尽管 Larry 在今天的演讲中使用了他的 Rakudo 别名,尽管他在示例中使用了一些不同的实现。

    【讨论】:

      【解决方案5】:

      最后我看到,Perl 6 继承了 Perl 5 的 / 字符,当需要一个术语时,它可以表示“正则表达式的开头”,或者当需要一个运算符时表示“除法”。鉴于此,以及原型,Perl 6 至少与 Perl 5 在静态标记化方面处于同一阵营。标记 Perl 6 程序的唯一方法是在 Perl 6 编译器中运行 Perl 6 解释器。海龟一路向下,再一次。

      【讨论】:

      • 但是,JavaScript 不是也有/ 字符用作注释、除法或正则表达式吗?不同之处在于 JavaScript 语法没有歧义。
      • JavaScript 没有任何类似于 Perl 的原型,因此每个标记对解析器状态和词法分析器状态都有众所周知的影响。 Perl 必须运行 BEGIN/use 的代码来正确加载其中定义的事物的可能原型。
      • (迟到了,但无论如何)这在 perl6 中不是问题,因为 / 是一个中缀运算符,你永远不能在需要一个 n 中缀运算符的地方启动一个正则表达式。但是,如果您同时定义前缀:> 和后缀:>,例如,您可以将过去的正则表达式 /1+1/ 解析为 1 和 1 的总和。但是,解析器会知道这一点并相应地进行自我纠正。无需在编译时运行任何代码来确保这一点。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-19
      • 2018-12-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多