2010-11-25 39 views
2

Apprendre à utiliser scala DSL: s et quelques exemples fonctionnent bien. Cependant, je suis coincé sur une chose très simple:scala dsl parser: rep, opt et regexps

Je suis l'analyse d'une langue, qui a '-' comme un commentaire jusqu'à la fin de la ligne.

Une seule ligne fonctionne très bien à l'aide:

def comment: Parser[Comment] = """--.*$""".r ^^ { case c => Comment(c) } 

Mais lors de la connexion de plusieurs lignes je reçois une erreur.

J'ai essayé plusieurs varaints, mais ce qui suit l'impression simple:

def commentblock: Parser[List[Comment]] = opt(rep(comment)) ^^ { 
    case Some(x) => { x } 
    case None => { List() } 
} 

Lors de l'exécution d'un test avec deux commentlines consécutifs je reçois une erreur.

Testcase:

--Test Comment 
--Test Line 2 

Erreur:

java.lang.AssertionError: Parse error: [1.1] failure: string matching regex `--.*$' expected but `-' found 

Toutes les idées sur la façon dont je résoudre ce problème?

Code complet ci-dessous:

import scala.util.parsing.combinator._ 

abstract class A 
case class Comment(comment:String) extends A 

object TstParser extends JavaTokenParsers { 
    override def skipWhitespace = true; 

    def comment: Parser[Comment] = """--.*$""".r ^^ { case c => Comment(c) } 

    def commentblock: Parser[List[Comment]] = opt(rep(comment)) ^^ { 
     case Some(x) => { x } 
     case None => { List() } 
    } 

    def parse(text : String) = { 
     parseAll(commentblock, text) 
    } 
} 

class TestParser { 
    import org.junit._, Assert._ 

    @Test def testComment() = { 
     val y = Asn1Parser.parseAll(Asn1Parser.comment, "--Test Comment") 
     assertTrue("Parse error: " + y, y.successful) 
     val y2 = Asn1Parser.parseAll(Asn1Parser.commentblock, 
"""--Test Comment 
--Test Line 2 
""") 
     assertTrue("Parse error: " + y2, y2.successful) 
    } 

}

Répondre

2

Vous ne connaissez Scala, mais en Java, les regex --.*$ matches:

  • --   deux traits d'union;
  • .*   suivi de zéro ou plusieurs caractères autres que les sauts de ligne;
  • $     suivi de la fin de l'entrée (pas nécessairement la fin de la ligne!).

Vous pouvez essayer:

def comment: Parser[Comment] = """--.*""".r ^^ { case c => Comment(c) } 

ou même:

def comment: Parser[Comment] = """--[^\r\n]*""".r ^^ { case c => Comment(c) } 

Notez que dans les deux cas, le saut de ligne est laissée en place et non "consommés" par votre comment " règle".

+0

Fonctionne parfaitement, merci !!! Silly m'a pensé que c'était un problème de scala match, pas un problème regexp. –

+0

@Bjorn, :), de rien! –