Tout ce dont j'ai besoin, c'est de vérifier, en utilisant Python, si une chaîne est une expression mathématique valide ou non.
Pour simplicité, disons que je n'ai pas besoin de afin que je puisse tester de cette façon: p> J'ai essayé PYPARSING mais juste essayer l'exemple: " Un analyseur d'expression algébrique simple, qui effectue "O_OO p> Des conseils? P> P> + - * / code> opérateurs (
+ - code> aussi unaire) avec des chiffres et des parenthèses imbriquées. J'ajouterai également des noms de variables simples pour la complétude. P>
+, -, *, / code> et
je reçois le code non invalide et essayez également de réparer J'obtiens toujours des syntaxes erronées à analyser sans élever des exceptions p> ^ code> opérations arithmétiques "
5 Réponses :
La raison est différente: les analyseurs pygarines ne vont pas essayer de consommer l'entrée entière par défaut. Vous devez ajouter Si vous souhaitez apprendre un peu d'analyse, ce dont vous avez besoin peut être construite de manière proprablement dans une trentaine de lignes avec une bibliothèque de parsing décente (j'aime Ceci est parce que le code pymparsing permet des fonctions. del> (et par la manière dont vous avez beaucoup plus que ce dont vous avez besoin, c'est-à-dire une pile et évaluez cela.) P>
pour commencer, vous pouvez supprimer pi code> et
Ident code> (et éventuellement autre chose qui me manque maintenant) du code pour interdire les personnages. del> p>
+ stringend () code> (et importez-le, bien sûr) à la fin de
Expr code> pour l'échouer s'il ne peut pas analyser l'entrée entière. Dans ce cas,
pygarsing.parsexception code> sera soulevé. (Source: http://pyparsing-public.wikispaces.com/faqs ) p>
non true depuis pi code> ... est
pi code> et non
Qitiy code> et l'identifiant vient uniquement suivi d'une parenthèse ... bien sûr si je pouvais obtenir du pyparsing Pour travailler comme un vérificateur de syntaxe valide, je l'aimerais. Je vais donner une chance leulée aussi.
@neuriono: Ensuite, soit le code source est trompeur et la grammaire est en réalité différente, ou pyparsing est cassée (éditer: une explication que je peux penser, ce qui serait dans la catégorie "PyparSing est cassé": il ne consomme pas le tout String mais plutôt sort et retourne ce qu'il a analysé jusqu'à présent si l'entrée restante ne parvient pas à analyser).
Eh bien, c'est assez évident, mais si vous regardez la partie du code qui construit l'analyseur (def Bnf ()) est assez simple et même enlever des choses comme exponentiation i> la pièce rendant encore plus simple que cela échoue encore Je suppose que le pyparsing n'est pas bon pour vérifier la syntaxe.
@neuriono: Je suppose que ça avait raison. Ajout de cause et correction de la réponse.
ou ajoutez parseall = true ... Merci d'avoir souligné cela, je verrai si je peux vraiment l'obtenir pour vérifier ma syntaxe et vous donner la meilleure réponse
Pourquoi ne pas simplement l'évaluer et attraper l'erreur de syntaxe?
> print validSyntax('a+b-1') # a, b are undefined, so a NameError arises. > False > print validSyntax('1 + 2') > True > print validSyntax('1 - 2') > True > print validSyntax('1 / 2') > True > print validSyntax('1 * 2') > True > print validSyntax('1 +/ 2') > False > print validSyntax('1 + (2') > False > print validSyntax('import os') > False > print validSyntax('print "asd"') > False > print validSyntax('import os; os.delete("~\test.txt")') > False # And the file was not removed
Cela est bien pire que la première réponse (maintenant supprimée), qui au moins vérifiée si la réponse est composée de numéros et d'opérateurs. Le vôtre permet un code abrégé :(
Literal_eval Code> n'est pas la réponse, comme vous souhaitez autoriser les opérateurs de mathématiques et les parens.
Une mise à jour supplémentaire: j'ai changé la source de littéral_eval code> afin que cela n'accepte que des opérations binaires et unaires (espérons-le que c'est propre maintenant).
Tant de travail et de code ... jamais pensé à simplement aller à la manière d'un autre type (vérification des chiffres + ops) ou de le faire correctement et de construire un analyseur?
Votre premier échantillon est toujours faux pour mes besoins ... L'expression est une syntaxe valide, si les variables ne sont pas définies, c'est une NameError, pas une SyntaxError ...
Sept lignes et -20 de la source? C'est
Je travaille dessus, Sheesh. Vous agissez comme si je fais un travail faux. Soyez heureux que vous obteniez même de l'aide.
@Blender: Même si les exigences se développent, une solution utilisant une bibliothèque d'analyse sera facilement ajustée. Pas besoin de maintenir la solution.
@Blender: Je suis heureux de l'aide de tout le monde, mais je le donne comme une hypothèse qui donnant une syntaxe à un Evaluator i> est la mauvaise et éventuellement faible. Merci de vos efforts de toute façon.
Ok, Cette mise à jour i> devrait fonctionner. Corrigez-moi si je me trompe, mais je pense qu'il est assez sûr d'utiliser un eval () code> dans ce cas.
Peut-être en sécurité, mais toujours beaucoup trop de code. Même discutable si nous allions évaluer l'expression, mais nous excédez absolument (et aussi toujours sale) si le problème est la vérification de la syntaxe.
Je peux le formater un peu mieux, mais pourquoi est-ce sale? Trouvez-moi un trou et je serai heureux.
Vous savez essayer EVAL ("1000 1000 B> 1000") suspendra votre python longtemps? J'espère que ce code ne fonctionne pas sur un serveur Web ...
Je vois ce que tu veux dire ... laissez-moi voir ce que je peux faire.
Je pense que cela serait vulnérable aux conditions de course si multithreaded.
Vous pouvez essayer de construire un analyseur simple vous-même pour goverser la chaîne de l'expression arithmétique, puis construire un arbre d'expression, si l'arbre est valide (les feuilles sont tous des opérandes et les nœuds internes sont tous des opérateurs), vous pouvez dire que vous pouvez dire que L'expression est valide. p>
Le concept de base consiste à faire fonctionner quelques fonctions d'assistance pour créer votre analyseur. P>
Alternativement si vous pouvez garantir des espaces blancheurs entre les caractères, vous pouvez utiliser Ensuite, vous construisez votre arbre et évaluez si sa structure correctement p>
Essayez ceci pour plus d'informations: http://effbot.org/zone/ Simple-Top-Down-Parsing.htm P> def extrait () code> obtiendra le caractère suivant de l'expression de
DEF PEEK () CODE> Semblable à l'extrait mais utilisé s'il n'y a pas de blancheur pour vérifier le caractère suivant de
get_expression () code>
get_next_Token () code> p>
divisé () code> pour faire tout la jeton. p>
Construire tout cela vous-même est si le siècle dernier ... De nos jours, vous utilisez une bibliothèque d'analyse qui prend soin de toute la bureaucratie méchante.
@delnan j'ai ajouté le fait que s'il y a une espace blanche, vous pouvez simplement utiliser Split (), également s'il n'y a pas de cette bibliothèque de ce type qui répond à vos besoins (fonctionnel mais pas trop grand, etc.), qu'est-ce que?
@YOEL: Ensuite, vous n'avez pas de chance et avez-vous des normes trop élevées.
@delnan, je ne comprends pas que quelqu'un devait écrire la bibliothèque LEPL que vous avez dit avoir aimé utiliser. Je suppose que cela m'appelle à l'ancienne pour vouloir faire des choses qui sont "sooo du siècle dernier";)
@Yoel: Je suppose que vous avez déjà analysé quelque chose de non-trivial (CSV est à la limite entre trivial et simple) à la main? Je cautions une fois, mais à mi-chemin, je me suis rendu compte que j'écris des fonctions d'assistant, des services publics, etc. que l'analyse des bibliothèques fournissait déjà (sans oublier que mon code était toujours buggy pendant que le leur travaille parfaitement).
@Delnan: +1 pour ne pas laisser cette chaîne de commentaires devenir agressifs. Je comprends où votre venant de et oui en utilisant des bibliothèques jugées et vraies est très utile. Je viens de ressentir pour cette application spécifique que @Neurino avait besoin, il pourrait être logique de faire la route personnalisée. Je suppose que je sautais à des conclusions sur les contraintes existantes sur l'espace et les dépendances
@Yoel: Eh bien, puisque OP a présenté une solution pymparsing, il souhaitait travailler, les dépendances semblent bien. Mais ne jamais relâcher.
Ajout parseall = true code> à l'appel à
parsestring code> convertira cet analgésique en validateur. P>
Eh bien, un peu tard ... (voir mon dernier commentaire à la réponse sélectionnée), merci quand même.
Si vous souhaitez modifier un moteur d'évaluateur de mathématiques personnalisé écrit dans Python de sorte qu'il s'agisse d'un validateur, vous pouvez commencer avec Evaluator 2.0 (Python 3.x) et math_evaluator (python 2. X). Ce ne sont pas des solutions prêtes à l'emploi mais vous permettraient de personnaliser pleinement tout ce que vous essayez de faire exactement utiliser (espérons-le) le code Python facile à lire. Notez que "et" & "ou" sont traités comme des opérateurs. P>