8

演算子の優先順位を考慮する必要がある解析ロジックに取り組んでいます。私のニーズはそれほど複雑ではありません。まず、足し算と引き算よりも掛け算と割り算を優先する必要があります。

例: 1 + 2 * 3 は 1 + (2 * 3) として扱われます。これは簡単な例ですが、要点はわかります。

[優先順位ロジックに追加する必要があるカスタム トークンがいくつかあります。ここで受け取った提案に基づいて追加できる可能性があります。]

演算子の優先順位を扱う一例を次に示します: http://jim-mcbeath.blogspot.com/2008/09/scala-parser-combinators.html#precedencerevisited

他のアイデアはありますか?

4

1 に答える 1

8

これは、Jim McBeath の例よりも少し単純ですが、必要なこと、つまり正しい算術優先順位を実行し、括弧も使用できます。Programming in Scalaの例を適用して、実際に計算を行い、答えを提供できるようにしました。

それは非常に自明であるはずです。散在する演算子でexpr構成され、演算子で構成され、括弧内の浮動小数点数または式であると言うことによって形成される階層があります。termstermsfactorsfactors

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
}
于 2012-07-18T03:17:39.527 に答える