我希望能够使用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 <~ "]" ^^ {
答案 0 :(得分:1)
错误消息告诉您,您正在针对~
构造函数对列表进行模式匹配,这是不允许的。要在模式中使用~
,您需要在解析器中使用~
。
在这种情况下,问题很简单,就是当您不想要时,使用intLiteral
丢弃了~>
的值。如果您在此处使用~
而不是~>
并添加括号 1 ,则可以解决您的问题。
1 括号是必需的,因此以下~>
只会抛弃括号而不是intLiteral ~ "["
的结果。 intLiteral ~ "[" ~> expr <~ "]"
被解析为(intLiteral ~ "[") ~> expr <~ "]"
,但仍会丢弃intLiteral
。您希望intLiteral ~ ("[" ~> expr <~ "]")
仅丢弃[
和]
。