Scala 解析器,为什么 "pat <~ pat ~> pat"不起作用?

标签 scala parser-combinators

尝试一个简单的解析器组合器,我遇到了编译错误。

我想将“Smith, Joe”解析为其 Name 对象,如 Name(Joe, Smith)。我想很简单。

这是与此相关的代码:

    import util.parsing.combinator._

    class NameParser extends JavaTokenParsers {
      lazy val name: Parser[Name] = 
        lastName <~ "," ~> firstName ^^ {case (l ~ f) => Name(f, l)}
      lazy val lastName = stringLiteral
      lazy val firstName = stringLiteral
    }

    case class Name(firstName:String, lastName: String)

我正在通过测试它

object NameParserTest {
  def main(args: Array[String]) {
    val parser = new NameParser()
    println(parser.parseAll(parser.name, "Schmo, Joe"))
  }
}

出现编译错误:

error: constructor cannot be instantiated to expected type;
found   : NameParser.this.~[a,b]
required: java.lang.String
lazy val name: Parser[Name] = lastName <~ "," ~> firstName ^^ {case (l ~ f) => Name(f, l)}

我在这里缺少什么?

最佳答案

在此行中:

  lazy val name: Parser[Name] = 
    lastName <~ "," ~> firstName ^^ {case (l ~ f) => Name(f, l)}

您不想同时使用 <~~> 。您正在创建一个与 "," 匹配的解析器和firstName并只保留 "," ,然后您将创建一个与 lastName 匹配的解析器和之前的解析器只保留 lastName .

您可以将其替换为:

(lastName <~ ",") ~ firstName ^^ {case (l ~ f) => Name(f, l)}

但是,虽然这会按照您想要的方式进行编译和组合,但它不会解析您想要的内容。当我尝试时,我得到了这个输出:

[1.1] failure: string matching regex `"([^"\p{Cntrl}\\]|\\[\\/bfnrt]|\\u[a-fA-F0-9]{4})*"' expected but `S' found

Schmo, Joe
^

stringLiteral期望看起来像代码中的字符串文字的东西(引号中的东西)。 ( JavaTokenParsers 旨在解析看起来像 Java 的东西。)这有效:

scala> val x = new NameParser
x: NameParser = NameParser@1ea8dbd

scala> x.parseAll(x.name, "\"Schmo\", \"Joe\"")
res0: x.ParseResult[Name] = [1.15] parsed: Name("Joe","Schmo")

您可能应该将其替换为正则表达式,该正则表达式指定您将接受名称字符串的类型。如果您查看文档 here ,你会看到:

implicit def regex (r: Regex) : Parser[String]

A parser that matches a regex string

所以你可以只输入 Regex那里的对象,它将被转换为与其匹配的解析器。

关于Scala 解析器,为什么 "pat <~ pat ~> pat"不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5765216/

相关文章:

scala - 尾递归 vs 头经典递归

bash - sbt 外部进程无法处理 `eval` 命令

scala - 线程 "main"java.lang.NoClassDefFoundError : org/rogach/scallop/ScallopConf 中的异常

json - Play + Anorm + Postgres - 将 json 值加载到案例类中

Scala 解析器组合器 - 消耗直到匹配

Scala解析器 token 定界符问题

rust - 调用一个函数,该函数使用不同的闭包进行两次闭包

Scala Generic,通过变量指定泛型

parsing - 在解析器组合器中组合词法分析器和解析器

error-handling - 为什么解析器组合器在发生故障的情况下不回退?