Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit df50d34

Browse files
Migrate PackratParsers tests to JUnit.
Most of the migration is straightforward. One exception is packrat3 (migrated to `test3` method). I simplified returned result by getting rid of useless Unit by changing this rule: repMany1(a,b) ~ not(b) into this rule: repMany1(a,b) <~ not(b) Also, I made all rules to be type safe. When constructing expected results, I decided to use scala.Symbol that allows us to use a bit more concise syntax for construction of one character strings. See `threeLists` method for details.
1 parent 062f7f3 commit df50d34

File tree

8 files changed

+141
-176
lines changed

8 files changed

+141
-176
lines changed

‎build.sbt‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ pomExtra := (
7676
</developers>
7777
)
7878

79+
libraryDependencies ++= Seq("junit" % "junit" % "4.11" % "test", "com.novocode" % "junit-interface" % "0.10" % "test")
80+
7981
// default value must be set here
8082
TestKeys.includeTestDependencies := true
8183

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
package scala.util.parsing.combinator
2+
3+
import org.junit.Test
4+
import org.junit.Assert.assertEquals
5+
6+
import scala.util.parsing.combinator.syntactical.StandardTokenParsers
7+
8+
class PackratParsersTest {
9+
10+
@Test
11+
def test1: Unit = {
12+
import grammars1._
13+
val head = phrase(term)
14+
15+
def extractResult(r : ParseResult[Int]): Int = r match {
16+
case Success(a,_) => a
17+
case NoSuccess(a,_) => sys.error(a)
18+
}
19+
20+
assertEquals(1,extractResult(head(new lexical.Scanner("1"))))
21+
assertEquals(3, extractResult(head(new lexical.Scanner("1+2"))))
22+
assertEquals(5, extractResult(head(new lexical.Scanner("9-4"))))
23+
assertEquals(81, extractResult(head(new lexical.Scanner("9*9"))))
24+
assertEquals(4, extractResult(head(new lexical.Scanner("8/2"))))
25+
assertEquals(37, extractResult(head(new lexical.Scanner("4*9-0/7+9-8*1"))))
26+
assertEquals(9, extractResult(head(new lexical.Scanner("(1+2)*3"))))
27+
}
28+
29+
@Test
30+
def test2: Unit = {
31+
import grammars2._
32+
val head = phrase(exp)
33+
34+
def extractResult(r : ParseResult[Int]): Int = r match {
35+
case Success(a,_) => a
36+
case NoSuccess(a,_) => sys.error(a)
37+
}
38+
39+
assertEquals(1, extractResult(head(new lexical.Scanner("1"))))
40+
assertEquals(3, extractResult(head(new lexical.Scanner("1+2"))))
41+
assertEquals(81, extractResult(head(new lexical.Scanner("9*9"))))
42+
assertEquals(43, extractResult(head(new lexical.Scanner("4*9+7"))))
43+
assertEquals(59, extractResult(head(new lexical.Scanner("4*9+7*2+3*3"))))
44+
assertEquals(188, extractResult(head(new lexical.Scanner("4*9+7*2+3*3+9*5+7*6*2"))))
45+
assertEquals(960, extractResult(head(new lexical.Scanner("4*(9+7)*(2+3)*3"))))
46+
}
47+
48+
@Test
49+
def test3: Unit = {
50+
import grammars3._
51+
val head = phrase(AnBnCn)
52+
def extractResult(r: ParseResult[AnBnCnResult]): AnBnCnResult = r match {
53+
case Success(a,_) => a
54+
case NoSuccess(a,_) => sys.error(a)
55+
}
56+
def threeLists(as: List[Symbol], bs: List[Symbol], cs: List[Symbol]): AnBnCnResult = {
57+
val as1 = as.map(_.name)
58+
val bs1 = bs.map(_.name)
59+
val cs1 = cs.map(_.name)
60+
new ~(new ~(as1, bs1), cs1)
61+
}
62+
63+
val expected1 = threeLists(List('a, 'b), List('a), List('b, 'c))
64+
assertEquals(expected1, extractResult(head(new lexical.Scanner("a b c"))))
65+
val expected2 = threeLists(List('a, 'a, 'b, 'b), List('a, 'a), List('b, 'b, 'c, 'c))
66+
assertEquals(expected2, extractResult(head(new lexical.Scanner("a a b b c c"))))
67+
val expected3 = threeLists(List('a, 'a, 'a, 'b, 'b, 'b), List('a, 'a, 'a), List('b, 'b, 'b, 'c, 'c, 'c))
68+
assertEquals(expected3, extractResult(head(new lexical.Scanner("a a a b b b c c c"))))
69+
val expected4 = threeLists(List('a, 'a, 'a, 'a, 'b, 'b, 'b, 'b), List('a, 'a, 'a, 'a), List('b, 'b, 'b, 'b, 'c, 'c, 'c, 'c))
70+
assertEquals(expected4, extractResult(head(new lexical.Scanner("a a a a b b b b c c c c"))))
71+
val failure1 = AnBnCn(new PackratReader(new lexical.Scanner("a a a b b b b c c c c"))).asInstanceOf[Failure]
72+
assertEquals("Expected failure", failure1.msg)
73+
val failure2 = AnBnCn(new PackratReader(new lexical.Scanner("a a a a b b b c c c c"))).asInstanceOf[Failure]
74+
assertEquals("``b'' expected but `c' found", failure2.msg)
75+
val failure3 = AnBnCn(new PackratReader(new lexical.Scanner("a a a a b b b b c c c"))).asInstanceOf[Failure]
76+
assertEquals("end of input", failure3.msg)
77+
}
78+
79+
}
80+
81+
private object grammars1 extends StandardTokenParsers with PackratParsers {
82+
83+
lexical.delimiters ++= List("+","-","*","/","(",")")
84+
lexical.reserved ++= List("Hello","World")
85+
86+
/****
87+
* term = term + fact | term - fact | fact
88+
* fact = fact * num | fact / num | num
89+
*/
90+
91+
92+
val term: PackratParser[Int] = (term~("+"~>fact) ^^ {case x~y => x+y}
93+
|term~("-"~>fact) ^^ {case x~y => x-y}
94+
|fact)
95+
96+
val fact: PackratParser[Int] = (fact~("*"~>numericLit) ^^ {case x~y => x*y.toInt}
97+
|fact~("/"~>numericLit) ^^ {case x~y => x/y.toInt}
98+
|"("~>term<~")"
99+
|numericLit ^^ {_.toInt})
100+
}
101+
102+
private object grammars2 extends StandardTokenParsers with PackratParsers {
103+
104+
lexical.delimiters ++= List("+","-","*","/","(",")")
105+
lexical.reserved ++= List("Hello","World")
106+
107+
/*
108+
* exp = sum | prod | num
109+
* sum = exp ~ "+" ~ num
110+
* prod = exp ~ "*" ~ num
111+
*/
112+
113+
val exp : PackratParser[Int] = sum | prod | numericLit ^^{_.toInt} | "("~>exp<~")"
114+
val sum : PackratParser[Int] = exp~("+"~>exp) ^^ {case x~y => x+y}
115+
val prod: PackratParser[Int] = exp~("*"~>(numericLit ^^{_.toInt} | exp)) ^^ {case x~y => x*y}
116+
117+
}
118+
119+
private object grammars3 extends StandardTokenParsers with PackratParsers {
120+
lexical.reserved ++= List("a","b", "c")
121+
val a: PackratParser[String] = memo("a")
122+
val b: PackratParser[String] = memo("b")
123+
val c: PackratParser[String] = memo("c")
124+
125+
type AnBnCnResult = List[String] ~ List[String] ~ List[String]
126+
127+
val AnBnCn: PackratParser[AnBnCnResult] =
128+
guard(repMany1(a,b) <~ not(b)) ~ rep1(a) ~ repMany1(b,c)// ^^{case x~y => x:::y}
129+
130+
131+
private def repMany[T](p: => Parser[T], q: => Parser[T]): Parser[List[T]] =
132+
( p~repMany(p,q)~q ^^ {case x~xs~y => x::xs:::(y::Nil)}
133+
| success(Nil)
134+
)
135+
136+
def repMany1[T](p: => Parser[T], q: => Parser[T]): Parser[List[T]] =
137+
p~opt(repMany(p,q))~q ^^ {case x~Some(xs)~y => x::xs:::(y::Nil)}
138+
139+
}

‎test/files/run/packrat1.check‎

Lines changed: 0 additions & 7 deletions
This file was deleted.

‎test/files/run/packrat1.scala‎

Lines changed: 0 additions & 47 deletions
This file was deleted.

‎test/files/run/packrat2.check‎

Lines changed: 0 additions & 7 deletions
This file was deleted.

‎test/files/run/packrat2.scala‎

Lines changed: 0 additions & 57 deletions
This file was deleted.

‎test/files/run/packrat3.check‎

Lines changed: 0 additions & 7 deletions
This file was deleted.

‎test/files/run/packrat3.scala‎

Lines changed: 0 additions & 51 deletions
This file was deleted.

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /