48 case class CharParser(c: Char) extends Parser[String, Char] { | 
    48 case class CharParser(c: Char) extends Parser[String, Char] { | 
    49   def parse(in: String) =   | 
    49   def parse(in: String) =   | 
    50     if (in != "" && in.head == c) Set((c, in.tail)) else Set()  | 
    50     if (in != "" && in.head == c) Set((c, in.tail)) else Set()  | 
    51 }  | 
    51 }  | 
    52   | 
    52   | 
         | 
    53 CharParser('c').parse("abc") | 
    53   | 
    54   | 
    54 // an atomic parser for parsing strings according to a regex  | 
    55 // an atomic parser for parsing strings according to a regex  | 
    55 import scala.util.matching.Regex  | 
    56 import scala.util.matching.Regex  | 
    56   | 
    57   | 
    57 case class RegexParser(reg: Regex) extends Parser[String, String] { | 
    58 case class RegexParser(reg: Regex) extends Parser[String, String] { | 
    63   | 
    64   | 
    64 // atomic parsers for numbers and "verbatim" strings   | 
    65 // atomic parsers for numbers and "verbatim" strings   | 
    65 val NumParser = RegexParser("[0-9]+".r) | 
    66 val NumParser = RegexParser("[0-9]+".r) | 
    66 def StrParser(s: String) = RegexParser(Regex.quote(s).r)  | 
    67 def StrParser(s: String) = RegexParser(Regex.quote(s).r)  | 
    67   | 
    68   | 
         | 
    69 NumParser.parse("a123a123bc")  | 
         | 
    70 StrParser("else").parse("eelsethen") | 
    68   | 
    71   | 
    69   | 
    72   | 
    70 // NumParserInt transforms a "string integer" into a propper Int  | 
    73 // NumParserInt transforms a "string integer" into a propper Int  | 
    71 // (needs "new" because MapParser is not a case class)  | 
    74 // (needs "new" because MapParser is not a case class)  | 
    72   | 
    75   | 
    73 val NumParserInt = new MapParser(NumParser, (s: String) => s.toInt)  | 
    76 val NumParserInt = new MapParser(NumParser, (s: String) => s.toInt)  | 
    74   | 
    77 NumParserInt.parse("123abc") | 
    75   | 
    78   | 
    76 // the following string interpolation allows us to write   | 
    79 // the following string interpolation allows us to write   | 
    77 // StrParser(_some_string_) more conveniently as   | 
    80 // StrParser(_some_string_) more conveniently as   | 
    78 //  | 
    81 //  | 
    79 // p"<_some_string_>"   | 
    82 // p"<_some_string_>"   | 
    80   | 
    83   | 
         | 
    84   | 
    81 implicit def parser_interpolation(sc: StringContext) = new { | 
    85 implicit def parser_interpolation(sc: StringContext) = new { | 
    82   def p(args: Any*) = StrParser(sc.s(args:_*))  | 
    86   def p(args: Any*) = StrParser(sc.s(args:_*))  | 
    83 }  | 
    87 }  | 
    84              | 
    88   | 
         | 
    89 (p"else").parse("elsethen")            | 
    85   | 
    90   | 
    86 // more convenient syntax for parser combinators  | 
    91 // more convenient syntax for parser combinators  | 
    87 implicit def ParserOps[I : IsSeq, T](p: Parser[I, T]) = new { | 
    92 implicit def ParserOps[I : IsSeq, T](p: Parser[I, T]) = new { | 
    88   def ||(q : => Parser[I, T]) = new AltParser[I, T](p, q)  | 
    93   def ||(q : => Parser[I, T]) = new AltParser[I, T](p, q)  | 
    89   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)  | 
    90   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)  | 
    91 }  | 
    96 }  | 
    92   | 
    97   | 
         | 
    98 def toU(s: String) = s.map(_.toUpper)  | 
         | 
    99   | 
         | 
   100 (p"ELSE").map(toU(_)).parse("ELSEifthen")   | 
         | 
   101   | 
    93 // these implicits allow us to use an infix notation for  | 
   102 // these implicits allow us to use an infix notation for  | 
    94 // sequences and alternatives; we also can write the usual  | 
   103 // sequences and alternatives; we also can write the usual  | 
    95 // map for a MapParser  | 
   104 // map for a MapParser  | 
    96   | 
   105   | 
    97   | 
   106   | 
    99 // as:  | 
   108 // as:  | 
   100   | 
   109   | 
   101 val NumParserInt2 = NumParser.map(_.toInt)  | 
   110 val NumParserInt2 = NumParser.map(_.toInt)  | 
   102   | 
   111   | 
   103   | 
   112   | 
         | 
   113   | 
         | 
   114   | 
   104 // A parser for palindromes (just returns them as string)  | 
   115 // A parser for palindromes (just returns them as string)  | 
   105 lazy val Pal : Parser[String, String] = { | 
   116 lazy val Pal : Parser[String, String] = { | 
   106   ((p"a" ~ Pal) ~ p"a").map{ case ((x, y), z) => s"$x$y$z" } ||  | 
   117    (p"a" ~ Pal ~ p"a").map{ case ((x, y), z) => s"$x$y$z" } ||  | 
   107    (p"b" ~ Pal ~ p"b").map{ case ((x, y), z) => s"$x$y$z" } ||  | 
   118    (p"b" ~ Pal ~ p"b").map{ case ((x, y), z) => s"$x$y$z" } ||  | 
   108     p"a" || p"b" || p""  | 
   119     p"a" || p"b" || p""  | 
   109 }    | 
   120 }    | 
   110   | 
   121   | 
   111 // examples  | 
   122 // examples  | 
   128 println(P.parse_all("(((()()))()))")) | 
   139 println(P.parse_all("(((()()))()))")) | 
   129 println(P.parse_all(")(")) | 
   140 println(P.parse_all(")(")) | 
   130 println(P.parse_all("()")) | 
   141 println(P.parse_all("()")) | 
   131   | 
   142   | 
   132 // A parser for arithmetic expressions (Terms and Factors)  | 
   143 // A parser for arithmetic expressions (Terms and Factors)  | 
   133   | 
   144 { | 
   134 lazy val E: Parser[String, Int] = { | 
   145 lazy val E: Parser[String, Int] = { | 
   135   (T ~ p"+" ~ E).map{ case ((x, _), z) => x + z } || | 
   146   (T ~ p"+" ~ E).map{ case ((x, _), z) => x + z } || | 
   136   (T ~ p"-" ~ E).map{ case ((x, _), z) => x - z } || T } | 
   147   (T ~ p"-" ~ E).map{ case ((x, _), z) => x - z } || T } | 
   137 lazy val T: Parser[String, Int] = { | 
   148 lazy val T: Parser[String, Int] = { | 
   138   (F ~ p"*" ~ T).map{ case ((x, _), z) => x * z } || F } | 
   149   (F ~ p"*" ~ T).map{ case ((x, _), z) => x * z } || F } | 
   139 lazy val F: Parser[String, Int] = { | 
   150 lazy val F: Parser[String, Int] = { | 
   140   (p"(" ~ E ~ p")").map{ case ((_, y), _) => y } || NumParserInt } | 
   151   (p"(" ~ E ~ p")").map{ case ((_, y), _) => y } || NumParserInt } | 
   141   | 
   152 }  | 
   142 println(E.parse_all("1+3+4")) | 
   153 println(E.parse_all("1+3+4")) | 
   143 println(E.parse("1+3+4")) | 
   154 println(E.parse("1+3+4")) | 
   144 println(E.parse_all("4*2+3")) | 
   155 println(E.parse_all("4*2+3")) | 
   145 println(E.parse_all("4*(2+3)")) | 
   156 println(E.parse_all("4*(2+3)")) | 
   146 println(E.parse_all("(4)*((2+3))")) | 
   157 println(E.parse_all("(4)*((2+3))")) |