Требуется реализация сортировочной станции на PHP, интерпретировать и анализировать строку, выполнять математическое сравнение и возвращать логический результат.
-
01-10-2019 - |
Вопрос
Я ищу что-то, что может интерпретировать строку в php и выполнять простые математические вычисления, а затем возвращать логический результат относительно того, является ли выражение истинным или ложным.
Например:
- Сью вводит «3*{mysalary}/9=10000».
- PHP разбивает это на два выражения: взорвать('=',string);
- PHP берет мой список полей базы данных и заменяет все поля с разделителями «{}» данными (приведенными к типу int)
- Затем PHP оценивает математическое выражение
- php затем сравнивает левую сторону с правой стороной
- выдается логический результат.
Это может показаться сложным, но все должно быть очень просто.Вот ограничения:1/ математические операторы закреплены за:+ - / * 2 / Операторы сравнения прикреплены к:=> <> = <= 3/ не нужны сравнения с плавающей запятой, все можно сделать на целочисленном уровне.Таким образом, любые деления при необходимости можно округлить или просто округлить конечный результат.
Всегда будет только два выражения с одним оператором сравнения.Если вообще возникнет какая-либо ошибка, мы просто вернем false.
Кто-нибудь уже видел что-то, что может это сделать?Я знаю, что могу что-то сделать, но зачем изобретать велосипед, верно?
Если вы ничего не видели, не могли бы вы перечислить некоторые «подводные камни» или предостережения, о которых вы можете подумать при создании этого.
Прочитав еще немного, я понял, что мог бы использовать алгоритм сортировочной станции.Есть ли у кого-нибудь реализация этого на PHP?
Я знаю, что eval может быть простым способом выполнить это, однако меня беспокоит то, что пользователь может очень легко что-то сломать, используя этот метод, или вызвать синтаксические ошибки.Я бы предпочел не включать его в решение, а если и сделаю, то придется жестко контролировать его использование.
Спасибо.
Джейсон
Решение
Взгляните на evalMath класс на PHPClasses.Это должно делать практически все, что вы хотите, включая замену переменных (например, установку значения для «mysalary» в вашем примере перед оценкой выражения).
Другие советы
Есть механизм синтаксического анализа выражений (реализации для JavaScript+узел, PHP, Питон и ActionScript), на github Xpresion (пс.я автор)
Движок довольно гибкий и настраиваемый, можно создавать парсеры, которые анализируют любое выражение, которое также включает в себя определяемые пользователем переменные, определяемые пользователем функции, полиморфные операторы и вообще n-арные операторы (например. троичный если-то-иначе)
Алгоритм достаточно общий (можно сказать, обобщенный вариант алгоритма). Алгоритм сортировочной станции)
Подход, который я бы выбрал:
- Токенизировать выражение
- Разберите его в абстрактное синтаксическое дерево.
- Выполните замену переменных (см. нетерпеливая оценка)
- Рассчитать результат
Сейчас...
- Алгоритм сортировочной станции – это способ выполнения шагов 1 и 2.
- Проверить синтаксическую правильность выражения можно после 2-го шага.
- То, как вы рассчитаете результат, будет зависеть от того, как построен AST.
Самый трудный шаг — 2-й;вам нужно учитывать приоритет операторов, круглые скобки и другие вещи, но по этому поводу есть много литературы (вы даже можете просто перейти по этой ссылке в Википедии)
почему бы вам просто не выполнить замену переменных, а затем сделать preg_replace("/[^0-9+-*\/]/", '', $inputString)
, а затем используйте либо eval()
или create_function()
?Если вы используете это, вы ДОЛЖНЫ убедиться, что возможно небезопасные «операторы» удалены, поэтому я использовал preg_replace, чтобы он удалил любую литеральную строку.