我正在研究需要考虑运算符优先级的解析逻辑。我的需求并不太复杂。首先,我需要乘法和除法,以获得比加法和减法更高的优先级。
例如:1 + 2 * 3应视为1 +(2 * 3)。这是一个简单的例子,但你明白了!
[还有一些我需要添加到优先级逻辑的自定义标记,我可以根据我在这里收到的建议添加这些标记。]
以下是处理运算符优先级的一个示例:http://jim-mcbeath.blogspot.com/2008/09/scala-parser-combinators.html#precedencerevisited。
还有其他想法吗?
答案 0 :(得分:7)
这比Jim McBeath的例子稍微简单一些,但是你做了你所说的你需要的,即正确的算术预测,并且还允许使用括号。我修改了 Scala编程中的示例,让它实际进行计算并提供答案。
它应该是不言自明的。通过说expr
由terms
穿插运算符组成,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
}