Требуется реализация Shunting Yard в PHP, интерпретировать и анализировать строку, выполнить математическое сравнение и вернуть логический результат - PullRequest
3 голосов
/ 08 сентября 2010

Я ищу что-то, что может интерпретировать строку в php и выполнить простые математические вычисления, а затем вернуть логический результат относительно того, является ли выражение истинным или ложным.

Например:

  1. Типы Сью в "3 * {mysalary} / 9 = 10000"
  2. PHP разбивает это на два выражения - взорваться ('=', строка);
  3. PHP берет мой список полей базы данных и заменяет любые поля с разделителями "{}" данными (с типом int)
  4. Затем PHP вычисляет математическое выражение
  5. php сравнивает левую и правую стороны
  6. Получен логический результат.

Это может звучать сложно, но это должно быть очень просто. Вот ограничения: 1 / математические операторы фиксируются на: + - / * 2 / операторы сравнения фиксируются на: => <> = <= 3 / не нужно сравнения с плавающей запятой, все можно сделать на целочисленном уровне. Таким образом, любые деления могут быть округлены, если это необходимо, или просто округлить окончательный результат </p>

Всегда будет только два выражения с одним оператором сравнения. Если есть какая-либо ошибка, мы просто вернем false.

Кто-нибудь видел что-то, что уже может это сделать? Я знаю, что могу что-то сделать, но зачем заново изобретать колесо, верно?

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

Прочитав еще немного, я понял, что могу использовать алгоритм маневрового двора . У кого-нибудь есть реализация этого в PHP?

Я знаю, что eval может быть простым методом для этого, однако меня беспокоит, что пользователь может очень легко что-то сломать, используя этот метод, или вызвать синтаксические ошибки. Я бы предпочел не включать его в решение, или, если я это сделаю, нужно будет жестко контролировать его использование.

Спасибо.

Jason

Ответы [ 4 ]

2 голосов
/ 27 января 2015

Имеется механизм синтаксического анализа выражений (реализации для JavaScript + Узел , PHP , Python и ActionScript) на github Xpresion (пс. я автор)

Движок довольно гибкий и настраиваемый, можно создавать парсеры, которые разбирают любое выражение, которое также включает пользовательские переменные , пользовательские функции , полиморфные операторы и общие n-арные операторы (например, троичный if-then-else )

Алгоритм довольно общий (можно сказать, обобщенный вариант алгоритма Shunting Yard )

2 голосов
/ 08 сентября 2010

Взгляните на класс evalMath в PHPClasses. Это должно делать почти все, что вы хотите, включая подстановку переменных (например, установка значения для «mysalary» в вашем примере перед вычислением выражения)

0 голосов
/ 08 сентября 2010

почему бы вам просто не выполнить замену переменных, а затем выполнить preg_replace("/[^0-9+-*\/]/", '', $inputString), а затем использовать eval() или create_function()? Если вы используете это, вы ДОЛЖНЫ убедиться, что, возможно, небезопасные «операторы» удалены, поэтому я использовал preg_replace, поэтому он удалит любую литеральную строку

0 голосов
/ 08 сентября 2010

Я бы выбрал следующий подход:

  1. Токенизация выражения
  2. Разобрать его в абстрактное синтаксическое дерево
  3. Выполнить подстановку переменных (см. нетерпеливая оценка )
  4. Рассчитать результат

Сейчас ...

  • Алгоритм маневрового двора - это способ выполнить шаги 1 и2.
  • Вы можете проверить правильность синтаксического выражения после 2-го шага
  • Способ вычисления результата будет зависеть от того, как построен AST.

Самый сложный шаг - второй;Вы должны учитывать приоритет операторов, скобки и другие вещи, но об этом много литературы (вы можете даже просто перейти по этой ссылке в Википедии)

...