我理解Perl语法含糊不清,而且它的歧义消除是非平凡的(sometimes involving execution of code during the compile phase)。无论如何,Perl是否具有正式语法(尽管模棱两可和/或上下文敏感)?
答案 0 :(得分:30)
来自perlfaq7
我可以获得Perl语言的BNF / yacc / RE吗?
没有BNF,但你可以用爪子 通过yacc语法的方式 perly.y在源代码分发中如果 你特别勇敢。语法 依赖于非常智能的令牌化代码, 所以要准备冒险进入toke.c 同样。
用Chaim Frenkel的话来说:“Perl's 语法不能简化为BNF。该 解析perl的工作是分布式的 yacc,lexer,smoke和 反射镜“。
要查看为什么由于上下文影响几乎不可能解析Perl的一组精彩示例,请查看Randal Schwartz's post: On Parsing Perl
此外,请参阅Simon Cozens在“Perl 5 Internals (Chapter 5. The Lexer and the Parser)”中的讨论。
请注意answer is different for Perl6:
Rakudo Perl有its own version of the grammar
答案 1 :(得分:9)
其他人之前已经在类似的问题上发布过此链接,但我认为这很有趣并且有一个很好的案例:Perl Cannot Be Parsed (A Formal Proof)。
从该链接:
[考虑]以下的恶魔 代码片段,由Randal编造 施瓦茨,并确定正确 解析它:
无论/ 25; #/;死“这死了!”;
Schwartz的Snippet可以解析两种不同的方式:如果有什么是无效的 (也就是说,没有参数), 第一个陈述是无效的分裂 上下文,其余的是一个 评论。如果有什么需要的 争论,Schwartz的Snippet解析为 用任何函数调用 匹配运算符的结果,然后a 调用die()函数。
这意味着,为了静态解析Perl,它必须是 可以从一串字符串中确定 Perl 5代码是否建立了 什么都是无形的原型 子程序。
我只是发布这部分,以表明它真的很难很快。
或者,许多代码/文本编辑器可以做一个体面的(虽然从来都不是很好)语法高亮的工作,所以你可以从那些规范开始看看他们做了什么。事实上,你激励了我,我想我会发一个相关的问题,询问哪个编辑最能突出Perl。
答案 2 :(得分:6)