Scala解析器-消息长度

| 我正在玩Scala的解析器库。我正在尝试编写一种解析器,用于指定长度的格式,然后是该长度的消息。例如:
x.parseAll(x.message, \"5helloworld\") // result: \"hello\", remaining: \"world\"
我不确定如何使用组合器执行此操作。我首先想到的是:
def message = length ~ body
但是很明显,身体取决于长度,我不知道该怎么做:p 相反,您可以只将消息解析器定义为单个解析器(而不是解析器的组合),并且我认为这是可行的(尽管我没有考虑单个解析器是否可以提取多个元素?)。 无论如何,我是scala菜鸟,我发现它很棒:)     
已邀请:
        为此,应使用
into
或其缩写
>>
scala> object T extends RegexParsers {
     |   def length: Parser[String] = \"\"\"\\d+\"\"\".r
     |   def message: Parser[String] = length >> { length => \"\"\"\\w{%d}\"\"\".format(length.toInt).r }
     | }
defined module T

scala> T.parseAll(T.message, \"5helloworld\")
res0: T.ParseResult[String] =
[1.7] failure: string matching regex `\\z\' expected but `w\' found

5helloworld
      ^

scala> T.parse(T.message, \"5helloworld\")
res1: T.ParseResult[String] = [1.7] parsed: hello
使用时请小心优先。例如,如果在上面的函数之后添加\“〜余数\”,Scala会将其解释为
length >> ({ length => ...} ~ remainder)
而不是
(length >> { length => ...}) ~ remainder
。     
        这听起来不像上下文无关的语言,所以您将需要使用flatMap:
def message = length.flatMap(l => bodyOfLength(n))
其中length为Parser [Int]类型,而bodyOfLength(n)类型则基于repN,例如
def bodyWithLength(n: Int) : Parser[String] 
  = repN(n, elem(\"any\", _ => true)) ^^ {_.mkString}
    
        我不会为此目的使用pasrer组合器。但是,如果必须这样做,或者问题变得更加复杂,则可以尝试以下操作:
def times(x :Long,what:String) : Parser[Any] = x match {
case 1 => what;
case x => what~times(x-1,what);
}
如果要保留某些内容,请不要使用parseAll,请使用parse。 您可以解析长度,将结果存储在一个可变字段x中(我知道这很丑,但在这里很有用),然后对正文进行x次解析,然后对String进行解析,其余的保留在解析器中。     

要回复问题请先登录注册