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] { |