Сучок, предполагающий пунктуацию / строку, если десятичному числу не предшествует числовое значение?

Учтите следующее:

A) {{ form.vars.attr.dimensions.width * .1875 }}
B) {{ form.vars.attr.dimensions.width * 0.1875 }}

куда form.vars.attr.dimensions.width является целым числом

Ниже дамп form.vars.attr.dimensions,

array:2 [
"width" => 1600
"height" => 478
]

Пример А скинет следующее исключение:

Неожиданный токен «пунктуация» значения «.».

Пример Б работает правильно и выводит 300.0,

Я понимаю, что это, скорее всего, интерпретировать значение как строку, но мой вопрос будет Зачем? Я бы подумал, что, поскольку он не заключен в кавычки, его не следует рассматривать как буквальный. Я понимаю, что могу обойти это с такими вещами, как number_format, предшествующие нули и т. Д. Мне просто искренне любопытно, почему Twig не может правильно идентифицировать этот десятичный знак. Или, может быть, я что-то упускаю.

более того, та же логика, применяемая в vanilla PHP, не создает такой ситуации:

<?php
$val = 1600;
var_dump($val * .1875);
// float(300)
?>

2

Решение

. в .1875 уже был идентифицирован как знак препинания на первом шаге рендеринга шаблона.

Документация Twig охватывает этот процесс в Внутренности ветки. На первом этапе:

Лексер токенизирует исходный код шаблона в поток токенов

В разделе документации Лексер, он показывает способ преобразования некоторого исходного кода в поток токенов. Если мы сделаем это с вашими двумя примерами:

$ex1 = '{{ form.vars.attr.dimensions.width * 0.1875 }}';
$ex2 = '{{ form.vars.attr.dimensions.width * .1875 }}';

$stream1 = $twig->tokenize(new Twig_Source($ex1, 'example1'));
$stream2 = $twig->tokenize(new Twig_Source($ex2, 'example2'));

Вывод выглядит так:

Example 1:               Example 2:

VAR_START_TYPE()         VAR_START_TYPE()
NAME_TYPE(form)          NAME_TYPE(form)
PUNCTUATION_TYPE(.)      PUNCTUATION_TYPE(.)
NAME_TYPE(vars)          NAME_TYPE(vars)
PUNCTUATION_TYPE(.)      PUNCTUATION_TYPE(.)
NAME_TYPE(attr)          NAME_TYPE(attr)
PUNCTUATION_TYPE(.)      PUNCTUATION_TYPE(.)
NAME_TYPE(dimensions)    NAME_TYPE(dimensions)
PUNCTUATION_TYPE(.)      PUNCTUATION_TYPE(.)
NAME_TYPE(width)         NAME_TYPE(width)
OPERATOR_TYPE(*)         OPERATOR_TYPE(*)
NUMBER_TYPE(0.1875)      PUNCTUATION_TYPE(.)     <----
VAR_END_TYPE()           NUMBER_TYPE(1875)
EOF_TYPE()               VAR_END_TYPE()
EOF_TYPE()

На следующем этапе процесса анализатор пытается преобразовать поток токенов в дерево, и токен пунктуации не имеет смысла после оператора, который вызывает ошибку, которую вы видите.

Насколько лексер Twig работает таким образом на первом этапе, если вы проверите источник, лексер выражения проходит по входной строке, последовательно применяя различные регулярные выражения. Число регулярное выражение

'/[0-9]+(?:\.[0-9]+)?/A'

который не соответствует .1875и на следующем этапе . идентифицируется как пунктуация

Этот ответ не поможет, если вы пытаетесь найти способ заставить его работать с десятичными числами без начальных нулей, но похоже, что вы больше заинтересованы в том, чтобы просто понять, как это работает, так что, надеюсь, это будет полезно ,

2

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector