diff options
author | Paul Phillips <paulp@improving.org> | 2010-01-29 19:11:20 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2010-01-29 19:11:20 +0000 |
commit | ad0fd8bca3c41a15ff688a7ca5e3278fa2ce127b (patch) | |
tree | 80845ebbbb692205d7973b1c7021e4e72ef284a1 | |
parent | a3da2dca9fafd6a5ecfd7ba77c73914ef6071d91 (diff) | |
download | scala-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.scala | 16 |
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 } |