From ad0fd8bca3c41a15ff688a7ca5e3278fa2ce127b Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Fri, 29 Jan 2010 19:11:20 +0000 Subject: 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.) --- src/library/scala/util/parsing/combinator/Parsers.scala | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'src/library') 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 } -- cgit v1.2.3