2

With scala-parser-combinators, I want to try parse with postfix string(end). but previous parser cought end contents. how to fix it? (just changing "[^z]".r is not good answer.)

val input = "aaabbbzzz"
parseAll(body, input) // java.lang.IllegalStateException: `zzz' expected but end of source found

def body: Parser[List[String]] = content.+ <~ end
def content: Parser[String] = repChar // more complex like (repChar | foo | bar)
def repChar: Parser[String] = ".{3}".r // If change this like "[^z]{3}", but no flexibility.
def end: Parser[String] = "zzz"

I want to try like followings.

"""(.*)(?=zzz)""".r.into(str => ...check content.+ or not... <~ end)
  1. search strings until end string.
  2. then parse them with another parser.
krrrr38
  • 155
  • 2
  • 12
  • How about this? http://stackoverflow.com/questions/7812610/non-greedy-matching-in-scala-regexparsers – zakki Jul 15 '15 at 09:26
  • Using `noneGreedy`, the above case is enough thanks :) I just notice the bottom pattern in my question is written easily... `def pattern: Parser[String] = """(.*)(?=zzz)""".r ^^ { case text => parseAll(another, text) ...` – krrrr38 Jul 15 '15 at 12:02
  • @krrrr38: Please answer your own question with the two solutions that you've encountered, and accept it. – fresskoma Jul 15 '15 at 14:50

1 Answers1

0

Another way to fix this is to use the not combinator. You just need to check that what you are parsing is not the end value.

The trick is that not doesn't consume the input, so if not(end) succeeds (meaning that end failed) then we didn't reach the stopping condition so we can parse the three characters with the content parser that made the end parser failing.

As with the non-greedy approach linked in comments, it will fail for an input that has characters after "zzz" in the input (such as "aaabbbzzzzzz" for example).

But it may be sufficient for your use case. So you could give it a try with:

def body: Parser[List[String]] = rep(not(end) ~> content) <~ end

In fact this is a kind of takeUntil parser, because it parses with content repeatedly until you're able to parse with end.

Alexis C.
  • 91,686
  • 21
  • 171
  • 177