import scala util parsing combinator JavaTokenParsers Created by Stani

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import scala.util.parsing.combinator.JavaTokenParsers
/**
* Created by Stanislav on 02.05.2015.
*/
class lab4 (var text: String){
abstract class Expr
case class Variable(name : String) extends Expr
case class Number(value: Double) extends Expr
case class UnaryOp(operator: String, arg: Expr) extends Expr
case class BinaryOp(operator: String, left: Expr, right: Expr) extends Expr
def setText(t : String): Unit = {
text = t
}
object Calc {
def simplify(e: Expr): Expr = {
// сначала упрощаем подвыражения
val simpSubs = e match {
// упрощаем обе части выражения
case BinaryOp(op, left, right) => BinaryOp(op, simplify(left), simplify(right))
// упрощаем операнд
case UnaryOp(op, operand) => UnaryOp(op, simplify(operand))
// здесь нечего упрощать
case _ => e
}
// теперь упрощаем само выражение, считая,
// что все вложенные выражения уже упрощены
def simplifyTop(x: Expr) = x match {
// Двойное отрицание не меняет значение операнда
case UnaryOp("-", UnaryOp("-", x)) => x
// Знак "+" не меняет значение операнда
case UnaryOp("+", x) => x
// Умножение x на 1 равно х
case BinaryOp("*", x, Number(1)) => x
// Умножение 1 на x равно х
case BinaryOp("*", Number(1), x) => x
// Умножение х на 0 равно 0
case BinaryOp("*", x, Number(0)) => Number(0)
// Умножение 0 на x равно 0
case BinaryOp("*", Number(0), x) => Number(0)
// Деление х на 1 равно х
case BinaryOp("/", x, Number(1)) => x
// Добавление х к 0 равно х
case BinaryOp("+", x, Number(0)) => x
// Добавление 0 к х равно х
case BinaryOp("+", Number(0), x) => x
// Других вариантов упрощения нет
case _ => e
}
simplifyTop(simpSubs)
}
object ExprParser extends JavaTokenParsers {
def expr: Parser[Expr] =
(term ~ "-" ~ expr) ^^ { case lhs~minus~rhs => BinaryOp("-", lhs, rhs) } |
(term ~ "+" ~ expr) ^^ { case lhs~minus~rhs => BinaryOp("+", lhs, rhs) } |
term
def term: Parser[Expr] =
(factor ~ "*" ~ factor) ^^ { case lhs~times~rhs => BinaryOp("*", lhs, rhs) } |
(factor ~ "/" ~ factor) ^^ { case lhs~div~rhs => BinaryOp("/", lhs, rhs) } |
factor
def factor : Parser[Expr] =
"(" ~> expr <~ ")" |
floatingPointNumber ^^ {x => Number(x.toFloat)}|
ident ^^ {x => Variable(x)}
def parse(text : String) = parseAll(expr, text)
}
def parse(text : String) = {
val results = ExprParser.parse(text)
System.out.println("parsed " + text + " as " + results + " which is a type "
+ results.getClass())
results.get
}
def evaluate() : Double = evaluate(parse(text))
def evaluate(e: Expr): Double = {
simplify(e) match {
case Variable(x) => {
System.out.println("Введите значение переменной " + x)
System.out.print(x + " = ")
val temp = readLine()
evaluate(parse(temp))
}
case Number(x) => x
case UnaryOp("-", x) => -(evaluate(x))
case BinaryOp("+", x1, x2) => (evaluate(x1) + evaluate(x2))
case BinaryOp("-", x1, x2) => (evaluate(x1) - evaluate(x2))
case BinaryOp("*", x1, x2) => (evaluate(x1) * evaluate(x2))
case BinaryOp("/", x1, x2) => (evaluate(x1) / evaluate(x2))
}
}
}
}
object Main {
def main(args: Array[String]): Unit = {
var line = ""
System.out.println("Введите выражние: ")
line = readLine()
val t = new lab4(line)
while(true) {
System.out.println("Что надо сделать? Введите цифру:")
System.out.println("1. Ввести новое выражние")
System.out.println("2. Вычеслить результат")
System.out.println("3. Показать текущее выражение")
System.out.println("4. Вместо переменной выражение и перестроить дерево")
System.out.println("5. Выход")
System.out.print(">>>")
var action = readInt()
action match {
case 1 => {
line = readLine()
t.setText(line)
}
case 2 => System.out.println("Результат: " + t.Calc.evaluate())
case 3 => System.out.println("Выражение: " + line)
case 4 => System.out.println("Implemented method")
case 5 => System.exit(0)
}
}
}
}
// TODO: Иправить ошибку: 2-2-3 (скобки)