У меня есть движок, который выполняет некоторые математические и логические операции, беря формулы, операнды и операторы из файла.
Все операции выполняются в eval
область и окончательный результат сохраняется в другом файле.
Эти файлы часто передаются по сети, поэтому я стараюсь минимизировать их, удаляя все пробелы до и после операций.
Насколько я знаю, в этом вопросе нет строгих правил, однако я наткнулся на это поведение:
$x = 1;
$result = $x++-++$x; // works
$result = $x+++++$x; // fails
$result = $x++ + ++$x; // works again
Почему PHP смущен синтаксисом «+++++», но принимает «++ — ++»? Как
«плюс» лучше чем «минус»?
Есть ли где-нибудь список операторов, которые являются чувствительными
о пространствах?
Парсер PHP ищет ++
подписать до последнего +
знак и синтаксис ($x++)++
не имеет смысла, в связи с тем, что оператор приращения должен применяться к переменной (а не целое число, которое является результатом первого $x++
).
Приоритет операций оператора можно найти здесь:
http://php.net/manual/en/language.operators.precedence.php
$x+++++$x;
^ php parser starts here, find $x++
^ here there is a new ++, which has hight precedence to the next + char
^ here is the last +, which the php parser will find last.
Когда два ++
, ++
разделить со знаком минус, код на самом деле $x++ - ++$x
, который может понять синтаксический анализатор PHP.
Это также причина, почему $x++ + ++$x
работает.
Ответ в том, что парсер ищет более длинные токены, прежде чем искать более короткие. Поэтому ++++++ становится ++ ++ +, что не воспринимается интерпретатором.
PHP — один из многих языков, который заимствует свою грамматику выражений из C, поэтому эта заметка может быть вам интересна. В проект С11, В разделе 6.4 пункта 6 приведен пример:
Фрагмент программы x +++++ y анализируется как x ++ ++ + y, что нарушает ограничение на операторы приращения, даже если синтаксический анализ x ++ + ++ y может привести к правильному выражению.
Еще немного дополнительной информации. Когда скрипт PHP «лексирован», то есть когда он сканируется, проверяются токены, составляющие скрипт. Пара символов, таких как «++», обозначает токен приращения следующим образом:
<ST_IN_SCRIPTING>"++" {
RETURN_TOKEN(T_INC);
}
Это «правило» находится в файле Zend / language_scanner.l который сопровождает PHP при загрузке и установке. Единственный способ, которым скрипт при сканировании становится понятным для лексера относительно пре- или постинкрементных переменных, — это если есть какой-то вид разграничения, такой как интервал, чтобы каждый «+» был правильно оценен в контексте.
Обратите внимание, что написание кода, подобного следующему, не рекомендуется:
<?php
$x=0;
echo $x++ + ++$x;
даже если это будет правильно сказано. Причина для возражения против этого стиля кодирования состоит в том, что он может быть менее чем очевидным для человеческого мозга относительно того, что действительно происходит. Порядок оценки не такой, как может показаться, то есть переменная, которая постинкрементно добавляется, а затем добавляется к себе с ее предварительно инкрементным значением.
В соответствии с опкоды, до и после приращения происходят до сложение происходит. Также обратите внимание, что постинкремент возвращает значение переменной, а затем увеличивает его. Итак, изначально, $ x присваивается значение 0. Затем оно постинкрементно, так что временная переменная возвращается со значением ноль. Затем $ x увеличивается, чтобы получить значение один. Затем, $ x предварительно увеличивается, и поэтому $ x перемещается со значения от одного до двух, и его временная переменная оценивается как два. Наконец, добавляются две временные переменные, так что 0 + 2 == 2
; увидеть Вот так же как Вот.
Кроме того, отличное чтение Вот.
Кстати, в этом случае PHP соответствует своему языку программирования C; увидеть Вот.