让我们使用3 - 4 * 5
为scala.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)
}
}
答案 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~