summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-01-29 19:11:20 +0000
committerPaul Phillips <paulp@improving.org>2010-01-29 19:11:20 +0000
commitad0fd8bca3c41a15ff688a7ca5e3278fa2ce127b (patch)
tree80845ebbbb692205d7973b1c7021e4e72ef284a1
parenta3da2dca9fafd6a5ecfd7ba77c73914ef6071d91 (diff)
downloadscala-ad0fd8bca3c41a15ff688a7ca5e3278fa2ce127b.tar.gz
scala-ad0fd8bca3c41a15ff688a7ca5e3278fa2ce127b.tar.bz2
scala-ad0fd8bca3c41a15ff688a7ca5e3278fa2ce127b.zip
Implemented rompf's suggested improvement to th...
Implemented rompf's suggested improvement to the tail recursive combinators, avoiding re-evaluation of by-name argument. Score one for code review. No review. (Ironic.)
-rw-r--r--src/library/scala/util/parsing/combinator/Parsers.scala16
1 files changed, 11 insertions, 5 deletions
diff --git a/src/library/scala/util/parsing/combinator/Parsers.scala b/src/library/scala/util/parsing/combinator/Parsers.scala
index 183465f84d..ee26c7ae71 100644
--- a/src/library/scala/util/parsing/combinator/Parsers.scala
+++ b/src/library/scala/util/parsing/combinator/Parsers.scala
@@ -578,13 +578,18 @@ trait Parsers {
def rep1[T](first: => Parser[T], p: => Parser[T]): Parser[List[T]] = Parser { in =>
val elems = new ListBuffer[T]
- @tailrec def applyp(in0: Input): ParseResult[List[T]] = p(in0) match {
- case Success(x, rest) => elems += x ; applyp(rest)
- case _ => Success(elems.toList, in0)
+ def continue(in: Input): ParseResult[List[T]] = {
+ val p0 = p // avoid repeatedly re-evaluating by-name parser
+ @tailrec def applyp(in0: Input): ParseResult[List[T]] = p0(in0) match {
+ case Success(x, rest) => elems += x ; applyp(rest)
+ case _ => Success(elems.toList, in0)
+ }
+
+ applyp(in)
}
first(in) match {
- case Success(x, rest) => elems += x ; applyp(rest)
+ case Success(x, rest) => elems += x ; continue(rest)
case ns: NoSuccess => ns
}
}
@@ -602,10 +607,11 @@ trait Parsers {
def repN[T](num: Int, p: => Parser[T]): Parser[List[T]] =
if (num == 0) success(Nil) else Parser { in =>
val elems = new ListBuffer[T]
+ val p0 = p // avoid repeatedly re-evaluating by-name parser
@tailrec def applyp(in0: Input): ParseResult[List[T]] =
if (elems.length == num) Success(elems.toList, in0)
- else p(in0) match {
+ else p0(in0) match {
case Success(x, rest) => elems += x ; applyp(rest)
case ns: NoSuccess => return ns
}