2011-02-03 12 views
1

GroupParser.parse( "{{}} {}}"のようなネストされた式を解析しようとしています 何時間も後、が失敗します。ネストされた括弧でスカラーを解析する

[1.5] failure: ``}'' expected but `{' found 
{{a}{{b}{c}}} 
    ^

sealed abstract class Expr 

case class ValueNode(value:String) extends Expr 

object GroupParser extends StandardTokenParsers { 
    lexical.delimiters ++= List("{","}") 

    def vstring = ident ^^ { case s => ValueNode(s) } 
    def expr = (vstring | parens) 
    def parens:Parser[Expr] = "{" ~> expr <~ "}" 

    def parse(s:String) = { 
     val tokens = new lexical.Scanner(s) 
     phrase(expr)(tokens) 
    } 

} 

ヒント

+0

あなたの質問には答えていませんか? –

答えて

3

問題は入れ子になっていません。順序は決まっています。あなたの文法は、中括弧の中に式を任意に入れ子にすることができますが、式を順序付けることができないので、{a}とそれに続く{{b} {c}}は処理できません。文法の明示的な再帰を使用してシーケンスをコード化するか、またはrepバリアントの1つを使用してコード化することができますhttp://www.scala-lang.org/api/current/scala/util/parsing/combinator/Parsers.html

1

式を複数回繰り返すことはできますか?もしそうなら、これはうまくいくでしょう:

def expr = (vstring | parens)+ 

しかし、あなたの文法は何か、あるいはあなたの例がなぜ受け入れられるのかは不明です。

0

これは、あなたが与えた二つの例解析します

import scala.util.parsing.combinator.syntactical._ 

sealed abstract class Expr 

case class ValueNode(value:String) extends Expr 

case class ValueListNode(value:List[Expr]) extends Expr 

object GroupParser extends StandardTokenParsers { 
    lexical.delimiters ++= List("{","}") 

    def vstring = ident ^^ { case s => ValueNode(s) } 
    def parens:Parser[Expr] = "{" ~> (expr) <~ "}" 
    def expr = vstring | parens 

    def exprList:Parser[Expr] = "{" ~> rep1(expr | exprList) <~ "}" ^^ { 
    case l => { 
     ValueListNode(l) 
    } 
    } 

    def anyExpr = expr | exprList 

    def parse(s:String) = { 
    val tokens = new lexical.Scanner(s) 
    phrase(anyExpr)(tokens) 
    } 

    def test(s: String) = { 
    parse(s) match { 
     case Success(tree, _) => 
     println("Tree: " + tree) 
     case e: NoSuccess => Console.err.println(e) 
    } 
    } 

    def main(args: Array[String]) = { 
    test("{a}") 
    test("{{a}}") 
    test("{{a}{{b}{c}}}") 
    } 
} 

をして出力して成功します。

Tree: ValueNode(a) 
Tree: ValueNode(a) 
Tree: ValueListNode(List(ValueNode(a), ValueListNode(List(ValueNode(b), ValueNode(c))))) 
関連する問題