Почему 42.toString() не работает в JS?

Отказ от ответственности

Ребята, я ДЕЙСТВИТЕЛЬНО знаю о Почему 10..toString() работает, а 10.toString() нет? существование вопроса, но дело в том, что формального объяснения он не дает.

Интерпретация спецификации файла . символ в этой конкретной позиции заключается в том, что это будет десятичная дробь. Это определяется синтаксисом числового литерала ECMAScript.

Без ссылки на стандарт нельзя доверять

Тело вопроса

Я подсознательно понимаю, что

42..toString()

обрабатывается синтаксическим анализатором как число 42., за которым следует вызов .toString().

Чего я не могу понять, так это почему переводчик не может понять, что

42.toString()

представляет собой 42, за которым следует вызов метода.

Это просто недостаток современных интерпретаторов JS или это явно указано в ES5.1?

Начиная с ES5.1 определяется Числовой литерал. как (только значительная часть определения):

NumericLiteral ::
    DecimalLiteral
    HexIntegerLiteral

DecimalLiteral ::
    DecimalIntegerLiteral . DecimalDigits(opt) ExponentPart(opt)
    . DecimalDigits ExponentPart(opt)
    DecimalIntegerLiteral ExponentPart(opt)

Я ожидаю, что последнее правило будет выбрано синтаксическим анализатором.

UPD: чтобы уточнить, этот вопрос ожидает в качестве ответа ссылки на спецификацию ES, в которой прямо указано, что интерпретатор должен вести себя так, как он.


person zerkms    schedule 25.06.2014    source источник
comment
Это пример, который я использовал в своем предыдущем комментарии?   -  person Derek 朕會功夫    schedule 25.06.2014
comment
@Derek 朕會功夫: именно так :-)   -  person zerkms    schedule 25.06.2014
comment
. в DecimalLiteral кажется необязательным.   -  person Derek 朕會功夫    schedule 25.06.2014
comment
@Derek 朕會功夫: см. строку №3   -  person zerkms    schedule 25.06.2014


Ответы (2)



Лексическая фаза процесса синтаксического анализа использует . именно из-за определения NumericLiteral, приведенного в стандарте. В определении указано, что числовой литерал (здесь DecimalLiteral) включает ., если он присутствует — см. первую строку под DecimalLiteral ::.

Поскольку 42. потребляется токеном числового литерала, следующим токеном будет toString, в котором отсутствует начальная точка, и поэтому его нельзя распознать как вызов метода.

person user4815162342    schedule 25.06.2014
comment
именно из-за определения NumericLiteral, цитируемого из стандарта --- см. правило DecimalIntegerLiteral ExponentPart(opt), в котором нет обязательного . - person zerkms; 25.06.2014
comment
@zerkms Это не обязательно, но в вашем примере оно есть, и лексер будет использовать его для токена. - person user4815162342; 25.06.2014
comment
в этом весь смысл моего вопроса - почему он так делает. И другой ответ объясняет это. В то время как этот основан на... на чем на самом деле? - person zerkms; 25.06.2014
comment
@zerkms Даже без предложения, процитированного в ответе Джесси Русака, EcmaScript все равно будет вести себя так же. Контекстно-свободные грамматики не возвращаются к лексическому анализу, чтобы попробовать другую токенизацию ввода в случае синтаксической ошибки. - person user4815162342; 25.06.2014
comment
Контекстно-свободные грамматики не восходят к лексическому анализу --- на чем основано это утверждение? Это определено в ES? Если да - где? (в этом весь смысл моего вопроса). Если нет, то как я должен знать, что стандарт ES основан на данном типе грамматики? - person zerkms; 25.06.2014
comment
@zerkms 5.1.1 и 5.1.2 ясно дают понять, что ES указывается с помощью контекстно-свободной грамматики. Кроме того, в разделе 7 прямо указано: Исходный текст программы ECMAScript сначала преобразуется в последовательность входных элементов, которые представляют собой токены, разделители строк, комментарии или пробелы. Т.е. сначала выполняется токенизация, не зависит от грамматической интерпретации ввода. - person user4815162342; 25.06.2014
comment
Это должно было быть включено в ответ, потому что это то, о чем был вопрос (я упоминаю об этом в третий раз в этом разговоре) - person zerkms; 25.06.2014
comment
@zerkms Вы ясно изложили это, да. Однако вопрос уже цитирует стандарт, и ответ явно относится к этой цитате. - person user4815162342; 25.06.2014
comment
Я обещаю, что это последний комментарий здесь :-D Как из вопроса, так и из этого ответа не очевидно, почему синтаксический анализатор должен предпочитать последнее правило DecimalLiteral первому. - person zerkms; 25.06.2014
comment
@zerkms На самом деле, он должен предпочесть первое. :) Может быть, это и не очевидно, но вытекает из общепонятного значения обозначений, использованных в вашей цитате. Учтите следующее: если бы лексер мог свободно интерпретировать ввод 42.toString как 42, за которым следует ., за которым следует toString, ввод 42.3 стал бы синтаксической ошибкой. Если бы стандарт позволял лексеру заглядывать вперед или возвращаться к нему после того, как синтаксический анализ показал неудачу, то он не использовал бы нотацию, подобную БНФ, и не упоминал бы контекстно-свободные грамматики в первую очередь. - person user4815162342; 25.06.2014