4slovo/expression

text formula converter to expression

v2.1.3 2019-10-10 12:25 UTC

README

Модуль 4slovo/expression позволяет преобразовывать псевдокод в php-код, это позволяет:

  1. вынести бизнес логику на конфигурационный уровень
  2. ограничить языковые конструкции до разрешённых в псевдокоде
  3. упрощать синтаксис операций (например, для сложения дат можно использовать операцию +)

Пример, формулу расчёта площади круга можно записать как:

$area = 3.14 * ($radius ** 2);

что будет преобразовано в php-код, производящий расчёт площади круга в зависимости от
переданной переменной $radius

Пример:

$expressionText = '$radius = 2; $area = 3.14 * ($radius ** 2);';
$codeContext = new CodeContext();
$codeExecutor = new CodeExecutor();
$variableName = '$result';
$areaResult = $codeExecutor
    ->setCode($expressionText)
    ->setCodeContext($codeContext)
    ->execute()
    ->getVariableByName('$area');

echo $areaResult; # выведет 12.56  

Поддерживаемые операции

Сложение

Знак Класс операции
+ addOperation

Допустимые операции с типами

Тип левого операнда Тип правого операнда Тип результата Пример
int int int 1 + 1 == 2
int float float 1 + 1.1 == 2.1
float int float 1.1 + 1 == 2.1
float float float 1.1 + 1.2 == 2.3
money money money 1$ + 2$20 == 3$20
dateInterval dateInterval dateInterval 1 day + 2 days == 3 days
dateInterval dateTime dateTime 1 day + 2018.01.02 == 2018.01.03
dateTime dateInterval dateTime 2018.01.02 + 1 day == 2018.01.03

Вычитание

Знак Класс операции
- SubtractionOperation

Допустимые операции с типами

Тип левого операнда Тип правого операнда Тип результата Пример
int int int 2 - 1 == 1
int float float 2 - 1.1 == 0.9
float int float 1.1 - 2 == -0.9
float float float 2.2 - 1.1 == 1.1
money money money 2$ - 1$ == 1$
dateInterval dateInterval dateInterval 2 day - 1 day == 1 day
dateTime dateTime dateInterval 2018.01.02 - 2018.01.01 == 1 day
dateTime dateInterval dateTime 2018.01.02 - 1 day == 2018.01.01

Умножение

Знак Класс операции
* MultiplyOperation

Допустимые операции с типами

Тип левого операнда Тип правого операнда Тип результата Пример
int int int 2 * 2 == 4
int float float 2 * 1.1 == 2.2
float int float 1.1 * 2 == 2.2
float float float 1.1 * 1.1 == 1.21
money int money 2$ * 2 == 4$
money float money 2$ * 2.1 == 4$20

Деление

Знак Класс операции
/ DivisionOperation

Допустимые операции с типами

Тип левого операнда Тип правого операнда Тип результата Пример
int int float 5 / 2 == 2.5
int float float 5 * 1.1 == 2.2
float int float 5 / 2.2 == 2.272727...
float float float 1.21 / 1.1 == 1.1
money int money 2$ / 2 == 1$
money float money 2$ / 2.1 == $95

Возведение в степень

Знак Класс операции
** ExponentiationOperation

Допустимые операции с типами

Тип левого операнда Тип правого операнда Тип результата Пример
int int int 2 ** 3 == 8
int float float 2 ** 1.1 == 2.1435...
float int float 2.2 ** 2 == 4.84
float float float 2.2 ** 2.2 == 5.6666...

Остаток от деления

Знак Класс операции
% RemainderOfDivisionOperation

Допустимые операции с типами

Тип левого операнда Тип правого операнда Тип результата Пример
int int int 5 % 3 == 2
int float int 5 % 3.9 == 2
float int int 5.5 % 3 == 2
float float int 5.5 % 3.9 == 2

##Операции сравнения

Равно

Знак Класс операции
== EqualOperation

Допустимые операции с типами

Тип левого операнда Тип правого операнда Тип результата Пример Результат
int int boolean 1 == 1 true
int int boolean 1 == 2 false
float float boolean 1.1 == 1.1 true
float float boolean 1.1 == 1.2 false
money money boolean 100$ == 100$ true
money money boolean 100$ == 200$ false
dateInterval dateInterval boolean 2 day == 2 day true
dateInterval dateInterval boolean 2 day == 3 day false
dateTime dateTime boolean 2018.06.19 15:06:00 == 2018.06.19 15:06:00 true
dateTime dateTime boolean 2018.06.19 15:06:00 == 2018.06.19 15:06:01 false
string string boolean 'a' == 'a' true
string string boolean 'a' == 'b' false

Не равно

Знак Класс операции
!= EqualOperation

Допустимые операции с типами

Тип левого операнда Тип правого операнда Тип результата Пример Результат
int int boolean 1 != 1 false
int int boolean 1 != 2 true
float float boolean 1.1 != 1.1 false
float float boolean 1.1 != 1.2 true
money money boolean 100$ != 100$ false
money money boolean 100$ != 200$ true
dateInterval dateInterval boolean 2 day != 2 day false
dateInterval dateInterval boolean 2 day != 3 day true
dateTime dateTime boolean 2018.06.19 15:06:00 != 2018.06.19 15:06:00 false
dateTime dateTime boolean 2018.06.19 15:06:00 != 2018.06.19 15:06:01 true
string string boolean 'a' != 'a' false
string string boolean 'a' != 'b' true

Больше

Знак Класс операции
> GreaterOperation

Допустимые операции с типами

Тип левого операнда Тип правого операнда Тип результата Пример Результат
int int boolean 3 > 2 true
int int boolean 3 > 3 false
int int boolean 3 > 4 false
float float boolean 3.14 > 3.13 true
float float boolean 3.14 > 3.14 false
float float boolean 3.14 > 3.15 false
money money boolean 301$ > 300$ true
money money boolean 300$ > 300$ false
money money boolean 300$ > 301$ false
dateInterval dateInterval boolean 6 day > 5 day true
dateInterval dateInterval boolean 6 day > 6 day false
dateInterval dateInterval boolean 6 day > 7 day false
dateTime dateTime boolean 2018.06.19 15:06:00 > 2018.06.19 15:05:59 true
dateTime dateTime boolean 2018.06.19 15:06:00 > 2018.06.19 15:06:00 false
dateTime dateTime boolean 2018.06.19 15:06:00 > 2018.06.19 15:06:01 false
string string boolean 'a' > 'a' false
string string boolean 'a' > 'b' false
string string boolean 'b' > 'a' true

Меньше

Знак Класс операции
< LessOperation

Допустимые операции с типами

Тип левого операнда Тип правого операнда Тип результата Пример Результат
int int boolean 3 < 4 true
int int boolean 3 < 3 false
int int boolean 3 < 2 false
float float boolean 3.14 < 3.15 true
float float boolean 3.14 < 3.14 false
float float boolean 3.14 < 3.13 false
money money boolean 300$ < 301$ true
money money boolean 300$ < 300$ false
money money boolean 301$ < 300$ false
dateInterval dateInterval boolean 6 day < 7 day true
dateInterval dateInterval boolean 6 day < 6 day false
dateInterval dateInterval boolean 6 day < 5 day false
dateTime dateTime boolean 2018.06.19 15:06:00 < 2018.06.19 15:06:01 true
dateTime dateTime boolean 2018.06.19 15:06:00 < 2018.06.19 15:06:00 false
dateTime dateTime boolean 2018.06.19 15:06:00 < 2018.06.19 15:05:59 false
string string boolean 'a' < 'a' false
string string boolean 'a' < 'b' true
string string boolean 'b' < 'a' false

Больше или равно

Знак Класс операции
>= GreaterOrEqualOperation

Допустимые операции с типами

Тип левого операнда Тип правого операнда Тип результата Пример Результат
int int boolean 3 >= 2 true
int int boolean 3 >= 3 true
int int boolean 3 >= 4 false
float float boolean 3.14 >= 3.13 true
float float boolean 3.14 >= 3.14 true
float float boolean 3.14 >= 3.15 false
money money boolean 301$ >= 300$ true
money money boolean 300$ >= 300$ true
money money boolean 300$ >= 301$ false
dateInterval dateInterval boolean 6 day >= 5 day true
dateInterval dateInterval boolean 6 day >= 6 day true
dateInterval dateInterval boolean 6 day >= 7 day false
dateTime dateTime boolean 2018.06.19 15:06:00 >= 2018.06.19 15:05:59 true
dateTime dateTime boolean 2018.06.19 15:06:00 >= 2018.06.19 15:06:00 true
dateTime dateTime boolean 2018.06.19 15:06:00 >= 2018.06.19 15:06:01 false
string string boolean 'a' >= 'a' true
string string boolean 'a' >= 'b' false
string string boolean 'b' >= 'a' true

Меньше или равно

Знак Класс операции
<= LessOrEqualsOperation

Допустимые операции с типами

Тип левого операнда Тип правого операнда Тип результата Пример Результат
int int boolean 3 <= 4 true
int int boolean 3 <= 3 true
int int boolean 3 <= 2 false
float float boolean 3.14 <= 3.15 true
float float boolean 3.14 <= 3.14 true
float float boolean 3.14 <= 3.13 false
money money boolean 300$ <= 301$ true
money money boolean 300$ <= 300$ true
money money boolean 301$ <= 300$ false
dateInterval dateInterval boolean 6 day <= 7 day true
dateInterval dateInterval boolean 6 day <= 6 day true
dateInterval dateInterval boolean 6 day <= 5 day false
dateTime dateTime boolean 2018.06.19 15:06:00 <= 2018.06.19 15:06:01 true
dateTime dateTime boolean 2018.06.19 15:06:00 <= 2018.06.19 15:06:00 true
dateTime dateTime boolean 2018.06.19 15:06:00 <= 2018.06.19 15:05:59 false
string string boolean 'a' <= 'a' true
string string boolean 'a' <= 'b' true
string string boolean 'b' <= 'a' false

Встроенные функции

date - приведение даты и времени к дате

Допустимые операции с типами

Тип параметра Тип результата Пример
dateTime dateTime (dateTime) date(2018.01.02 22:32:18) == 2018.01.02

dateFormat - преобразование даты и времени к строке

Допустимые операции с типами

Тип параметра Тип результата Пример
dateTime string (string) dateFormat(2018.01.02, 'Y.m.d') == '2018.01.02'

daysInYear - определение числа дней в году для указанной даты

Допустимые операции с типами

Тип параметра Тип результата Пример
dateTime int (int) daysInYear(2018.01.02) == 365
(int) daysInYear(2016.01.02) == 366

days - определение числа дней во временном интервале

Допустимые операции с типами

Тип параметра Тип результата Пример
dateInterval int (int) days(2 days) == 2
(int) days(2016.01.03 - 2016.01.01) == 2
int dateInterval (dateInterval) days(1) == 1 day

firstYearDay - преобразование даты в дату первого числа года

Допустимые операции с типами

Тип параметра Тип результата Пример
dateTime dateTime (dateTime) firstYearDay(2018.06.12 08:56:10) == 2018.01.01 00:00:00

int - преобразование числа с плавающей точкой в целое число

Допустимые операции с типами

Тип параметра Тип результата Пример
float int int(1.1) == 1
float int int(3.9) == 3
money int int(1$01) == 101

money - преобразование числа в деньги

Допустимые операции с типами

Тип параметра Тип результата Пример
float money money(100.1) == 1$
int money money(100) == 1$

min - определение минимального значения

Допустимые операции с типами

Тип параметра 1 Тип параметра N Тип результата Пример
int int int (int) min(3,1,2) == 1
float float float (float) min(3.1, 1.2, 2.3) == 1.2
money money money (money) min(3$, 1$, 2$) == $1
dateTime dateTime dateTime (dateTime) min(2018.01.01, 2019.01.01, 2015.01.01) == 2015.01.01
dateInterval dateInterval dateInterval (dateInterval) min(3 days, 1 day, 2 days) == 1 day

max - определение минимального значения

Допустимые операции с типами

Тип параметра 1 Тип параметра N Тип результата Пример
int int int (int) max(3,1,2) == 3
float float float (float) max(3.1, 1.2, 2.3) == 3.1
money money money (money) max(3$, 1$, 2$) == $3
dateTime dateTime dateTime (dateTime) max(2018.01.01, 2019.01.01, 2015.01.01) == 2019.01.01
dateInterval dateInterval dateInterval (dateInterval) max(3 days, 1 day, 2 days) == 3 days

isNull - определение является ли значение нулевым

Допустимые операции с типами

Тип параметра Тип результата Пример
null boolean (boolean) isNull(null) == true
int boolean (boolean) isNull(3) == false
float boolean (boolean) isNull(3.1) == false
money boolean (boolean) isNull(3$) == false
dateTime boolean (boolean) isNull(2018.01.01) == false
dateInterval boolean (boolean) isNull(3 days) == false

isNotNull - определение является ли значение не нулевым

Допустимые операции с типами

Тип параметра Тип результата Пример
null boolean (boolean) isNull(null) == false
int boolean (boolean) isNull(3) == true
float boolean (boolean) isNull(3.1) == true
money boolean (boolean) isNull(3$) == true
dateTime boolean (boolean) isNull(2018.01.01) == true
dateInterval boolean (boolean) isNull(3 days) == true

floor - округление до ближайшего меньшего целого (для денег до мажорных единиц)

Допустимые операции с типами

Тип параметра Тип результата Пример
float float (int) floor(100.23) == 100
money money (money) floor(1$23) == 1$

ceil - округление до ближайшего большего целого (для денег до мажорных единиц)

Допустимые операции с типами

Тип параметра Тип результата Пример
float float (int) ceil(100.23) == 101
money money (money) ceil(1$23) == 2$

round - округление по математическим правилам (для денег до мажорных единиц)

Допустимые операции с типами

Тип параметра Тип результата Пример
float float (int) round(100.5) == 101
money money (money) round(1$50) == 2$

printR - вывод значения в формате print_r

Тип параметра Тип результата Пример
произвольный тип null printR(1); // выведет 1

varDump - вывод значения в формате var_dump

Тип параметра Тип результата Пример
произвольный тип null varDump(1); // выведет int(1)

Встроенные функции для работы с массивами

array - создание массива

Тип параметра 1 Тип параметра N Тип результата Пример
произвольный тип произвольный тип array array(1$, 2.0, 3);

getArrayValue - получение значения из массива по ключу

Тип параметра 1 Тип параметра 2 Тип результата Пример
array int или string (ключ) произвольный тип (значение) $list = array(1, 2, 3);
$result = (int)getArrayValue($list, 2);
// переменная $result будет содержать значение 3его элемента массива

setArrayValue - установка значения в массив по ключу

Тип параметра 1 Тип параметра 2 Тип параметра 3 Тип результата Пример
array int или string (ключ) произвольный тип (значение) null $list = array(1, 2, 3);
setArrayValue($list, 2, 5);
// 3ий элемент массива будет содержать значение 5

arrayKeyExists - проверка существования ключа в массиве

Тип параметра 1 Тип параметра 2 Тип результата Пример
int или string (ключ) array boolean $list = array(1, 2, 3);
$resultTrue = arrayKeyExists(0, $list);
$resultFalse = arrayKeyExists(3, $list);

reset - сброс указателя массива на первый элемент

Тип параметра 1 Тип результата Пример
array произвольный тип (значение) $list = array(1, 2, 3);
$firstElement = (int) reset($list);
// $firstElement = 1

end - сброс указателя массива на последний элемент

Тип параметра 1 Тип результата Пример
array произвольный тип (значение) $list = array(1, 2, 3);
$lastElement = (int) end($list);
// $lastElement = 3

next - передвинуть указатель массива вперёд

Тип параметра 1 Тип результата Пример
array произвольный тип (значение) $list = array(1, 2, 3);
$secondElement = (int) next($list);
// $secondElement = 2

prev - передвинуть указатель массива назад

Тип параметра 1 Тип результата Пример
array произвольный тип (значение) $list = array(1, 2, 3, 4);
end($list);
$thirdElement = (int) prev($list);
// $thirdElement = 3

key - получение ключа элемента на котором находится указатель массива

Тип параметра 1 Тип результата Пример
array int или string (или null если указатель находится вне массива) $list = array(1, 2, 3, 4);
$firstElementKey = key($list);
// $firstElementKey = 0

count - определение размера массива

Тип параметра 1 Тип результата Пример
array int $list = array(1, 2, 3);
$listSize = (int) count($list);
// $listSize = 3

arrayKeys - получение ключей массива

Тип параметра 1 Тип результата Пример
array array $list = (array) arrayKeys(array(1, 3, 2)); // $list = array(0, 1, 2)

sort - сортировка элементы массива в порядке возрастания

Тип параметра 1 Тип результата Пример
array array $list = (array) sort(array(1, 3, 2)); // $list = array(1, 2, 3)

rsort - сортировка элементы массива в порядке убывания

Тип параметра 1 Тип результата Пример
array array $list = (array) rsort(array(1, 3, 2)); // $list = array(3, 2, 1)

asort - сортировка ключей массива в порядке возрастания

Тип параметра 1 Тип результата Пример
array array $list = (array) arrayKeys(asort(array(1, 3, 2))); // $list = array(0, 2, 1)

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

Тип параметра 1 Тип результата Пример
array array $list = (array) arrayKeys(arsort(array(1, 3, 2))); // $list = array(0, 2, 1)

Присваивание

Пример Результат
$a = 1; создаётся переменная $a со значением 1
$i = 1; $i = $i + 1; создаётся переменная $i со значением 1, а затем инициализируется значением 2

Тернарный условный оператор

Пример Результат
1 > 2 ? 1 : 2 2
1 < 2 ? 1 : 2 1
1 < 2 && 2 < 3 ? 1 : 2 1
1 < 2 && 2 > 3 ? 1 : 2 2
1 < 2 ? 1 + 1 : 2 + 2 2
1 > 2 ? 1 + 1 : 2 + 2 4

Условный оператор if

синтаксис:
if(conditionExpression){ doStatementList }
, где
conditionExpression - логическое выражение, пока оно возвращает true - цикл не завершается
doStatementList - список инструкций который необходимо многократно выполнить

Пример Результат
if(1 > 2) { $a = 1; } переменная $a будет содержать значение 1

Цикл for

синтаксис:
for(firstStatement; conditionExpression, eachStepStatement){ doStatementList }
, где
firstStatement - инструкция выполняющаяся первой
conditionExpression - логическое выражение, пока оно возвращает true - цикл не завершается
eachStepStatement - инструкция выполняющаяся каждый шаг
doStatementList - список инструкций который необходимо многократно выполнить

Пример Результат
for($i = 1; $i < 10; $i = $i + 1) { $a = $i; } переменная $a будет содержать значение 9

Приоритет операций

Чем больше приоритет, тем раньше будет выполнена операция

Обозначение операции Приоритет
! 17
*, /, % 16
+, - 15
>
>=
<
<=
13
== 12
&& 8
|| 7
= 4

В выражениях можно использовать скобки для изменения стандартных приоритетов

Переменные

Переменные в выражениях должны начинаться с символа $, например, $creditAmount, $creditPeriod ...

Типы

Поддерживается работа с типами: boolean, int, float, money, dateTime, dateInterval, null, string

Пользовательские функции

В выражения можно внедрять пользовательские функции для расширения базового функционала Пример пользовательской функции: (money) annuityPayment($yearPercent, $creditAmount, $creditMonths). Название функции должно начинаться с указания возвращаемого типа и иметь набор параметров, заключённых в круглые скобки, если параметров нет, то скобки () всё-равно должны присутствовать. В качестве параметров функции могут использоваться переменные, выражения и типы. Пример использования пользовательской функции можно найти в тесте: TestExpression::testExpressionFunction

Комментарии

синтаксис:
/* многострочный комментарий */

Пример Результат
/* Пример */ 1 + 1 /* комментария */ 2