Question

I am trying to build a simple external DSL in Scala that would be able to parse strings like:

value = "john${tom}peter${greg}${sue}meg"

In general, a substring within quotation marks contains interlaced names and names put between ${ and }.

My grammar is as following:

class Grammar extends JavaTokenParsers {
  def workflow = "value" ~> "=" ~> "\"" ~> pair <~ "\""

  def pair = rep(str | token)

  def str = rep(char)

  def char: Parser[String] = """[a-z]""".r

  def token = "$" ~> "{" ~> str <~ "}"
}

and executed by:

var res = parseAll(workflow, str)
println(res)

I thought that a method def pair = rep(str | token) would make it possible to parse it properly. Not only it doesn't work but also it leads to an infinite loop within parseAll method.

How can I parse such a string then? It seems that an alternative repetition (rep) is not the right approach.

Was it helpful?

Solution

You should replace rep with rep1.

rep is always successful (unless it is an Error), so in rep(char) | token right part (token) is useless - you'll get an empty successful result of rep(char).

Also, you could either replace """[a-z]""".r with accept('a' to 'z') or define str as def str: Parser[String] = """[a-z]+""".r. Usage of Regex to match a single Char is an overkill.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top