开发者

scala dsl parser: rep, opt and regexps

开发者 https://www.devze.com 2023-01-27 03:45 出处:网络
Learning how to use scala DSL:s and quite a few examples work nice. However I get stuck on a very simple thing:

Learning how to use scala DSL:s and quite a few examples work nice. However I get stuck on a very simple thing:

I'm parsing a language, which has '--' as comment until end of line.

A single line works fine using:

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

But when connecting multiple lines I get an error.

I've tried several varaints, but the following feel simple:

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

When running a test with two consecutive commentlines I get an error.

Testcase:

--Test Comment
--Test Line 2

Error:

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

Any ideas on how I should fix this?

Complete code below:

    import scala.util.parsing.combinator._

abstra开发者_运维百科ct 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)
    }

}


Not familiar with Scala, but in Java, the regex --.*$ matches:

  • --   two hyphens;
  • .*   followed by zero or more characters other than line breaks;
  • $     followed by the end of the input (not necessarily the end of the line!).

So you could try:

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

or even:

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

Note that in both cases, the line break is left in place and not "consumed" by your comment "rule".

0

精彩评论

暂无评论...
验证码 换一张
取 消