From 9dc1228b72debb3d783d487e9531fe63b6f6b53a Mon Sep 17 00:00:00 2001 From: Alexey Rykhalskiy Date: Thu, 20 Jun 2024 11:34:06 +0300 Subject: [PATCH] -- few signatures --- .../p2concrete/math/AbstractMathParser.scala | 24 ++++++++++++------- .../math_num/MathOpToNumberSpec.scala | 9 +++++-- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/fp_red/src/main/scala/fp_red/red09/p2concrete/math/AbstractMathParser.scala b/fp_red/src/main/scala/fp_red/red09/p2concrete/math/AbstractMathParser.scala index fbd5c737..11ccd745 100644 --- a/fp_red/src/main/scala/fp_red/red09/p2concrete/math/AbstractMathParser.scala +++ b/fp_red/src/main/scala/fp_red/red09/p2concrete/math/AbstractMathParser.scala @@ -8,24 +8,30 @@ trait AbstractMathParser[A] { val R = Reference import R._ - def process[EA >: Expr[A]](t: (EA, Seq[(Char, EA)])): EA = t match { + def combine[EA >: Expr[A]](t: (EA, Seq[(Char, EA)])): EA = t match { case (n, Nil) => n - case (a, l) => l.foldLeft(a) { case (acc, (op, x)) => mkNode(op, acc, x) } + case (a, l) => l.foldLeft(a) { case (acc, (op, x)) => mkNode(op, acc, x) } } - val plusOrMinus: Parser[Char] = char('+') | char('-') - val mulOrDiv: Parser[Char] = char('*') | char('/') + val `+|-` : Parser[Char] = char('+') | char('-') + val `*|/` : Parser[Char] = char('*') | char('/') + /** this is what we call value: integer.map(x => Value(x)) */ def value: Parser[Expr[A]] + /** whatever between parens */ + def parens: Parser[Expr[A]] = surround(char('('), char(')'))(addSubSeq) + + def term: Parser[Expr[A]] = value | parens + /** recursive grammar */ - def parens = surround(char('('), char(')'))(addSub) - def factor = value | parens + def mulDivSeq: Parser[Expr[A]] = (term ** (`*|/` ** term).many) // (Expr[A], List[(Char, Expr[A])]) + .map(combine) - def divMul = ( factor ** (mulOrDiv ** factor).many ).map(process) - def addSub: Parser[Expr[A]] = ( divMul ** (plusOrMinus ** divMul).many ).map(process) + def addSubSeq: Parser[Expr[A]] = (mulDivSeq ** (`+|-` ** mulDivSeq).many) // (Expr[A], List[(Char, Expr[A])]) + .map(combine) /** root of grammar */ - def built = root(addSub) + def built: Parser[Expr[A]] = root(addSubSeq) } diff --git a/fp_red/src/main/scala/fp_red/red09/p2concrete/math_num/MathOpToNumberSpec.scala b/fp_red/src/main/scala/fp_red/red09/p2concrete/math_num/MathOpToNumberSpec.scala index 71404c1c..63b05e79 100644 --- a/fp_red/src/main/scala/fp_red/red09/p2concrete/math_num/MathOpToNumberSpec.scala +++ b/fp_red/src/main/scala/fp_red/red09/p2concrete/math_num/MathOpToNumberSpec.scala @@ -1,10 +1,11 @@ package fp_red.red09.p2concrete.math_num +import fp_red.red09.p0trait.ParseError import fp_red.red09.p1impl.Reference +import fp_red.red09.p2concrete.math.BiTree import org.scalatest.matchers.should.Matchers import org.scalatest.funspec.AnyFunSpec -// 1 class MathOpToNumberSpec extends AnyFunSpec with Matchers { val R = Reference @@ -21,7 +22,11 @@ class MathOpToNumberSpec extends AnyFunSpec with Matchers { "1-2*3", "(1-2)*-3", "((1-2)*(3+4))/5-1", - ).foreach { s => pprint.log(R.run(built)(s)) } + ).foreach { input => + val parser: String => Either[ParseError, BiTree.Expr[Int]] = R.run(built) + val parsed: Either[ParseError, BiTree.Expr[Int]] = parser(input) + pprint.log(parsed) + } } }