|     16  |     16  | 
|     17  |     17  | 
|     18  |     18  | 
|     19 case class ~[+A, +B](x: A, y: B) |     19 case class ~[+A, +B](x: A, y: B) | 
|     20  |     20  | 
|         |     21 type IsSeq[I] = I => Seq[_] | 
|         |     22  | 
|     21 abstract class Parser[I, T](using is: I => Seq[_])  { |     23 abstract class Parser[I, T](using is: I => Seq[_])  { | 
|     22   def parse(in: I): Set[(T, I)]   |     24   def parse(in: I): Set[(T, I)]   | 
|     23  |     25  | 
|     24   def parse_all(in: I) : Set[T] = |     26   def parse_all(in: I) : Set[T] = | 
|     25     for ((hd, tl) <- parse(in);  |     27     for ((hd, tl) <- parse(in);  | 
|     27 } |     29 } | 
|     28  |     30  | 
|     29 // parser combinators |     31 // parser combinators | 
|     30  |     32  | 
|     31 // alternative parser |     33 // alternative parser | 
|     32 class AltParser[I, T](p: => Parser[I, T],  |     34 class AltParser[I : IsSeq, T](p: => Parser[I, T],  | 
|     33                       q: => Parser[I, T])(using I => Seq[_]) extends Parser[I, T] { |     35                               q: => Parser[I, T]) extends Parser[I, T] { | 
|     34   def parse(in: I) = p.parse(in) ++ q.parse(in)    |     36   def parse(in: I) = p.parse(in) ++ q.parse(in)    | 
|     35 } |     37 } | 
|     36  |     38  | 
|     37 // sequence parser |     39 // sequence parser | 
|     38 class SeqParser[I, T, S](p: => Parser[I, T],  |     40 class SeqParser[I : IsSeq, T, S](p: => Parser[I, T],  | 
|     39                          q: => Parser[I, S])(using I => Seq[_]) extends Parser[I, ~[T, S]] { |     41                                  q: => Parser[I, S]) extends Parser[I, ~[T, S]] { | 
|     40   def parse(in: I) =  |     42   def parse(in: I) =  | 
|     41     for ((hd1, tl1) <- p.parse(in);  |     43     for ((hd1, tl1) <- p.parse(in);  | 
|     42          (hd2, tl2) <- q.parse(tl1)) yield (new ~(hd1, hd2), tl2) |     44          (hd2, tl2) <- q.parse(tl1)) yield (new ~(hd1, hd2), tl2) | 
|     43 } |     45 } | 
|     44  |     46  | 
|     45 // map parser |     47 // map parser | 
|     46 class maparser[I, T, S](p: => Parser[I, T],  |     48 class maparser[I : IsSeq, T, S](p: => Parser[I, T],  | 
|     47                          f: T => S)(using I => Seq[_]) extends Parser[I, S] { |     49                                 f: T => S) extends Parser[I, S] { | 
|     48   def parse(in: I) = for ((hd, tl) <- p.parse(in)) yield (f(hd), tl) |     50   def parse(in: I) = for ((hd, tl) <- p.parse(in)) yield (f(hd), tl) | 
|     49 } |     51 } | 
|     50  |     52  | 
|     51  |     53  | 
|     52  |     54  | 
|     88 extension (sc: StringContext)  |     90 extension (sc: StringContext)  | 
|     89   def p(args: Any*) = StrParser(sc.s(args:_*)) |     91   def p(args: Any*) = StrParser(sc.s(args:_*)) | 
|     90  |     92  | 
|     91  |     93  | 
|     92 // more convenient syntax for parser combinators |     94 // more convenient syntax for parser combinators | 
|     93 extension [I, T](p: Parser[I, T])(using I => Seq[_]) { |     95 extension [I : IsSeq, T](p: Parser[I, T]) { | 
|     94   def ||(q : => Parser[I, T]) = new AltParser[I, T](p, q) |     96   def ||(q : => Parser[I, T]) = new AltParser[I, T](p, q) | 
|     95   def ~[S] (q : => Parser[I, S]) = new SeqParser[I, T, S](p, q) |     97   def ~[S] (q : => Parser[I, S]) = new SeqParser[I, T, S](p, q) | 
|     96   def map[S](f: => T => S) = new maparser[I, T, S](p, f) |     98   def map[S](f: => T => S) = new maparser[I, T, S](p, f) | 
|     97 } |     99 } | 
|     98  |    100  |