2010-09-27 3 views
3

J'apprends à écrire un simple analyseur-analyseur. J'écris les règles de bas en haut et j'écris des tests unitaires pour vérifier au fur et à mesure. Cependant, je suis bloqué à l'aide de repsep() avec des espaces comme séparateur.scala: parser help

object MyParser extends RegexParsers { 
    lazy val listVal:Parser[List[String]]=elem('{')<~repsep("""\d+""".r,"""\s+""".r)~>elem('}') 
} 

La règle a été simplifiée pour illustrer le problème. Quand je l'analyseur avec nourrirai "{1 2 3}", il se plaint toujours qu'il ne correspond pas à:

[1.4] échec: `} 'attendu mais 2 trouvé

I' Je me demande quelle est la bonne façon d'écrire une règle comme je l'ai décrit?

Merci

Répondre

6

Par défaut, RegexParsers parseurs sauter lespace avant dérivée de tenter de faire correspondre un symbole terminal. À moins que votre interprétation des espaces blancs ne soit inhabituelle, vous pouvez simplement travailler avec cela. Si le caractère particulier (séquences) que vous souhaitez traiter en tant qu'espace blanc ignoré est autre que le caractère par défaut (\s+), vous pouvez remplacer la valeur val whiteSpace: Regex = ... projetée dans votre analyseur RegexParsers. Si vous ne spécifiez pas ce type d'espace, override def skipWhitespace = false.

Edit: Alors oui, de changer cette situation

repsep("""\d+""".r,"""\s+""".r) 

à ceci:

rep("""\d+""".r) 

et laissant tout le reste défini dans RegexParsers sans changement devrait faire ce que vous voulez. Par ailleurs, l'utilisation courante de repsep est pour des choses comme des listes séparées par des virgules où vous devez vous assurer que les virgules sont présentes mais n'ont pas besoin de les conserver dans l'arbre d'analyse résultant (ou AST).

+0

en changeant 'repsep (" "" \ d + "" ".r ...)' en 'rep (" "" \ d + "" ". R)'? – svrist