I am experimenting with parser combinators and I often run into what seems like infinite recursions. Here is the first one I ran into:
import util.parsing.combinator.Parsers
import util.parsing.input.CharSequenceReader
class CombinatorParserTest extends Parsers {
type Elem = Char
def notComma = elem("not comma", _ != ',')
def notEndLine = elem("not end line", x => x != '\r' && x != '\n')
def text = rep(notComma | notEndLine)
}
object CombinatorParserTest {
def main(args:Array[String]): Unit = {
val p = new CombinatorParserTest()
val r = p.text(new CharSequenceReader(","))
// does not get here
println(r)
}
}
How can I print what is going on? And why does this not finish?
Logging the attempts to parse notComma
and notEndLine
show that it is the end-of-file (shown as a CTRL-Z in the log(...)("mesg") output) that is being repeatedly parsed. Here's how I modified your parser for this purpose:
def text = rep(log(notComma)("notComma") | log(notEndLine)("notEndLine"))
I'm not entirely sure what's going on (I tried many variations on your grammar), but I think it's something like this: The EOF is not really a character artificially introduced into the input stream, but rather a sort of perpetual condition at the end of the input. Thus this never-consumed EOF pseudo-character is repeatedly parsed as "either not a comma or not an end-of-line."
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With