I have written a scala parser using parser combinator:
case class KW(str: String) {
val parser: Parser[String] = str
}
implicit class SymbolView(symbol: Symbol) {
val $: KW = {
KW(symbol.name.toLowerCase())
}
}
implicit def ks2Parser(ks: KW): Parser[String] = ks.parser
val _DELETE = 'delete $
val _REMOVE = 'remove $
val _DROP = 'drop $
val DELETE = _DELETE | _REMOVE | _DROP
lexical.reserved ++= Seq("delete", "remove", "drop")
val scanner: lexical.Scanner = new lexical.Scanner("delete")
phrase(DELETE).apply(scanner)
However scala parser give me this error:
failure: You are trying to parse "drop", but it is neither contained in the delimiters list, nor in the reserved keyword list of your lexical object
I'm very sure both "delete" and "drop" are both contained in the reserved keyword list of lexical (I've found both in debug mode). So this error information is obviously wrong. Is it a bug in scala parser combinator? What should I do to fix it?
When you use $
, StandardTokenParsers.keyword
eventually gets invoked implictly in the line val parser: Parser[String] = str
. It uses the contents of lexical.reserved
at the time of invocation. And those invocations happen when you create _DELETE
/_REMOVE
/_DROP
parsers, which is before you add tokens to lexical.reserved
.
So either move the line to add reserved tokens before parsers creation:
lexical.reserved ++= Seq("delete", "remove", "drop")
val _DELETE = 'delete $
val _REMOVE = 'remove $
val _DROP = 'drop $
val DELETE = _DELETE | _REMOVE | _DROP
Or make parser definitions def
s (or lazy val
s) instead of val
s:
def _DELETE = 'delete $
def _REMOVE = 'remove $
def _DROP = 'drop $
def DELETE = _DELETE | _REMOVE | _DROP