【发布时间】:2013-12-27 00:21:22
【问题描述】:
我正在尝试构建一个小型解析器,其中标记(幸运的是)从不包含空格。空白(空格、制表符和换行符)本质上是标记分隔符(除了有括号等的情况)。
我正在扩展RegexParsers 类。如果我打开skipWhitespace,当下一个标记与前一个标记的正则表达式匹配时,解析器会贪婪地将标记连接在一起。另一方面,如果我关闭skipWhitespace,它会抱怨,因为空格不是定义的一部分。我试图尽可能地匹配 BNF,并且鉴于空格几乎总是分隔符(除了括号或在 BNF 中明确定义分隔符的一些其他情况),是否可以避免将空格正则表达式放在所有我的定义?
更新
这是一个将标记连接在一起的小测试示例:
import scala.util.parsing.combinator.RegexParsers
object TestParser extends RegexParsers {
def test = "(test" ~> name <~ ")"
def name : Parser[String] = (letter ~ (anyChar*)) ^^ { case first ~ rest => (first :: rest).mkString}
def anyChar = letter | digit | "_".r | "-".r
def letter = """[a-zA-Z]""".r
def digit = """\d""".r
def main(args: Array[String]) {
val s = "(test hello these should not be joined and I should get an error)"
val res = parseAll(test, s)
res match {
case Success(r, n) => println(r)
case Failure(msg, n) => println(msg)
case Error(msg, n) => println(msg)
}
}
}
在上述情况下,我只是将字符串连接在一起。
类似的效果是,如果我将test 更改为以下内容,期望它在测试后给我单独的单词列表,但它却将它们连接在一起,只给我一个带有长字符串的元素列表,没有中间空格:
def test = "(test" ~> (name+) <~ ")"
【问题讨论】:
-
IIRC,跳过空白仅在每个标记的开头完成,直到找到第一个非空白字符。这与您所说的情况不一致,您能否提供示例代码和测试用例?
-
@DanielC.Sobral 添加了一个小例子来说明它正在发生。