Arithmetic evaluation: Difference between revisions

Content added Content deleted
m (→‎Icon and Unicon: header simplification)
Line 1,998: Line 1,998:
is practically non-existent, to avoid obscuring the code.
is practically non-existent, to avoid obscuring the code.


<lang scala>package org.rosetta.arithmetic_evaluator.scala
<lang scala>
package org.rosetta.arithmetic_evaluator.scala


object ArithmeticParser extends scala.util.parsing.combinator.RegexParsers {
object ArithmeticParser extends scala.util.parsing.combinator.RegexParsers {


def readExpression(input: String) : Option[()=>_] = {
def readExpression(input: String) : Option[()=>Int] = {
parseAll(expr, input) match {
parseAll(expr, input) match {
case Success(result, _) =>
case Success(result, _) =>
Some(result)
Some(result)
case other =>
case other =>
println(other)
println(other)
None
None
}
}
}
}


private type AST = ()=>Int
private def expr : Parser[()=>Int] = {
(term<~"+")~expr ^^ { case l~r => () => l() + r() } |
(term<~"-")~expr ^^ { case l~r => () => l() - r() } |
term
}


private def expr : Parser[AST] =
private def term : Parser[()=>Int] = {
(term~("+" | "-")~expr ^^ toExpr) | term
(factor<~"*")~term ^^ { case l~r => () => l() * r() } |
(factor<~"/")~term ^^ { case l~r => () => l() / r() } |
factor
}


private def term : Parser[AST] =
private def factor : Parser[()=>Int] = {
"("~>expr<~")" |
(factor~("*" | "/")~term ^^ toExpr) | factor
"\\d+".r ^^ { x => () => x.toInt } |

failure("Expected a value")
private def factor : Parser[AST] =
"("~> expr <~")" | digits ^^ toLiteral | failure("Expected a value")

private def digits =
"\\d+".r

private def toLiteral(partialResult: String) =
() => partialResult.toInt

private def toExpr(partialResult: ~[~[AST, String], AST]) = {
partialResult match {
case (l~op)~r =>
op match {
case "+" => () => l() + r()
case "-" => () => l() - r()
case "*" => () => l() * r()
case "/" => () => l() / r()
case x => error("Unknown operation " + x + ".")
}
}
}
}
}
}
Line 2,055: Line 2,044:
} while (input != "q")
} while (input != "q")
}
}
}
}</lang>
</lang>


Example:
Example: