progs/parser-combinators/comb2.sc
changeset 971 b7d97a2a083b
parent 970 e15be5466802
child 972 1544a674dd35
equal deleted inserted replaced
970:e15be5466802 971:b7d97a2a083b
    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] {