Reputation: 398
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.
Upvotes: 0
Views: 170
Reputation: 38045
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.
Upvotes: 1