progs/parser-combinators/comb2.sc
changeset 972 ebb4a40d9bae
parent 971 51e00f223792
child 973 f25d338d16c9
equal deleted inserted replaced
971:51e00f223792 972:ebb4a40d9bae
    15 // case x ~ y ~ z => ...
    15 // case x ~ y ~ z => ...
    16 
    16 
    17 case class ~[+A, +B](x: A, y: B)
    17 case class ~[+A, +B](x: A, y: B)
    18 
    18 
    19 
    19 
       
    20 trait IsSeq[I] {
       
    21   extension (i: I) def isEmpty: Boolean
       
    22 }
       
    23 
       
    24 given IsSeq[String] = _.isEmpty
       
    25 given [I]: IsSeq[Seq[I]] = _.isEmpty
       
    26 
       
    27 
    20 // parser combinators
    28 // parser combinators
    21 abstract class Parser[I, T] { p =>
    29 abstract class Parser[I : IsSeq, T] { p =>
    22   def parse(in: I): Set[(T, I)]  
    30   def parse(in: I): Set[(T, I)]  
    23 
    31 
    24   def parse_all(in: I)(using toSeq: I => Seq[?]) : Set[T] =
    32   def parse_all(in: I) : Set[T] =
    25     for ((hd, tl) <- parse(in); 
    33     for ((hd, tl) <- parse(in); 
    26         if toSeq(tl).isEmpty) yield hd
    34         if tl.isEmpty) yield hd
    27 
    35 
    28   // alternative parser
    36   // alternative parser
    29   def ||(q: => Parser[I, T]) = new Parser[I, T] {
    37   def ||(q: => Parser[I, T]) : Parser[I, T] = Parser[I, T] {
    30     def parse(in: I) = p.parse(in) ++ q.parse(in)
    38     def parse(in: I) = p.parse(in) ++ q.parse(in)
    31   }
    39   }
    32 
    40 
    33   // sequence parser
    41   // sequence parser
    34   def ~[S](q: => Parser[I, S]) = new Parser[I, T ~ S] {
    42   def ~[S](q: => Parser[I, S]) = new Parser[I, T ~ S] {