218 /* nested comments */ |
218 /* nested comments */ |
219 |
219 |
220 def comment: Parser[String] = new Parser[String] |
220 def comment: Parser[String] = new Parser[String] |
221 { |
221 { |
222 val comment_text = |
222 val comment_text = |
223 rep(many1(sym => sym != "*" && sym != "(") | """\*(?!\))|\((?!\*)""".r) |
223 rep1(many1(sym => sym != "*" && sym != "(") | """\*(?!\))|\((?!\*)""".r) |
224 val comment_open = "(*" ~ comment_text ^^^ () |
|
225 val comment_close = comment_text ~ "*)" ^^^ () |
|
226 |
224 |
227 def apply(in: Input) = |
225 def apply(in: Input) = |
228 { |
226 { |
229 var rest = in |
227 var rest = in |
230 def try_parse(p: Parser[Unit]): Boolean = |
228 def try_parse[A](p: Parser[A]): Boolean = |
231 { |
229 { |
232 parse(p, rest) match { |
230 parse(p ^^^ (), rest) match { |
233 case Success(_, next) => { rest = next; true } |
231 case Success(_, next) => { rest = next; true } |
234 case _ => false |
232 case _ => false |
235 } |
233 } |
236 } |
234 } |
237 var depth = 0 |
235 var depth = 0 |
238 var finished = false |
236 var finished = false |
239 while (!finished) { |
237 while (!finished) { |
240 if (try_parse(comment_open)) depth += 1 |
238 if (try_parse("(*")) depth += 1 |
241 else if (depth > 0 && try_parse(comment_close)) depth -= 1 |
239 else if (depth > 0 && try_parse("*)")) depth -= 1 |
242 else finished = true |
240 else if (depth == 0 || !try_parse(comment_text)) finished = true |
243 } |
241 } |
244 if (in.offset < rest.offset && depth == 0) |
242 if (in.offset < rest.offset && depth == 0) |
245 Success(in.source.subSequence(in.offset, rest.offset).toString, rest) |
243 Success(in.source.subSequence(in.offset, rest.offset).toString, rest) |
246 else Failure("comment expected", in) |
244 else Failure("comment expected", in) |
247 } |
245 } |