6

Cay Horstmann のコンビネーター パーサーの演習を行っています。match ステートメントで、数値を表す文字列と変数を表す文字列を区別する最善の方法を考えています。

def factor: Parser[ExprTree] = (wholeNumber | "(" ~ expr ~ ")" | ident) ^^ {
    case a: wholeNumber  => Number(a.toInt)
    case a: String => Variable(a)
}

そこの 2 行目の「case a: wholeNumber」は正しくありません。正規表現について考えましたが、「ケース」で動作させる方法が見つかりませんでした。

4

1 に答える 1

6

少し分割して、事例分析を|. これは、コンビネータの利点の 1 つであり、実際には LL(*) 解析全般です。

def factor: Parser[ExprTree] = ( wholeNumber ^^ { Number(_.toInt) }
                               | "(" ~> expr <~ ")" 
                               | ident ^^ { Variable(_) } )

アンダースコアの構文に慣れていない場合は、申し訳ありません。基本的には、「 n番目のパラメーターを囲んでいる関数値に置き換える」ことを意味します。したがって{ Variable(_) }、 と同等{ x => Variable(x) }です。

ここでのもう 1 つの構文マジックは、 の代わりに~>and<~演算子です~。これらの演算子は、その用語の解析には両方の括弧の構文を含める必要があることを意味しますが、結果は の結果によってのみ決定される必要がありexprます。したがって、 は"(" ~> expr <~ ")"とまったく同じものに一致"(" ~ expr ~ ")"しますが、 から内部の結果値を取得するために追加のケース分析は必要ありませんexpr

于 2008-11-02T19:44:07.103 に答える