私は Scala Parser Combinators の使い方を学んでいます。
残念ながら、コンパイルエラーが発生しています。http://www.artima.com/pins1ed/combinator-parsing.html <-- Programming in Scala, First Edition の第 31 章、および他のいくつかのブログから、動作する例を読み、再作成しました。
問題を示すために、コードをより単純なバージョンに減らしました。次のサンプルを解析するパーサーに取り組んでいます
if a then x else y
if a if b then x else y else z
条件にオプションの「/1,2,3」構文を含めることができるという少し余分なものがあります
if a/1 then x else y
if a/2,3 if b/3,4 then x else y else z
だから私は次のコードで終わった
def ifThenElse: Parser[Any] =
"if" ~> condition ~ inputList ~ yes ~> "else" ~ no
def condition: Parser[Any] = ident
def inputList: Parser[Any] = opt("/" ~> repsep(input, ","))
def input: Parser[Any] = ident
def yes: Parser[Any] = "then" ~> result | ifThenElse
def no: Parser[Any] = result | ifThenElse
def result: Parser[Any] = ident
ここで、いくつかの変換を追加したいと思います。次の場合、2 番目の ~ でコンパイル エラーが発生します。
def ifThenElse: Parser[Any] =
"if" ~> condition ~ inputList ~ yes ~> "else" ~ no ^^ {
case c ~ i ~ y ~ n => null
^ constructor cannot be instantiated to expected type; found : SmallestFailure.this.~[a,b] required: String
コードを次のように変更すると
"if" ~> condition ~ inputList ~ yes ~> "else" ~ no ^^ {
case c ~ i => println("c: " + c + ", i: " + i)
コンパイルされないことを期待していましたが、コンパイルされました。節ごとに変数が必要だと思いました。(parseAll を使用して) 実行すると、「if a then b else c」を解析すると、「c: else, i: c」が生成されます。つまり、c と i は文字列の末尾のようです。
それが重要かどうかはわかりませんが、チュートリアルの例には、2 つ以上の変数が一致する例がないようで、これは 4 つに一致しています。