Как я могу добавить скобки обратно в выражение при печати? - PullRequest
0 голосов
/ 31 октября 2018

Я написал упрощающее выражение, которое принимает строку в качестве входных данных, преобразует ее в синтаксическое дерево, упрощает это дерево, а затем, наконец, проходит по дереву, чтобы преобразовать выходные данные обратно в строку. Мне трудно понять, как вернуть скобки в выражение, когда я печатаю вложенное решение, такое как: (a || !b) && c Прямо сейчас мой код дает мне решение a || !b && c. Кажется, что мое решение правильное, потому что упрощенное дерево выводит правильно, я просто не знаю, как добавить скобки при обходе.

Вот мой код:

import scala.util.parsing.combinator._
import scala.io.StdIn.readLine

abstract class Expression
case class And(l: Expression, r: Expression) extends Expression
case class Or(l: Expression, r: Expression) extends Expression
case class Not(arg: Expression) extends Expression
case class Var(n: Char) extends Expression
case object True extends Expression
case object False extends Expression


object Simplifier extends Combinators {

  def eval(e: Expression):  Expression = e match {


case Or(True, _) => True
case Or(_, True) => True
case Or(l, False) => l
case Or(False, r) => r
case Or(l, r) => {
  val leval = eval(l)
  val reval = eval(r)
  (leval, reval) match {
    case (True, _) => True
    case (_, True) => True
    case (l, False) => l
    case (False, r) => r
    case (leval, reval) => Or(eval(l),eval(r))
  }
}

case And(True, r) => if(r == True) {return True} else {return r}
case And(l, True) => if(l == True) {return True} else {return l}
case And(False, _) => False
case And(_, False) => False
case And(l, r) => {
  val leval = eval(l)
  val reval = eval(r)
  (leval, reval) match {
    case (True, r) => if(r == True) {return True} else {return r}
    case (l, True) => if(l == True) {return True} else {return l}
    case (False, _) => False
    case (_, False) => False
    case (leval, reval) => And(eval(l), eval(r))
  }
}

case Not(True) => False
case Not(False) => True
case Not(arg) => Not(eval(arg))

case Var(n) => Var(n)
  }

def stringify(e: Expression): String = e match{
case Or(l, r) => {
  stringify(l) + " || " + stringify(r)
}

case And(l, r) => {
  stringify(l) + " && " + stringify(r)
}

case Not(arg) => {
  "!" + stringify(arg)
}

case Var(n) => n.toString()

case True => "true"
case False => "false"

  }

def main(args:Array[String]): Unit = {

var response: String = ""

do {
  println("expression? ")
  val input = readLine()

  val expr: Expression = parseAll(e, input).get
  println(eval(expr))
  val simplifiedExpression: String = stringify(eval(expr))
  println(simplifiedExpression)

  println("Would you like to enter another expression? (y/n): ")
  response = readLine()
} while (response != "n")

}
}


class Combinators extends JavaTokenParsers {

  def e: Parser[Expression] = t ~ or ~ e ^^ {case l ~ _ ~ r => Or(l, r)} | t
  def t: Parser[Expression] = f ~ and ~ t ^^ {case l ~ _ ~ r => And(l, r)} | f
  def f: Parser[Expression] = not ~ a ^^ {case _ ~ arg => Not(arg)} | a
  def a: Parser[Expression] = openparen ~ e ~ closeparen ^^ {case _ ~ e ~ _ => e} | c

  def c: Parser[Expression] = "true" ^^ {case "true" => True} | "false" ^^ {case "false" => False} | z

  def z: Parser[Var] = "[a-c]".r ^^ {str => Var(str.head)}
  def and[Expression] = "&&"
  def or[Expression] = "||"
  def not[Expression] = "!"
  def openparen[Expression] = "("
  def closeparen[Expression] = ")"
}

1 Ответ

0 голосов
/ 31 октября 2018

Ваш stringify метод никогда ставит круглые скобки, так что это не может быть правильным, как вы выяснили. Самым простым улучшением было бы всегда вместо скобок. Например:

case Or(l, r) => {
  "(" + stringify(l) + " || " + stringify(r) + ")"
}

И аналогично для других случаев.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...