为什么019不是JavaScript语法错误?或者为什么是019> 020

时间:2015-01-24 15:15:41

标签: javascript grammar language-lawyer ecmascript-5 javacc

如果我在JavaScript控制台中输入019 > 020(在Chrome和Firefox中测试过),我会得到答案true

这是因为020被解释为OctalIntegerLiteral(等于16),而019显然被解释为DecimalLiteral(等于{{ 1}})。由于19大于1916019 > 020

让我感到困惑的是,为什么true首先被解释为019。它是哪种产品? DecimalLiteral不允许DecimalIntegerLiteral

019

DecimalIntegerLiteral :: 0 NonZeroDigit DecimalDigits_opt 也不允许OctalIntegerLiteral(因为019不是八进制数字):

9

因此,从我在规范中看到的情况来看,OctalIntegerLiteral :: 0 OctalDigit OctalIntegerLiteral OctalDigit OctalDigit :: one of 0 1 2 3 4 5 6 7 实际上应该被拒绝,我不明白为什么它被解释为十进制整数。

我想这里有某种兼容性规则,但我找不到正式的定义。可以请任何人帮助我吗?

(为什么我需要这个:我开发JavaScript/ECMAScript parser for Java with JavaCC并且必须特别注意规范 - 以及它的偏差。)

1 个答案:

答案 0 :(得分:52)

根据我的发现,似乎JavaScript的某些实现不符合该点的规范。

来自MDN site:

  

请注意,十进制文字可以以零(0)开头,后跟   另一个十进制数字,但如果前导0之后的下一个数字是   小于8时,该数字被解析为八进制数。这不会   扔进JavaScript,请参阅bug 957513。另请参阅有关的页面   parseInt函数()。

这仍然无法解释为什么019 == 19,因为前导0之后的下一个数字是1,因此整数应该被解析为八进制。但引用的bug似乎与您的案例有关。它的描述说:

  

以下JavaScript程序应该抛出错误:

08
     

根据规范,DecimalIntegerLiteral永远不能直接0   然后是另一个十进制数字,虽然Chrome / Opera,PrestOpera,   和Firefox确实支持它。

该错误已关闭为WONTFIX

但是,根据下一版的草稿,019将是一个有效的十进制文字,其值等于19:

https://people.mozilla.org/~jorendorff/es6-draft.html#sec-additional-syntax-numeric-literals

(我已经标记了相关规则)

The syntax and semantics of 11.8.3 is extended as follows except that 
this extension is not allowed for strict mode code:

[...]

DecimalIntegerLiteral ::
    0
    NonZeroDigit DecimalDigits_opt
    NonOctalDecimalIntegerLiteral                         // (1)

NonOctalDecimalIntegerLiteral ::
    0 NonOctalDigit
    LegacyOctalLikeDecimalIntegerLiteral NonOctalDigit    // (2)
    NonOctalDecimalIntegerLiteral DecimalDigit

LegacyOctalLikeDecimalIntegerLiteral ::
    0 OctalDigit                                          // (3)
    LegacyOctalLikeDecimalIntegerLiteral OctalDigit

所以01LegacyOctalLikeDecimalIntegerLiteral(3)。然后019NonOctalDecimalIntegerLiteral(2),而DecimalIntegerLiteral(1)又是{{1}}。