作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
假设我正在用 Scala 编写一个基本的 SQL 解析器。我有以下几点:
class Arith extends RegexParsers {
def selectstatement: Parser[Any] = selectclause ~ fromclause
def selectclause: Parser[Any] = "(?i)SELECT".r ~ tokens
def fromclause: Parser[Any] = "(?i)FROM".r ~ tokens
def tokens: Parser[Any] = rep(token) //how to make this non-greedy?
def token: Parser[Any] = "(\\s*)\\w+(\\s*)".r
}
SELECT foo FROM bar
匹配时,我如何防止选择子句由于
rep(token)
而吞噬整个短语在
~ tokens
?
def token: Parser[Any] = stringliteral | numericliteral | columnname
最佳答案
不容易,因为不会重试成功的匹配。考虑,例如:
object X extends RegexParsers {
def p = ("a" | "aa" | "aaa" | "aaaa") ~ "ab"
}
scala> X.parseAll(X.p, "aaaab")
res1: X.ParseResult[X.~[String,String]] =
[1.2] failure: `ab' expected but `a' found
aaaab
^
p
失败的。如
p
是替代匹配的一部分,将尝试替代,所以诀窍是生产可以处理那种事情的东西。
def nonGreedy[T](rep: => Parser[T], terminal: => Parser[T]) = Parser { in =>
def recurse(in: Input, elems: List[T]): ParseResult[List[T] ~ T] =
terminal(in) match {
case Success(x, rest) => Success(new ~(elems.reverse, x), rest)
case _ =>
rep(in) match {
case Success(x, rest) => recurse(rest, x :: elems)
case ns: NoSuccess => ns
}
}
recurse(in, Nil)
}
def p = nonGreedy("a", "ab")
nonGreedy
之类的东西。以上。特别是看如何
rep1
已定义,以及如何更改它以避免重新评估其重复参数——同样的事情可能对
nonGreedy
有用。 .
trait NonGreedy extends Parsers {
def nonGreedy[T, U](rep: => Parser[T], terminal: => Parser[U]) = Parser { in =>
def recurse(in: Input, elems: List[T]): ParseResult[List[T]] =
terminal(in) match {
case _: Success[_] => Success(elems.reverse, in)
case _ =>
rep(in) match {
case Success(x, rest) => recurse(rest, x :: elems)
case ns: NoSuccess => ns
}
}
recurse(in, Nil)
}
}
class Arith extends RegexParsers with NonGreedy {
// Just to avoid recompiling the pattern each time
val select: Parser[String] = "(?i)SELECT".r
val from: Parser[String] = "(?i)FROM".r
val token: Parser[String] = "(\\s*)\\w+(\\s*)".r
val eof: Parser[String] = """\z""".r
def selectstatement: Parser[Any] = selectclause(from) ~ fromclause(eof)
def selectclause(terminal: Parser[Any]): Parser[Any] =
select ~ tokens(terminal)
def fromclause(terminal: Parser[Any]): Parser[Any] =
from ~ tokens(terminal)
def tokens(terminal: Parser[Any]): Parser[Any] =
nonGreedy(token, terminal)
}
关于regex - Scala RegexParsers 中的非贪婪匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7812610/
假设我正在用 Scala 编写一个基本的 SQL 解析器。我有以下几点: class Arith extends RegexParsers { def selectstatement: Par
我正在尝试读取 hdfs 中的 csv,通过级联对其进行解析,然后使用生成的元组流使用 RegexParser 在另一个元组流中形成正则表达式的基础。据我所知,执行此操作的唯一方法是编写自己的自定义函
解析空格有什么问题? scala> object BlankParser extends RegexParsers { def blank: Parser[Any] = " "
我是一名优秀的程序员,十分优秀!