2

中置演算子の左連想ツリーを構築するための構文をマスターしました。

term * (
        "+" ^^^ { (a:Expr, b:Expr) => new FunctionCall(plus, a::b::Nil) } |
        "-" ^^^ { (a:Expr, b:Expr) => new FunctionCall(minus, a::b::Nil) } )

告白しなければなりませんが、それがどのように機能するかを完全には理解していません。私が今やりたいことは、次のような構文に対して同様の効果を達成することです

a[b](c)(d)[e]

として解析する必要があります

sub(call(call(sub(a, b), c), d), e)

高レベルの "^^^" マジックを拡張して、純粋な中置演算子ではない場合をカバーできますか? それとも、ある種の左折ロジックを自分で実装する必要がありますか? もしそうなら、それがどのように見えるかについてのヒントはありますか?

4

1 に答える 1

0

私は次のように問題を解決しました。私はこの解決策に満足していますが、Scala の専門家が解決策を改善するのを手伝ってくれるなら、それは大歓迎です。

  def subscript: Parser[Expr => Expr] = {
    "[" ~> expr <~ "]" ^^ {
      case sub => {
        { (base: Expr) => new FunctionCall(subscriptFn, base :: sub :: Nil)}
      }
    }
  }

  def argumentList: Parser[Expr => Expr] = {
    "(" ~> repsep(expr, ",") <~ ")" ^^ {
      case args => {
        { (base: Expr) => new FunctionCall(base :: args)}
      }
    }
  }

  def postfixExpr: Parser[Expr] = {
    primary ~ rep ( subscript | argumentList ) ^^ {
      case base ~ suffixes => {
        (base /: suffixes)((b:Expr, f:Expr=>Expr) => f(b))
      }
    }
  }
于 2013-05-16T07:32:09.670 に答える