Suppose we have a very simple language where it is a valid program
block inside the block
and we want to parse this into a List[String] with each row inside the block as one String .
First, we define a method that takes a minimum indent level and returns a parser for a line with that indent level.
def line(minIndent:Int):Parser[String] = repN(minIndent + 1,"\\s".r) ~ ".*".r ^^ {case s ~ r => s.mkString + r}
Then we define the block with the minimum indentation, repeating the line parser with a suitable separator between the lines.
def lines(minIndent:Int):Parser[List[String]] = rep1sep(line(minIndent), "[\n\r]|(\n\r)".r)
Now we can define a parser for our small language as follows:
val block:Parser[List[String]] = (("\\s*".r <~ "block\\n".r) ^^ { _.size }) >> lines
First, it determines the current indentation level and then passes that value to at least the line parser. Let him check it:
val s = """block inside the block outside the block""" println(block(new CharSequenceReader(s)))
And get
[4.10] parsed: List( inside, the, block)
For all this to compile you need import data
import scala.util.parsing.combinator.RegexParsers import scala.util.parsing.input.CharSequenceReader
And you need to put everything in an object that extends RegexParsers so
object MyParsers extends RegexParsers { override def skipWhitespace = false ....