2009-10-19 9 views
2

Je cherche à implémenter le Shunting-yard Algorithm, mais j'ai besoin d'aide pour déterminer quelle est la meilleure façon de diviser une chaîne en ses jetons.Existe-t-il un moyen simple de marquer une chaîne sans un lexer complet?

Si vous remarquez, la première étape de l'algorithme est "lire un jeton". Ce n'est pas exactement une chose non triviale à faire. Les jetons peuvent être composés de nombres, d'opérateurs et de parens.

Si vous faites quelque chose comme:

(5 + 1)

Un string.split simple() va me donner un tableau des jetons { "(", « 5 "," + "," 1 ",") "}.

Cependant, il devient plus compliqué si vous avez des nombres avec plusieurs chiffres tels que:

((2048 * 124) + 42)

maintenant un string.split naïf() gagné Ne fais pas l'affaire. Les numéros à plusieurs chiffres sont un problème.

Je sais que je pourrais écrire un lexer, mais y a-t-il un moyen de le faire sans écrire un lexer à part entière? Je l'implémente en JavaScript et je voudrais éviter d'avoir à descendre le lexer-path si possible. Je vais utiliser les opérateurs "*", "+", "-" et "/", ainsi que les entiers.

+1

Tout ce qui convertit correctement un flux de caractères en flux de jeton * est * un lexer. –

Répondre

6

Que diriez-vous des expressions régulières? Vous pouvez facilement écrire regex pour le découper comme vous le souhaitez, et la méthode JS string.split accepte aussi regex comme paramètre.

Par exemple ... (modifier pour inclure tous les caractères dont vous avez besoin, etc.)

/([0-9]+|[*+-\/()])/ 
+1

+1 Il se casse pour les parenthèses imbriquées comme '((42 + 7) * 4) '' mais cela peut être corrigé en ajoutant des parenthèses à la seconde moitié de l'expression: '/ ([0-9] + | [* + - \ /()])/' – brianpeiris

+0

Il utilise toujours l'algorithme spécifié sur la page wiki. Le pseudo-code dit "Read Token". – mmcdole

+0

@Simucal, @KingNestor Je suis confus maintenant, n'est-ce pas la bonne réponse? – brianpeiris

2

Vous pouvez utiliser une correspondance globale comme décrit à http://mikesamuel.blogspot.com/2009/05/efficient-parsing-in-javascript.html

Fondamentalement, vous créez un regex qui décrit un jeton

/[0-9]+|false|true|\(|\)/g 

et mettre le « g » à la fin il correspond globalement, puis vous appelez sa méthode de correspondance

var tokens = myRegex.match(inputString); 

et de récupérer un tableau.

+0

Je pense que c'est la meilleure méthode. J'utilise result = subject.match (/ (-? [0-9] + | [* + - \ /()])/g); Vous obtenez les jetons dont vous avez besoin, et les jetons que vous voulez :). –