[SOLVED] Parser combinator: removing comments

I have been trying to use Scala’s parser combinator to remove Java like comments from a string. Seems like a pretty simple problem, but I cannot seem to solve it.

Here is the code:

  import scala.util.parsing.combinator.JavaTokenParsers

  object CommentParser extends JavaTokenParsers {
    import scala.language.implicitConversions

    def singleLine: Parser[String] = "//.*".r ^^ ( _ => "")
    def multiLine: Parser[String] = """/\*.*\*/""".r ^^^ ""
    def comments: Parser[Seq[String]] = (singleLine | multiLine).*
    def commentedText : Parser[String] = comments ~> "[^\\/*]*".r <~ comments
    def empty: Parser[Seq[String]] = "" ^^^ Seq()
    def expression: Parser[String] = commentedText ~ (empty | commentedText.*) ^^ {
      case (a:String) ~ (b:Seq[String]) => a+b.mkString("")
    }

    def stripComments(str: String): Either[String, String] = {
      parseAll(expression, str) match {
        case Success(result, _) => Right(result)
        case failedOrIncomplete => Left(failedOrIncomplete.toString)
      }
    }
  }

The following tests work:

    val r1 = CommentParser.stripComments("/* a comment */")
    assertEquals(Right(""), r1)

    val r2 = CommentParser.stripComments("// a comment")
    assertEquals(Right(""), r2)

    val r3 = CommentParser.stripComments("/* level1 /* level 2 */  */")
    assertEquals(Right(""), r3)

    val r4 = CommentParser.stripComments("Text Before./* level1 /* level 2 */  */")
    assertEquals(Right("Text Before."), r4)

    val r5 = CommentParser.stripComments("/* level1 /* level 2 */  */Text after.")
    assertEquals(Right("Text after."), r5)

However this test:


    val r6 = CommentParser.stripComments("Text Before./* level1 /* level 2 */  */Text after.")
    assertEquals(Right("Text Before.Text after."), r6)

fails with the following message:

Test data.ConfigPreProcessorSpec.testDummy failed: expected:<Right(Text Before.Text after.)> but was:<Left([1.40] failure: end of input expected

Text Before./* level1 /* level 2 */  */Text after.
                                       ^)>, took 0.034 sec

I cannot figure out why it expects an empty line. I use the combinator:

 (empty | commentedText.*)

so I would expect empty to fail and another attempt be made.

Can anyone point me in the right direction?

TIA

Once again I find the answer after posting for help. Must be psychological.
Anyway, the problem is in the empty. It should be:

    def empty: Parser[Seq[String]] = ".*$".r ^^ {e => Seq(e) } 

Apologies for the noise.