打印时如何在表达式中加上括号?

时间:2018-10-31 19:25:17

标签: scala tree

我写了一个表达式简化器,将字符串作为输入,将其转换为语法树,将该树简化,然后遍历该树将输出转换回字符串。在打印诸如(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 :(得分:0)

您的stringify方法从不放入任何括号,因此您认为这是不正确的。最简单的改进是改为始终放入括号。例如:

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

其他情况也是如此。