progs/parser-combinators/comb1.sc
changeset 948 6bb67c2dcfd3
parent 941 66adcae6c762
child 954 eda0ccf56c72
equal deleted inserted replaced
947:dc31a099dc98 948:6bb67c2dcfd3
    19     for ((hd, tl) <- parse(in); 
    19     for ((hd, tl) <- parse(in); 
    20         if is(tl).isEmpty) yield hd
    20         if is(tl).isEmpty) yield hd
    21 }
    21 }
    22 
    22 
    23 // parser combinators
    23 // parser combinators
    24 
       
    25 
    24 
    26 
    25 
    27 // alternative parser
    26 // alternative parser
    28 class AltParser[I : IsSeq, T](p: => Parser[I, T], 
    27 class AltParser[I : IsSeq, T](p: => Parser[I, T], 
    29                               q: => Parser[I, T]) extends Parser[I, T] {
    28                               q: => Parser[I, T]) extends Parser[I, T] {
    94   def ||(q : => Parser[I, T]) = new AltParser[I, T](p, q)
    93   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)
    94   def ~[S] (q : => Parser[I, S]) = new SeqParser[I, T, S](p, q)
    96   def map[S](f: => T => S) = new MapParser[I, T, S](p, f)
    95   def map[S](f: => T => S) = new MapParser[I, T, S](p, f)
    97 }
    96 }
    98 
    97 
       
    98 // simple example of transforming the 
       
    99 // result into capital letters
    99 def toU(s: String) = s.map(_.toUpper)
   100 def toU(s: String) = s.map(_.toUpper)
   100 
   101 
   101 (p"ELSE").map(toU(_)).parse("ELSEifthen")  
   102 (p"else").map(toU(_)).parse("elseifthen")  
   102 
   103 
   103 // these implicits allow us to use an infix notation for
   104 // these implicits allow us to use an infix notation for
   104 // sequences and alternatives; we also can write the usual
   105 // sequences and alternatives; we also can write the usual
   105 // map for a MapParser
   106 // map for a MapParser
   106 
   107 
   110 
   111 
   111 val NumParserInt2 = NumParser.map(_.toInt)
   112 val NumParserInt2 = NumParser.map(_.toInt)
   112 
   113 
   113 
   114 
   114 // A parser for palindromes (just returns them as string)
   115 // A parser for palindromes (just returns them as string)
       
   116 //  since the parser is recursive it needs to be lazy
   115 lazy val Pal : Parser[String, String] = {
   117 lazy val Pal : Parser[String, String] = {
   116    (p"a" ~ Pal ~ p"a").map{ case ((x, y), z) => s"$x$y$z" } || 
   118    (p"a" ~ Pal ~ p"a").map{ case ((x, y), z) => s"$x$y$z" } || 
   117    (p"b" ~ Pal ~ p"b").map{ case ((x, y), z) => s"$x$y$z" } || 
   119    (p"b" ~ Pal ~ p"b").map{ case ((x, y), z) => s"$x$y$z" } || 
   118     p"a" || p"b" || p""
   120     p"a" || p"b" || p""
   119 }  
   121 }