Конструктор scala.util.parsing.combinator.RegexParsers не может быть создан для ожидаемого типа. - PullRequest
0 голосов
/ 28 апреля 2018

Я хочу иметь возможность анализировать строки, подобные приведенной ниже, с помощью комбинаторов синтаксического анализа 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 голосов
/ 28 апреля 2018

Сообщение об ошибке говорит вам, что вы соответствует шаблону списку с конструктором ~, что недопустимо. Чтобы использовать ~ в вашем паттерне, вы должны использовать ~ в парсере.

Похоже, что в этом случае проблема заключается в том, что вы просто отбросили значение intLiteral, используя ~>, когда не хотели этого делать. Если вы используете ~ вместо ~> здесь и добавляете скобки 1 , это должно решить вашу проблему.

1 Требуются круглые скобки, поэтому следующий ~> только убирает скобку вместо результата intLiteral ~ "[". intLiteral ~ "[" ~> expr <~ "]" анализируется как (intLiteral ~ "[") ~> expr <~ "]", который по-прежнему выбрасывает intLiteral. Вы хотите intLiteral ~ ("[" ~> expr <~ "]"), который только выбрасывает [ и ].

...