|
| 1 | +packagescala.util.parsing.combinator |
| 2 | + |
| 3 | +// import scala.language.implicitConversions |
| 4 | + |
| 5 | +importjava.io.StringReader |
| 6 | +importorg.junit.Test |
| 7 | +importorg.junit.Assert.{assertEquals,assertTrue,fail } |
| 8 | +importscala.util.parsing.input.StreamReader |
| 9 | + |
| 10 | +classPrecedenceParsersTest { |
| 11 | + |
| 12 | +abstractclassOp |
| 13 | +objectPlusextendsOp { |
| 14 | +overridedeftoString="+" |
| 15 | + } |
| 16 | +objectMinusextendsOp { |
| 17 | +overridedeftoString="-" |
| 18 | + } |
| 19 | +objectMultextendsOp { |
| 20 | +overridedeftoString="*" |
| 21 | + } |
| 22 | +objectDivideextendsOp { |
| 23 | +overridedeftoString="/" |
| 24 | + } |
| 25 | +objectEqualsextendsOp { |
| 26 | +overridedeftoString="=" |
| 27 | + } |
| 28 | + |
| 29 | +abstractclassNode |
| 30 | +caseclassLeaf(v:Int)extendsNode { |
| 31 | +overridedeftoString= v.toString |
| 32 | + } |
| 33 | +caseclassBinop(lhs:Node,op:Op,rhs:Node)extendsNode { |
| 34 | +overridedeftoString=s"($lhs$op$rhs)" |
| 35 | + } |
| 36 | + |
| 37 | +objectArithmeticParserextendsRegexParsers { |
| 38 | +valprec=List( |
| 39 | + (Associativity.Left,List(Mult,Divide)), |
| 40 | + (Associativity.Left,List(Plus,Minus)), |
| 41 | + (Associativity.Right,List(Equals))) |
| 42 | +definteger:Parser[Leaf]="[0-9]+".r^^ {s:String=>Leaf(s.toInt) } |
| 43 | +defbinop:Parser[Op]="+"^^^Plus|"-"^^^Minus|"*"^^^Mult|"/"^^^Divide|"="^^^Equals |
| 44 | +defexpression=newPrecedenceParser(integer, binop, prec,Binop.apply) |
| 45 | + } |
| 46 | + |
| 47 | +deftestExp(expected:Node,input:String):Unit= { |
| 48 | +ArithmeticParser.expression(StreamReader(newStringReader(input)))match { |
| 49 | +caseArithmeticParser.Success(r, next)=> { |
| 50 | + assertEquals(expected, r); |
| 51 | + assertTrue(next.atEnd); |
| 52 | + } |
| 53 | +case e=> { |
| 54 | + fail(s"Error parsing$input:$e"); |
| 55 | + } |
| 56 | + } |
| 57 | + } |
| 58 | + |
| 59 | +@Test |
| 60 | +defbasicExpTests:Unit= { |
| 61 | + testExp(Leaf(4),"4") |
| 62 | + testExp(Binop(Leaf(1),Plus,Leaf(2)),"1 + 2") |
| 63 | + testExp(Binop(Leaf(2),Mult,Leaf(1)),"2 * 1") |
| 64 | + } |
| 65 | + |
| 66 | +@Test |
| 67 | +defassociativityTests:Unit= { |
| 68 | + testExp(Binop(Binop(Leaf(1),Minus,Leaf(2)),Plus,Leaf(3)),"1 - 2 + 3") |
| 69 | + testExp(Binop(Leaf(1),Equals,Binop(Leaf(2),Equals,Leaf(3))),"1 = 2 = 3") |
| 70 | + } |
| 71 | + |
| 72 | +@Test |
| 73 | +defprecedenceTests:Unit= { |
| 74 | + testExp(Binop(Binop(Leaf(0),Mult,Leaf(5)),Minus,Leaf(2)),"0 * 5 - 2") |
| 75 | + testExp(Binop(Leaf(3),Plus,Binop(Leaf(9),Divide,Leaf(11))),"3 + 9 / 11") |
| 76 | + testExp(Binop(Binop(Leaf(6),Plus,Leaf(8)),Equals,Leaf(1)),"6 + 8 = 1") |
| 77 | + testExp(Binop(Leaf(4),Equals,Binop(Leaf(5),Minus,Leaf(3))),"4 = 5 - 3") |
| 78 | + } |
| 79 | +} |