Skip to content

Commit

Permalink
Tests
Browse files Browse the repository at this point in the history
  • Loading branch information
j-mie6 committed Jul 23, 2023
1 parent bcf897c commit 561c9ed
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 4 deletions.
7 changes: 3 additions & 4 deletions parsley/shared/src/main/scala/parsley/combinator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -911,15 +911,14 @@ object combinator {
def exactly[A](n: Int, p: Parsley[A]): Parsley[List[A]] = traverse[Int, A](_ => p, (1 to n): _*)
private def skipExactly(n: Int, p: Parsley[_]): Parsley[Unit] = skip(p, (2 to n).map(_ => p): _*)

def count(p: Parsley[_]): Parsley[Int] = p.foldLeft(0)((n, _) => n + 1)
def count1(p: Parsley[_]): Parsley[Int] = p.foldLeft1(0)((n, _) => n + 1)

def range[A](min: Int, max: Int)(p: Parsley[A]): Parsley[List[A]] = fresh(mutable.ListBuffer.empty[A]).persist { xs =>
count(min, max)((xs, p).zipped(_ += _)) ~>
xs.map(_.toList)
}

def range_(min: Int, max: Int)(p: Parsley[_]): Parsley[Unit] = count(min, max)(p).void

def count(p: Parsley[_]): Parsley[Int] = p.foldLeft(0)((n, _) => n + 1)
def count1(p: Parsley[_]): Parsley[Int] = p.foldLeft1(0)((n, _) => n + 1)
def count(min: Int, max: Int)(p: Parsley[_]): Parsley[Int] = min.makeReg { i =>
skipExactly(min, p) ~>
skipMany(ensure(i.gets(_ < max), p) ~> i.modify(_ + 1)) ~>
Expand Down
27 changes: 27 additions & 0 deletions parsley/shared/src/test/scala/parsley/CombinatorTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package parsley
import Predef.{ArrowAssoc => _, _}

import parsley.combinator.{exactly => repeat, _}
import parsley.character.item
import parsley.Parsley._
import parsley.registers.{forYieldP, forYieldP_, Reg}
import parsley.implicits.character.{charLift, stringLift}
Expand Down Expand Up @@ -233,5 +234,31 @@ class CombinatorTests extends ParsleyTest {
p.parse("ababababab") shouldBe Success(5)
p.parse("abababababab") shouldBe Success(5)
p.parse("ababababa") shouldBe a [Failure[_]]
val q = count(2, 5)(atomic("ab"))
q.parse("ab") shouldBe a [Failure[_]]
q.parse("abab") shouldBe Success(2)
q.parse("ababab") shouldBe Success(3)
q.parse("abababab") shouldBe Success(4)
q.parse("ababababab") shouldBe Success(5)
q.parse("abababababab") shouldBe Success(5)
q.parse("ababababa") shouldBe Success(4)
}

"range" should "collect results up instead of count" in {
val p = range(2, 5)(item)
p.parse("a") shouldBe a [Failure[_]]
p.parse("ab") shouldBe Success(List('a', 'b'))
p.parse("abcd") shouldBe Success(List('a', 'b', 'c', 'd'))
p.parse("abcde") shouldBe Success(List('a', 'b', 'c', 'd', 'e'))
p.parse("abcdef") shouldBe Success(List('a', 'b', 'c', 'd', 'e'))
}

"range_" should "perform a range with no results" in {
val p = range_(2, 5)(item)
p.parse("a") shouldBe a [Failure[_]]
p.parse("ab") shouldBe Success(())
p.parse("abcd") shouldBe Success(())
p.parse("abcde") shouldBe Success(())
(p <~ 'f').parse("abcdef") shouldBe Success(())
}
}

0 comments on commit 561c9ed

Please sign in to comment.