2010-11-25 13 views
2

Lernen, wie man scala DSL verwendet: s und einige Beispiele funktionieren gut. Allerdings stehe ich auf eine sehr einfache Sache fest:scala dsl parser: rep, opt und regexps

Ich analysiere eine Sprache, die '-' als Kommentar bis zum Ende der Zeile hat.

Eine einzelne Linie funktioniert gut mit:

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

Aber wenn mehrere Zeilen ich einen Fehler zu verbinden.

Ich habe mehrere varaints versucht, aber die folgenden fühlen einfach:

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

Wenn ein Test mit zwei aufeinander folgenden commentlines laufen bekomme ich einen Fehler.

Testfall:

--Test Comment 
--Test Line 2 

Fehler:

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

Alle Ideen, wie ich dieses Problem beheben sollte?

komplette Code unten:

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) 
    } 

}

Antwort

2

Nicht vertraut mit Scala, aber in Java, die regex --.*$ Spiele:

  • --   zwei Bindestriche;
  • .*   gefolgt von null oder mehr Zeichen außer Zeilenumbrüchen;
  • $     gefolgt von dem Ende der Eingabe (nicht unbedingt das Ende der Zeile!).

So könnten Sie versuchen:

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

oder sogar:

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

Beachten Sie, dass in beiden Fällen wird der Zeilenumbruch an seinem Platz belassen und nicht "verbraucht" durch Ihre comment " Regel".

+0

Funktioniert perfekt, danke !!! Dumm ich dachte, das war ein Scala-Match-Problem, kein Regexp-Problem. –

+0

@Bjorn, :), gern geschehen! –