Shunting mise en œuvre en PHP cour nécessaire, interpréter et analyser une chaîne effectuer une comparaison mathématique et renvoient une valeur booléenne

StackOverflow https://stackoverflow.com/questions/3664017

Question

Je cherche quelque chose qui peut interpréter une chaîne en php et effectuer le calcul mathématique simple, puis renvoyer un résultat booléen pour savoir si l'expression est vraie ou fausse.

Par exemple:

  1. types Sue dans "3 * {} MonSalaire / 9 = 10000"
  2. PHP divise ce en deux expressions - explode ( '=', string);
  3. PHP prend ma liste de champs de base de données, et remplace toute « {} » champs délimités par les données (à typecasted int)
  4. PHP évalue alors l'expression mathématique
  5. php compare ensuite le côté gauche à droite
  6. résultat booléen produit.

Il peut sembler complexe, mais il n'a besoin que d'être très simple. Voici les contraintes: 1 opérateurs / mathématiques sont fixés à: + - / * 2 / opérateurs de comparaison sont fixés: => <> = <= 3 / ne pas les comparaisons à virgule flottante besoin, tout peut se faire à un niveau entier. Ainsi, les divisions peuvent être arrondis en cas de besoin ou tout simplement autour du résultat final

Il ne sera jamais deux expressions, avec un opérateur de comparaison. S'il y a toute sorte d'erreur à tout ce que nous allons simplement revenir faux.

Quelqu'un at-il vu quelque chose qui peut déjà le faire? Je sais que je peux faire quelque chose, mais pourquoi réinventer la roue droite?

Si vous ne l'avez pas vu quoi que ce soit que vous aimez à la liste des « de Gotcha » ou mise en garde-ce que vous pouvez penser lors de la construction cela.

Après avoir lu un peu plus je me rends compte que je pouvais utiliser le shunter algorithme de cour . Quelqu'un at-il une mise en œuvre de ce en PHP?

Je suis conscient du eval pourrait être une méthode facile à réaliser cela, cependant, il me concerne que l'utilisateur pourrait se casser très facilement quelque chose en utilisant cette méthode ou de provoquer des erreurs de syntaxe. Je préfère ne pas inclure dans la solution, ou si je fais alors il avais besoin de contrôler étroitement la façon dont il est utilisé.

Merci.

Jason

Était-ce utile?

La solution

Jetez un oeil à la evalMath classe sur PHPClasses. Cela devrait faire à peu près tout ce que vous voulez, y compris la substitution des variables (telles que la définition d'une valeur pour « MonSalaire » dans votre exemple avant d'évaluer l'expression)

Autres conseils

Il y a un expression moteur analyseur (implémentations pour JavaScript + Noeud , PHP , Python et ActionScript) , sur github Xpresion (ps. Je suis l'auteur)

Le moteur est très flexible et configurable, on peut créer des analyseurs qui analysent toute expression qui comprend également variables définies par l'utilisateur , fonctions définies par l'utilisateur , polymorphes opérateurs et les opérateurs généraux n-aire (par exemple. ternaire if-then-else )

L'algorithme est assez général (on pourrait dire, une variation généralisée de algorithme de triage )

L'approche que je prendrais est:

  1. Tokenize l'expression
  2. Parse dans un arbre de syntaxe abstraite
  3. Effectuer des substitutions variables (voir évaluation stricte )
  4. Calculer le résultat

...

  • L'algorithme-cour est shuntage une façon de faire les étapes 1 et 2.
  • Vous pouvez vérifier si l'expression est syntaxiquement correcte après la 2ème étape
  • Comment calculer le résultat dépendra de la façon dont l'AST est construit.

Le plus dur étape est la 2ème; vous devez considérer la priorité des opérateurs, entre parenthèses et d'autres choses, mais il y a beaucoup de littérature sur ce (vous pouvez même il suffit de suivre ce lien wikipedia)

pourquoi ne vous effectuez simplement le remplacement des variables, puis effectuez une preg_replace("/[^0-9+-*\/]/", '', $inputString), puis utilisez soit eval() ou create_function()? Si vous utilisez ce que vous devez vous assurer que peut-être dangereux « déclarations » sont supprimés, c'est pourquoi je l'ai utilisé preg_replace, il supprimerait toute chaîne littérale

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top