Guest User

Untitled

a guest
Dec 10th, 2018
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.29 KB | None | 0 0
  1. package parsing
  2.  
  3. import util.parsing.combinator.RegexParsers
  4.  
  5. /**
  6. * User: andraz
  7. * Date: 8/25/12
  8. * Time: 4:05 PM
  9. */
  10. object ExpressionParsing {
  11.  
  12. object Tokens {
  13.  
  14. sealed trait Expression
  15.  
  16. case class Number(n: Double) extends Expression
  17.  
  18. case class Add(left: Expression, right: Expression) extends Expression
  19.  
  20. case class Subtract(left: Expression, right: Expression) extends Expression
  21.  
  22. case class Multiply(left: Expression, right: Expression) extends Expression
  23.  
  24. case class Divide(left: Expression, right: Expression) extends Expression
  25.  
  26. }
  27.  
  28. object Parser extends RegexParsers {
  29.  
  30. import Tokens._
  31.  
  32. private def number: Parser[Expression] = """\d+\.?\d*""".r ^^ {
  33. s => Number(s.toDouble)
  34. }
  35.  
  36. private def factor: Parser[Expression] = number | ("(" ~> expr <~ ")")
  37.  
  38. private def term: Parser[Expression] = factor ~ rep(("*" | "/") ~ factor) ^^ {
  39. case head ~ tail => {
  40. var tree: Expression = head
  41. tail.foreach {
  42. case "*" ~ e => tree = Multiply(tree, e)
  43. case "/" ~ e => tree = Divide(tree, e)
  44. }
  45. tree
  46. }
  47. }
  48.  
  49. private def expr: Parser[Expression] = term ~ rep(("+" | "-") ~ term) ^^ {
  50. case head ~ tail => {
  51. var tree: Expression = head
  52. tail.foreach {
  53. case "+" ~ e => tree = Add(tree, e)
  54. case "-" ~ e => tree = Subtract(tree, e)
  55. }
  56. tree
  57. }
  58. }
  59.  
  60. def apply(s: String) = parseAll(expr, s) match {
  61. case Success(tree, _) => Some(tree)
  62. case e: NoSuccess => None
  63. }
  64. }
  65.  
  66. object Evaluator {
  67.  
  68. import Tokens._
  69.  
  70. def apply(e: Expression): Double = e match {
  71. case Number(n) => n
  72. case Add(l, r) => apply(l) + apply(r)
  73. case Subtract(l, r) => apply(l) - apply(r)
  74. case Multiply(l, r) => apply(l) * apply(r)
  75. case Divide(l, r) => apply(l) / apply(r)
  76. }
  77. }
  78.  
  79. def apply(s: String) = Parser(s) map Evaluator.apply
  80.  
  81. def repl = {
  82. def rep: Unit = {
  83. print(">> ")
  84. readLine match {
  85. case "exit" => return
  86. case "help" => println("enter an expression\nsupported: floats + - * / ( )")
  87. case exp => {
  88. println(
  89. apply(exp) match {
  90. case Some(res) => res
  91. case None => "invalid syntax"
  92. })
  93. rep
  94. }
  95. }
  96. }
  97. rep
  98. }
  99. }
Add Comment
Please, Sign In to add comment