如何构建简单表达式的解析树

时间:2016-10-21 10:46:46

标签: scala parsing

让我们使用3 - 4 * 5scala.util.parsing.combinator._等简单表达式构建解析器树:

def expr: Parser[Any] = term ~ opt(("+"|"-") ~ expr)
def term: Parser[Any] = factor ~ opt(("*"|"/") ~ factor)
def factor: Parser[Any] = wholeNumber | "(" ~> expr <~ ")"

使用3 - 4 * 5,结果树为:

       expr
      / |  \
  term  -   expr
   |       / |  \
 factor term * term  
   |      |      |
 number factor factor
   |      |      |
   3    number number
          |      |
          4      5

哪个是对的。但是使用3 - 4 + 5我的树似乎不正确:

       expr
      / |  \
  term  -   expr
   |       / |  \
 factor term + term  
   |      |      |
 number factor factor
   |      |      |
   3    number number
          |      |
          4      5

我该如何解决?我认为这是解决方案:

def expr: Parser[Any] = expr ~ opt(("+"|"-") ~ term)

但这太错了......

我的完整代码

import scala.util.parsing.combinator._


class Expr

case class Number(value: Int) extends Expr {
    override def toString = s"$value"
}

case class Operator(left: Expr, right: Expr, f: (Int, Int) => Int) extends Expr {
    override def toString = s"($f, $left, $right)"
}

class SimpleLanguageParser extends JavaTokenParsers {

    def expr: Parser[Expr] = (term ~ opt(("+" | "-") ~ expr)) ^^ {
        case a ~ None => a
        case a ~ Some("+" ~ b) => Operator(a, b, _ + _)
        case a ~ Some("-" ~ b) => Operator(a, b, _ - _)
    }

    def term: Parser[Expr] = (factor ~ opt(("*" | "/" ) ~ term)) ^^ {
        case a ~ None => a
        case a ~ Some("*" ~ b) => Operator(a, b, _ * _)
        case a ~ Some("/" ~ b) => Operator(a, b, _ / _)
    }

    def factor: Parser[Expr] = wholeNumber ^^ (n => Number(Integer.parseInt(n))) | "(" ~> expr <~ ")"

}

object Main {
    def main(args: Array[String]) = {
        val parser = new SimpleLanguageParser
        val result = parser.parse(parser.expr, "3 - 4 + 5")
        println(result)
    }
}

1 个答案:

答案 0 :(得分:0)

我认为def largerExpr: Parser[Any] = expr ~ opt(("+"|"-") ~ expr) def expr: Parser[Any] = term ~ opt(("+"|"-") ~ term) 无法保留+/-操作的顺序。

def expr1: Parser[Expr] = (expr ~ opt(("+" | "-") ~ expr)) ^^ {
    case a ~ None => a
    case a ~ Some("+" ~ b) => Operator(a, b, _ + _)
    case a ~ Some("-" ~ b) => Operator(a, b, _ - _)
}

def expr: Parser[Expr] = (term ~ opt(("+" | "-") ~ term)) ^^ {
    case a ~ None => a
    case a ~ Some("+" ~ b) => Operator(a, b, _ + _)
    case a ~ Some("-" ~ b) => Operator(a, b, _ - _)
}

EIDT

(<function2>, 3, (<function2>, 4, 5))

您的结果为expr1,使用(<function2>, (<function2>, 3, 4), 5)的结果为print~