English 中文(简体)
将编织者名单/数目改为单一
原标题:Turning a list/sequence of combinator parsers into a single one

我有一份价值观清单,我可以从中拟定一份按这些价值观绘制的教区名单(见例子)。 然后,我想要做的是,把教区名单变成一个单一的教区。

一种可能性是使用<条码>、和<条码>。

parsers.foldLeft(success(Nil)){case (ps,p) => rs ~ p ^^ {case xs ~ x => x ::xs}} ^^ (_.reverse)

Is this efficient?

I don t know how combinator parsers work; will there be a call stack with depth of length of the list? Thus may I run into SO errors for very long concatenations?

Better way

是否有可读性的不同方法?

Example

附录一 第1行含有N integers x_1 to x_n。 第二行含有x_1 + x_2 + ×_n integers,根据第一行属于群体。 我想从第一行顺序排列的分类顺序,并创建一端 par,p.1至p_n,p_i parses x_i integers。

附录一载有第一行的分类账清单l = 清单(1,2,3)。 每一英寸<条码> 我创设了一个教区:n integers:parsers = l.map(repN(_,integer))

最佳回答

What you re describing (and what you ve more or less reinvented in your implementation with foldLeft and ~) is essentially Haskell s sequence for monads (really you only need an applicative functor, but that s irrelevant here). sequence takes a list of monadic values and returns a monadic list of values. Parser is a monad, so sequence for Parser would change a List[Parser[A]] into a Parser[List[A]].

Scalaz gives you sequence, but off the top of my head I don t know if there s a nice way to get the necessary Applicative instance for Parser. Fortunately you can roll your own pretty easily (I m directly translating the Haskell definition):

import scala.util.parsing.combinator._

object parser extends RegexParsers {
  val integer = """d+""".r

  val counts = List(1, 2, 3)
  val parsers = counts.map(repN(_, integer))

  val line = parsers.foldRight(success(Nil: List[List[String]])) {
    (m, n) => for { x <- m ; xs <- n } yield (x :: xs)
  }

  def apply(s: String) = parseAll(line, s)
}

这使我们想到List(List(1), List(2,3), List(4,5, 6),parser(”1 2 3 4 5 6”)

(说明:使用<代码>的Im 这里是一个方便的完整的例子,但这一办法一般运作。

如果我们取消<<<><>>><>条码/代码>,那么今后将会出现什么更为清楚。 理解:

val line = parsers.foldRight(success(Nil: List[List[String]])) {
  (current, acc) => current.flatMap(x => acc.map(x :: _))
}

我们可以将<条码>flatMap作为<条码>、<条码>和<条码>作为<条码>。

val line = parsers.foldRight(success(Nil: List[List[String]])) {
  (current, acc) => current into (x => acc ^^ (x :: _))
}

This isn t too far from your formulation, except that we re using a right fold instead of reversing and aren t building up and breaking down the ~s.


提高效率: 我们的这两项执行工作都将造成无休止的警钟。 在我的经验中,这只是一个与Schala族长结合的生活事实。 To quote ,例如:

Scala s parser combinators aren t very efficient. They weren t designed to be. They re good for doing small tasks with relatively small inputs.

我的<代码>squence-y办法述及贵问题中的“可读”部分,而且几乎肯定是解决与S Scala族长结合者问题的最佳途径。 这比你的执行效率低一些,应该对几千个团体处以罚款。 如果你需要处理多于这种情况,就必须在<条码>scala.util.parsing.combinator之外检查。 我建议:

def parse(counts: Seq[Int], input: String): Option[Seq[Seq[Int]]] = {
  val parsed = try {
    Some(input.split(" ").map(_.toInt))
  } catch {
    case _ : java.lang.NumberFormatException => None
  }

  parsed.flatMap { ints =>
    if (ints.length != counts.sum) None
    else Some(counts.foldLeft((Seq.empty[Seq[Int]], ints)) {
      case ((collected, remaining), count) => {
        val (m, n) = remaining.splitAt(count)
        (m.toSeq +: collected, n)
      }
    }._1.reverse)
  }
}

没有任何保障,但在我的制度上,它向100k英寸的集团倾斜。


问题回答

Have you considered using a RegexParsers (in scala.util.parsing.combinator)? Then you can use regular expressions as parsers, which will compute very fast and be easy to write.

例如,如果你使用子午线器将AST用于简单的算术,那么你可以使用定期的表述来解释提及物体的标语,这样你就可以将诸如<条码>pple形形码>size + 4等表述加以区别。

Here is a rather trivial example, but it shows how regular expressions can be combined by parser combinators.

object MyParser extends RegexParsers {
  val regex1 = """[abc]*""".r
  val regex2 = """[def]*""".r
  val parse = regex1 ~ regex2

  def apply(s: String) = parseAll(parse, s)
}




相关问题
How to flatten a List of different types in Scala?

I have 4 elements:List[List[Object]] (Objects are different in each element) that I want to zip so that I can have a List[List[obj1],List[obj2],List[obj3],List[obj4]] I tried to zip them and I ...

To use or not to use Scala for new Java projects? [closed]

I m impressed with Twitter and investigating to use Scala for a new large scale web project with Hibernate and Wicket. What do you think about Scala, and should I use it instead of Java? EDIT: And, ...

Why does Scala create a ~/tmp directory when I run a script?

When I execute a Scala script from the command line, a directory named "tmp" is created in my home directory. It is always empty, so I simply deleted it without any apparent problem. Of course, when I ...

Include jar file in Scala interpreter

Is it possible to include a jar file run running the Scala interpreter? My code is working when I compile from scalac: scalac script.scala -classpath *.jar But I would like to be able to include a ...

Scala and tail recursion

There are various answers on Stack Overflow which explain the conditions under which tail recursion is possible in Scala. I understand the limitations and how and where I can take advantage of tail ...

热门标签