8    | 
     8    | 
     9 //  Note, in the lectures I did not show the type bound  | 
     9 //  Note, in the lectures I did not show the type bound  | 
    10 //  using is: I => Seq[_], which means that the input   | 
    10 //  using is: I => Seq[_], which means that the input   | 
    11 //  type 'I' needs to be a sequence.   | 
    11 //  type 'I' needs to be a sequence.   | 
    12   | 
    12   | 
    13 abstract class Parser[I, T](using is: I => Seq[_])  { | 
    13 type IsSeq[I] = I => Seq[_]  | 
         | 
    14   | 
         | 
    15 abstract class Parser[I, T](using is: IsSeq[I])  { | 
    14   def parse(in: I): Set[(T, I)]    | 
    16   def parse(in: I): Set[(T, I)]    | 
    15   | 
    17   | 
    16   def parse_all(in: I) : Set[T] =  | 
    18   def parse_all(in: I) : Set[T] =  | 
    17     for ((hd, tl) <- parse(in);   | 
    19     for ((hd, tl) <- parse(in);   | 
    18         if is(tl).isEmpty) yield hd  | 
    20         if is(tl).isEmpty) yield hd  | 
    19 }  | 
    21 }  | 
    20   | 
    22   | 
    21 // parser combinators  | 
    23 // parser combinators  | 
    22   | 
    24   | 
         | 
    25   | 
         | 
    26   | 
    23 // alternative parser  | 
    27 // alternative parser  | 
    24 class AltParser[I, T](p: => Parser[I, T],   | 
    28 class AltParser[I : IsSeq, T](p: => Parser[I, T],   | 
    25                       q: => Parser[I, T])(using I => Seq[_]) extends Parser[I, T] { | 
    29                               q: => Parser[I, T]) extends Parser[I, T] { | 
    26   def parse(in: I) = p.parse(in) ++ q.parse(in)     | 
    30   def parse(in: I) = p.parse(in) ++ q.parse(in)     | 
    27 }  | 
    31 }  | 
    28   | 
    32   | 
    29 // sequence parser  | 
    33 // sequence parser  | 
    30 class SeqParser[I, T, S](p: => Parser[I, T],   | 
    34 class SeqParser[I: IsSeq, T, S](p: => Parser[I, T],   | 
    31                          q: => Parser[I, S])(using I => Seq[_]) extends Parser[I, (T, S)] { | 
    35                                 q: => Parser[I, S]) extends Parser[I, (T, S)] { | 
    32   def parse(in: I) =   | 
    36   def parse(in: I) =   | 
    33     for ((hd1, tl1) <- p.parse(in);   | 
    37     for ((hd1, tl1) <- p.parse(in);   | 
    34          (hd2, tl2) <- q.parse(tl1)) yield ((hd1, hd2), tl2)  | 
    38          (hd2, tl2) <- q.parse(tl1)) yield ((hd1, hd2), tl2)  | 
    35 }  | 
    39 }  | 
    36   | 
    40   | 
    37 // map parser  | 
    41 // map parser  | 
    38 class MapParser[I, T, S](p: => Parser[I, T],   | 
    42 class MapParser[I : IsSeq, T, S](p: => Parser[I, T],   | 
    39                          f: T => S)(using I => Seq[_]) extends Parser[I, S] { | 
    43                          f: T => S) extends Parser[I, S] { | 
    40   def parse(in: I) = for ((hd, tl) <- p.parse(in)) yield (f(hd), tl)  | 
    44   def parse(in: I) = for ((hd, tl) <- p.parse(in)) yield (f(hd), tl)  | 
    41 }  | 
    45 }  | 
    42   | 
    46   | 
    43   | 
    47   | 
    44   | 
    48   | 
    84   | 
    88   | 
    85   | 
    89   | 
    86 (p"else").parse("elsethen")            | 
    90 (p"else").parse("elsethen")            | 
    87   | 
    91   | 
    88 // more convenient syntax for parser combinators  | 
    92 // more convenient syntax for parser combinators  | 
    89 extension [I, T](p: Parser[I, T])(using I => Seq[_]) { | 
    93 extension [I: IsSeq, T](p: Parser[I, T]) { | 
    90   def ||(q : => Parser[I, T]) = new AltParser[I, T](p, q)  | 
    94   def ||(q : => Parser[I, T]) = new AltParser[I, T](p, q)  | 
    91   def ~[S] (q : => Parser[I, S]) = new SeqParser[I, T, S](p, q)  | 
    95   def ~[S] (q : => Parser[I, S]) = new SeqParser[I, T, S](p, q)  | 
    92   def map[S](f: => T => S) = new MapParser[I, T, S](p, f)  | 
    96   def map[S](f: => T => S) = new MapParser[I, T, S](p, f)  | 
    93 }  | 
    97 }  | 
    94   | 
    98   |