带有嵌套括号的 scala 解析

发布于 2024-10-16 04:43:57 字数 632 浏览 1 评论 0原文

尝试解析嵌套表达式,例如 GroupParser.parse("{{a}{{c}{d}}}") 经过几个小时后,我现在有了以下可以很好地解析 {a} 的片段,但失败并有

[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)
    }

}

任何提示吗?

Trying to parse an nested expressions like GroupParser.parse("{{a}{{c}{d}}}")
After many hours i have now following snipplet that parse {a} well, but fails with

[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)
    }

}

any hints?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

帝王念 2024-10-23 04:43:57

问题不在于嵌套,而在于排序。您的语法允许在花括号内任意嵌套表达式,但并没有说可以对表达式进行排序,因此解析器无法处理紧随其后的 {a} {{b}{c}}。您可以在语法中使用显式递归或使用 http://www.scala-lang.org/api/current/scala/util/parsing/combinator/Parsers.html

The problem isn't nesting, it's sequencing. Your grammar would allow arbitrary nesting of expressions inside curlies, but doesn't say that an expression can be sequenced so the parser can't handle {a} followed immediately by {{b}{c}}. You can code sequencing using explicit recursion in your grammar or by using one of the rep variants in http://www.scala-lang.org/api/current/scala/util/parsing/combinator/Parsers.html

白鸥掠海 2024-10-23 04:43:57

表达式可以重复多次吗?如果是这样,这将起作用:

def expr = ( vstring | parens )+

但是,尚不清楚您的语法是什么,或者为什么您的示例可以接受。

Can expressions be repeated multiple times? If so, this would work:

def expr = ( vstring | parens )+

However, it is not clear what is your grammar, or why would your example be acceptable.

表情可笑 2024-10-23 04:43:57

这会解析您给出的两个示例:

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)))))

This parses the two examples you gave:

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}}}")
  }
}

And succeeds with output:

Tree: ValueNode(a)
Tree: ValueNode(a)
Tree: ValueListNode(List(ValueNode(a), ValueListNode(List(ValueNode(b), ValueNode(c)))))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文