2017-01-12 1 views
2

J'essaie de diviser une chaîne d'équation en jetons. J'ai trouvé un bon point de départ »([A-Za-z] + | [0-9.] + | [& => < \ |!] + | \ S) '. Cependant, cela a du mal avec les nombres négatifs:équation mathématique tokenizing utilisant regex

turns: '5--4=sin(2+3)' 
into: ['5','-','-','4','=','sin','(','2','+','3',')'] 
want: ['5','-','-4','=','sin','(','2','+','3',')'] 

et aussi

turns: -3+3 
into: ['-','3','+','3'] 
want: ['-3','+','3'] 

Il ressemble à un mon regex pourrait utiliser quelque chose qui vérifie s'il y a un numéro à gauche du « - » si ne pas le garder avec le prochain numéro (note '-3' n'a rien à gauche). Peut-il être fait en utilisant regex? Ou y a-t-il un meilleur outil pour diviser cela en .NET?

Répondre

1

Regex n'est pas assez puissant pour faire ce que vous voulez dans tous les contextes. Bien que vous puissiez faire regex reconnaître + ou - en tant que partie d'un littéral entier, par exemple, en ajoutant un [+-]? facultatif devant une séquence de chiffres, l'expression rationnelle résultante choisirait de marquer '-3+3' comme ['-3', '+3'] (demo).

L'utilisation d'un générateur lexer devrait résoudre ce problème; Alternativement, vous pouvez gérer le regroupement des opérateurs unaires avec leurs opérandes dans l'analyseur syntaxique .

+0

Oh viens, regex est parfaitement adapté pour lexique - c'est un problème de Chomsky type 3. OP ne réalise pas que le résultat qu'il a obtenu est réellement * exactement * ce dont il a besoin. dans '-'' 3', le '-' est en fait l'opérateur de négation unaire. –

+0

@LucasTrzesniewski Bien sûr, regex est parfaitement adapté au lexique, mais OP veut que son lexique soit sensible au contexte. Il veut que deux "-3-3" soient traités différemment, ce qui n'est ni ce qu'il veut ni ce que regex peut fournir. – dasblinkenlight

+0

Oui, après avoir lu votre réponse pour la deuxième fois maintenant, j'ai compris ce que vous vouliez dire. BTW un générateur de lexer ne résoudra pas simplement le problème par magie, la plupart utilisent juste regex sous le capot;) –

2

Vous n'abordez pas correctement le problème. Le résultat que vous avez obtenu est le bon.

-3+3 devrait analyser à:

operator binary + 
| 
+-- operator unary - 
| | 
| +-- 3 
| 
+-- 3 

Il sera beaucoup plus facile à raisonner sur des expressions mathématiques de cette façon, vous éviterez beaucoup ambiguïtés. Laissez simplement - toujours être un jeton en lui-même, et utilisez-le soit comme un binaire négatif, soit comme un opérateur de négation unaire.

Voir here pour une réponse connexe qui aborde le problème de cette façon (il utilise ANTLR mais le passage lexing fait exactement ce que je vous conseille de faire).