scala.util.parsing.combinator.RegexParsers构造函数无法实例化为预期类型

时间:2018-04-28 14:01:09

标签: scala parser-combinators

我希望能够使用Scala解析器组合器解析下面的字符串。

aaa22[bbb33[ccc]ddd]eee44[fff]

在每个空方括号之前,保证存在整数字。

到目前为止我的代码:

import scala.util.parsing.combinator.RegexParsers

trait AST
case class LetterSeq(value: String) extends AST
case class IntLiteral(value: String) extends AST
case class Repeater(count: AST, content: List[AST]) extends AST

class ExprParser extends RegexParsers {
  def intLiteral: Parser[AST] = "[0-9]+".r ^^ IntLiteral
  def letterSeq: Parser[AST] = "[a-f]+".r ^^ LetterSeq
  def term: Parser[AST] = letterSeq | repeater
  def expr: Parser[List[AST]] = rep1(term)
  def repeater: Parser[AST] = intLiteral ~> "[" ~> expr <~ "]" ^^ {
    case intLiteral ~ expr => Repeater(intLiteral, expr)
  }
}

我收到的消息:

<console>:25: error: constructor cannot be instantiated to expected type;
 found   : ExprParser.this.~[a,b]
 required: List[AST]
           case intLiteral ~ expr => Repeater(intLiteral, expr)

有什么想法吗?

稍后编辑:在@ sepp2k建议更改后,我仍然得到相同的错误。改变是:

def repeater: Parser[AST] = intLiteral ~ "[" ~> expr <~ "]" ^^ {

1 个答案:

答案 0 :(得分:1)

错误消息告诉您,您正在针对~构造函数对列表进行模式匹配,这是不允许的。要在模式中使用~,您需要在解析器中使用~

在这种情况下,问题很简单,就是当您不想要时,使用intLiteral丢弃了~>的值。如果您在此处使用~而不是~>并添加括号 1 ,则可以解决您的问题。

1 括号是必需的,因此以下~>只会抛弃括号而不是intLiteral ~ "["的结果。 intLiteral ~ "[" ~> expr <~ "]"被解析为(intLiteral ~ "[") ~> expr <~ "]",但仍会丢弃intLiteral。您希望intLiteral ~ ("[" ~> expr <~ "]")仅丢弃[]