加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala:如何组合来自不同对象的解析器组合器

发布时间:2020-12-16 09:23:40 所属栏目:安全 来源:网络整理
导读:给出一系列实现解析器组合器的对象,我如何组合解析器?由于 Parsers.Parser 是一个内部课,而在Scala inner classes are bound to the outer object 中,这个故事变得稍微复杂一些. 这是一个尝试组合来自不同对象的两个解析器的示例. import scala.util.parsin
给出一系列实现解析器组合器的对象,我如何组合解析器?由于 Parsers.Parser是一个内部课,而在Scala inner classes are bound to the outer object中,这个故事变得稍微复杂一些.

这是一个尝试组合来自不同对象的两个解析器的示例.

import scala.util.parsing.combinator._

class BinaryParser extends JavaTokenParsers {
  def anyrep: Parser[Any] = rep(any)
  def any: Parser[Any] = zero | one
  def zero: Parser[Any] = "0"
  def one: Parser[Any] = "1"
}

object LongChainParser extends BinaryParser {
  def parser1: Parser[Any] = zero~zero~one~one
}

object ShortChainParser extends BinaryParser {
  def parser2: Parser[Any] = zero~zero
}

object ExampleParser extends BinaryParser {
  def parser: Parser[Any] = (LongChainParser.parser1
    ||| ShortChainParser.parser2) ~ anyrep

  def main(args: Array[String]) {
    println(parseAll(parser,args(0) ))
  }
}

这导致以下错误:

<console>:11: error: type mismatch;
 found   : ShortChainParser.Parser[Any]
 required: LongChainParser.Parser[?]
         def parser: Parser[Any] = (LongChainParser.parser1 
           ||| ShortChainParser.parser2) ~ anyrep

我已经找到了解决这个问题的方法,但是由于它已经被提出来了
最近在scala-user ML(Problem injecting one parser into another)上,也许值得把它放在这里.

解决方法

快速的答案是使用特征,而不是在对象中托管解析器:

import scala.util.parsing.combinator._

trait BinaryParser extends JavaTokenParsers {
  def anyrep: Parser[Any] = rep(any)
  def any: Parser[Any] = zero | one
  def zero: Parser[Any] = "0"
  def one: Parser[Any] = "1"
}

trait LongChainParser extends BinaryParser {
  def parser1: Parser[Any] = zero~zero~one~one
}

trait ShortChainParser extends BinaryParser {
  def parser2: Parser[Any] = zero~zero
}

object ExampleParser extends LongChainParser with ShortChainParser  {
  def parser: Parser[Any] = (parser1 ||| parser2) ~ anyrep

  def main(args: Array[String]) {
    println(parseAll(parser,args(0) ))
  }
}

因为组合运算符喜欢?和|被写入内部类,通过说BinaryParser#Parser [_]不会让你做任何改善,将解析器引用升级到类级别.使用traits可以解决所有这些内部问题,因为LongChainParser和ShortChainParser中的Parser [Any]都是引用ExampleParser对象的内部类.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读