Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
178 views
in Technique[技术] by (71.8m points)

scala - Parser combinator handling alternation with an optional parser

I have a parser p of type Parser[Option[X]] and another q of type Parser[Y]. (X and Y are concrete types but that's not important here).

I'd like to combine them in such a way that the resulting parser returns a Parser[Either[X, Y]]. This parser will succeed with Left(x) if p yields Some(x) or, failing that, it will succeed with Right(y) if q yields a y. Otherwise, it will fail. Input will be consumed in the successful cases but not in the unsuccessful case.

I'd appreciate any help with this as I can't quite figure out how to make it work.

question from:https://stackoverflow.com/questions/65930980/parser-combinator-handling-alternation-with-an-optional-parser

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

A little more perseverance after taking a break and I was able to solve this. I don't think my solution is the most elegant and would appreciate feedback:

def compose[X, Y](p: Parser[Option[X]], q: Parser[Y]): Parser[Either[X, Y]] = Parser {
  in =>
    p(in) match {
      case [email protected](Some(_), _) => s map (xo => Left(xo.get))
      case _ => q(in) match {
        case [email protected](_, _) => s map (x => Right(x))
        case _ => this.Failure("combine: failed", in)
      }
    }
}

implicit class ParserOps[X](p: Parser[Option[X]]) {
  def ?|[Y](q: => Parser[Y]): Parser[Either[X, Y]] = compose(p, q)
}

// Example of usage
def anadicTerm: Parser[AnadicTerm] = (maybeNumber ?| anadicOperator) ^^ {
  case Left(x: Number) => debug("anadicTerm (Number)", AnadicTerm(Right(x)))
  case Right(x: String) => debug("anadicTerm (String)", AnadicTerm(Left(x)))
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...