Почему плюс и унарный плюс ведут себя странно в синтаксисе массива?

После этого вопроса об операторе "плюс" у меня есть дополнительный вопрос. Мы знаем разницу между plus и uplus, и, таким образом, 1+2 разрешается в 3, так же как 1++2 или даже 1++++++++2. Странная вещь происходит в синтаксисе массива, рассмотрим этот пример:

>> [1 ++ 2]
ans =
     1     2 % Two unary plusses
>> [1 + + 2]
ans =
     3 % A normal plus and a unary one
>> [1++2]
ans =
     3 % A normal plus and a unary one

То же самое работает с несколькими плюсами, [1 +++..+++ 2], поэтому со всеми плюсами последовательно в середине генерируется [1 2], все остальные комбинации (насколько я тестировал) приводят к 3.

Насколько я знаю, пробелы имеют ограниченное значение в MATLAB; exp(3*x/y) совпадает с exp( 3 * x / y ). Их можно использовать при создании массивов: [1 2] будет генерировать массив 1 на 2, и есть несколько других применений, но разделение операторов не входит в их число.

Поэтому мой вопрос: почему [1 ++ 2] и [1 + + 2] разрешаются по-разному?

Обратите внимание, что minus и uminus имеют такое же поведение, и что синтаксический анализатор достаточно волшебен, чтобы анализировать [1;;;3++ + + +--+ + ++4,;;;,;] отлично подходит для [1;7].


person Adriaan    schedule 05.10.2018    source источник
comment
Но мы все знаем, что это бессмысленный вопрос, потому что мы никогда не будем использовать такой синтаксис в нашем коде, верно? Верно?   -  person Cris Luengo    schedule 05.10.2018
comment
На самом деле, я думаю, что синтаксический анализатор должен выдавать ошибку (или, по крайней мере, выдавать предупреждение) при неоднозначном синтаксисе, подобном этому. И я думаю, что использование пробела в качестве разделителя элементов в массивах было ошибкой. Пожалуйста, используйте запятые!   -  person Cris Luengo    schedule 05.10.2018
comment
@Крис не тот язык ;)   -  person Andras Deak    schedule 05.10.2018


Ответы (1)


Я подозреваю, что это связано с тем, как анализируются числовые литералы. В частности, рассмотрим следующие сложные примеры:

>> [1+2i]

ans =

   1.0000 + 2.0000i

>> [1 +2i]

ans =

   1.0000 + 0.0000i   0.0000 + 2.0000i

>> [1 + 2i]

ans =

   1.0000 + 2.0000i

Существует конфликт между пробелом как разделителем массива и пробелом как частью комплексного числа.

Я считаю, что синтаксический анализатор был написан таким образом, что он пытается как можно разумнее понять комплексные числа (в отличие от сложных массивов). Это может легко привести к нетривиальному поведению при синтаксическом анализе выражений, включающих сложение/вычитание и пробелы.


Чтобы быть немного более конкретным:

1 ++ 2 может интерпретироваться как 1 +2, так как множественные унарные плюсы по-прежнему являются унарными плюсами, а унарные плюсы могут действовать только на 2.

Но 1 + + 2 может быть проанализировано как 1 + (+ 2), где последний плюс используется как унарный плюс, оставляя 1 + 2, который является одним «комплексным» числом.


Дальнейшее продолжение после любознательный комментарий от @Adriaan:

[...] [1 ++ + 2] это [1 2], но [1 + ++ 2] это 3

Так что я правильно предполагаю, что синтаксический анализатор перемещается справа налево.

  • [1 ++ + 2] -> [1 ++ (+ 2)] -> [1 ++ 2] по сравнению с
  • [1 + ++ 2] -> [1 + (++ 2)] -> [1 + 2].

Это также означает, что любая комбинация [1 + ...2] (где есть только один плюс в первом связанном блоке плюсов) даст вам [3], тогда как, если первый блок плюсов содержит два или более плюсов, вы получите [1 2]. Несколько псевдослучайных тестов, похоже, подтвердили это поведение.

Конечно, пока The MathWorks не сделает свой парсер открытым или задокументированным, мы можем только догадываться.

person Andras Deak    schedule 05.10.2018
comment
Таким образом, для случая [1 ++ + 2] это [1 2], а [1 + ++ 2] это 3, синтаксический анализатор читает унарный плюс в первом случае, делая все последующие плюсы унарными, тогда как во втором случае он читает сложение, за которым следуют унарные плюсы? - person Adriaan; 05.10.2018
comment
@ Адриан, я думаю, он идет справа налево. [1 ++ + 2] -> [1 ++ (+ 2)] -> [1 ++ 2] против [1 + ++ 2] -> [1 + (++ 2)] -> [1 + 2]. - person Andras Deak; 05.10.2018
comment
@ Адриан, посмотри мой обновленный пост с правильной гипотезой. - person Andras Deak; 05.10.2018