Scala Parser组合器的运算符优先级

Sur*_*apu 7 functional-programming scala parser-combinators

我正在研究一种需要考虑运算符优先级的解析逻辑.我的需求并不太复杂.首先,我需要乘法和除法,以获得比加法和减法更高的优先级.

例如:1 + 2*3应视为1 +(2*3).这是一个简单的例子,但你明白了!

[我还需要添加几个自定义令牌才能添加到优先级逻辑中,我可以根据我在此处收到的建议添加这些令牌.]

以下是处理运算符优先级的一个示例:http://jim-mcbeath.blogspot.com/2008/09/scala-parser-combinators.html#precedencerevisited.

还有其他想法吗?

Lui*_*hys 7

这比Jim McBeath的例子稍微简单一点,但是你做了你所说的你需要的,即正确的算术预测,并且还允许使用括号.我修改了Scala编程中的示例,让它实际进行计算并提供答案.

它应该是不言自明的.有一个层次结构,它由一个exprterms运算符穿插而成,terms由运算符组成factors,并且factors是括号中的浮点数或表达式.

import scala.util.parsing.combinator.JavaTokenParsers

class Arith extends JavaTokenParsers {

  type D = Double

  def expr:   Parser[D]    = term ~ rep(plus | minus)     ^^ {case a~b => (a /: b)((acc,f) => f(acc))} 
  def plus:   Parser[D=>D] = "+" ~ term                   ^^ {case "+"~b => _ + b}
  def minus:  Parser[D=>D] = "-" ~ term                   ^^ {case "-"~b => _ - b}
  def term:   Parser[D]    = factor ~ rep(times | divide) ^^ {case a~b => (a /: b)((acc,f) => f(acc))}
  def times:  Parser[D=>D] = "*" ~ factor                 ^^ {case "*"~b => _ * b }
  def divide: Parser[D=>D] = "/" ~ factor                 ^^ {case "/"~b => _ / b} 
  def factor: Parser[D]    = fpn | "(" ~> expr <~ ")" 
  def fpn:    Parser[D]    = floatingPointNumber          ^^ (_.toDouble)

}

object Main extends Arith with App {
  val input = "(1 + 2 * 3 + 9) * 2 + 1"
  println(parseAll(expr, input).get) // prints 33.0
}
Run Code Online (Sandbox Code Playgroud)