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

lex*_*ore 78 javascript grammar javacc language-lawyer ecmascript-5

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

这是因为020被解释为OctalIntegerLiteral(等于16),而019显然被解释为DecimalLiteral(和等于19).由于19是大于16,019 > 020true.

令我困惑的是为什么019被解释为DecimalLiteral第一名.它是哪种产品?DecimalIntegerLiteral不允许019:

DecimalIntegerLiteral ::
    0
    NonZeroDigit DecimalDigits_opt
Run Code Online (Sandbox Code Playgroud)

OctalIntegerLiteral也不允许019(因为9不是八进制数字):

OctalIntegerLiteral ::
    0 OctalDigit
    OctalIntegerLiteral OctalDigit

OctalDigit :: one of
    0 1 2 3 4 5 6 7
Run Code Online (Sandbox Code Playgroud)

因此,从我在规范中看到的,019实际应该被拒绝,我不明白为什么它被解释为十进制整数.

我想这里有一些兼容性规则,但我找不到正式的定义.可以请任何人帮我这个吗?

(为什么我需要这个:我正在使用JavaCC为Java开发一个JavaScript/ECMAScript解析器,并且必须特别注意规范 - 以及它的偏差.)

abl*_*abl 52

从我能找到的,似乎JavaScript的某些实现不遵循该点的规范.

来自MDN网站:

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

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

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

08
Run Code Online (Sandbox Code Playgroud)

根据规范,虽然Chrome/Opera,PrestOpera和Firefox都支持它,但DecimalIntegerLiteral永远不能0直接跟随另一个十进制数字.

该错误以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
Run Code Online (Sandbox Code Playgroud)

所以,01LegacyOctalLikeDecimalIntegerLiteral(3).然后019NonOctalDecimalIntegerLiteral(2)又是DecimalIntegerLiteral(1).

  • 看看V8解析扫描器,它确实假设如果一个数字从0开始但是有一个数字8或9,那么这个数字是十进制的(虽然没有注释解释原因)https://github.com/v8/v8/ BLOB/97757e2d8c5b706f1f642340a424b38e20022a2c/src目录/ scanner.cc#L834 (4认同)
  • 这是正确的答案.Chrome似乎也有类似的问题.使用Spidermonkey评估"019"会产生"1:警告:09不是合法的ECMA-262八进制常量:019".它似乎已被退出,因为现有(重要)网站会破裂. (2认同)
  • 不确定为什么仅仅因为第二个数字是1,为什么会期望019是八进制文字?当然任何包含`9'的东西都不可以是八进制的。 (2认同)
  • @Bergi我想你应该问MDN的那些人,因为我在ECMAScript规范中找不到任何证明这种解释的点. (2认同)
  • @VitaliiFedorenko你怎么把它挖出来的印象非常深刻. (2认同)