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