progs/comb1.scala
changeset 462 fb5e1ef58049
parent 461 890188804fb4
child 467 b5ec11e89768
equal deleted inserted replaced
461:890188804fb4 462:fb5e1ef58049
    32 }
    32 }
    33 
    33 
    34 // atomic parsers  
    34 // atomic parsers  
    35 case class CharParser(c: Char) extends Parser[String, Char] {
    35 case class CharParser(c: Char) extends Parser[String, Char] {
    36   def parse(sb: String) = 
    36   def parse(sb: String) = 
    37     if (sb.head == c) Set((c, sb.tail)) else Set()
    37     if (sb != "" && sb.head == c) Set((c, sb.tail)) else Set()
    38 }
    38 }
    39 
    39 
    40 case class StringParser(s: String) extends Parser[String, String] {
    40 case class StringParser(s: String) extends Parser[String, String] {
    41   def parse(sb: String) = {
    41   def parse(sb: String) = {
    42     val (prefix, suffix) = sb.splitAt(s.length)
    42     val (prefix, suffix) = sb.splitAt(s.length)
    53     }) 
    53     }) 
    54   }
    54   }
    55 }
    55 }
    56 
    56 
    57 // convenience
    57 // convenience
    58 implicit def string2parser(s : String) = StringParser(s)
    58 implicit def string2parser(s: String) = StringParser(s)
       
    59 implicit def char2parser(c: Char) = CharParser(c)
    59 
    60 
    60 implicit def ParserOps[I<% Seq[_], T](p: Parser[I, T]) = new {
    61 implicit def ParserOps[I<% Seq[_], T](p: Parser[I, T]) = new {
    61   def || (q : => Parser[I, T]) = new AltParser[I, T](p, q)
    62   def || (q : => Parser[I, T]) = new AltParser[I, T](p, q)
    62   def ==>[S] (f: => T => S) = new FunParser[I, T, S](p, f)
    63   def ==>[S] (f: => T => S) = new FunParser[I, T, S](p, f)
    63   def ~[S] (q : => Parser[I, S]) = new SeqParser[I, T, S](p, q)
    64   def ~[S] (q : => Parser[I, S]) = new SeqParser[I, T, S](p, q)
    76 // a parse palindromes
    77 // a parse palindromes
    77 lazy val Pal : Parser[String, String] = 
    78 lazy val Pal : Parser[String, String] = 
    78   (("a" ~ Pal ~ "a") ==> { case ((x, y), z) => x + y + z } ||
    79   (("a" ~ Pal ~ "a") ==> { case ((x, y), z) => x + y + z } ||
    79    ("b" ~ Pal ~ "b") ==> { case ((x, y), z) => x + y + z } || "")
    80    ("b" ~ Pal ~ "b") ==> { case ((x, y), z) => x + y + z } || "")
    80 
    81 
    81 println("Palindrom: " + Pal.parse_all("ababbaba"))
    82 println("Palindrome: " + Pal.parse_all("ababbaba"))
    82 
    83 
    83 // well-nested parenthesis parser
    84 // well-nested parenthesis parser
    84 lazy val P : Parser[String, String] = 
    85 lazy val P : Parser[String, String] = 
    85   "(" ~ P ~ ")" ~ P ==> { case (((u, x), y), z) => "{" + x + "}" + z } || ""
    86   "(" ~ P ~ ")" ~ P ==> { case (((u, x), y), z) => "{" + x + "}" + z } || ""
    86 
    87 
   101 println(E.parse("1*2+3"))
   102 println(E.parse("1*2+3"))
   102 println(E.parse("1 + 2 * 3"))
   103 println(E.parse("1 + 2 * 3"))
   103 println(E.parse_all("(1+2)+3"))
   104 println(E.parse_all("(1+2)+3"))
   104 println(E.parse_all("1+2+3"))  // this is not parsed, because of 
   105 println(E.parse_all("1+2+3"))  // this is not parsed, because of 
   105                                // how the grammar is set up
   106                                // how the grammar is set up
       
   107 
       
   108 // a repetition parser
       
   109 
       
   110 def RepParser[I  <% Seq[_], T](p: => Parser[I, T]): Parser[I, List[T]] = {
       
   111   p ==> { case x => x :: Nil } ||
       
   112   p ~ RepParser(p) ==> { case (x, y) => x :: y }   
       
   113 }
       
   114 
       
   115 
       
   116 // a repetition parser
       
   117 lazy val R : Parser[String, List[Char]] = RepParser('a') 
       
   118 println(R.parse_all("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"))
       
   119 
       
   120 
   106 
   121 
   107 // non-ambiguous vs ambiguous grammars
   122 // non-ambiguous vs ambiguous grammars
   108 lazy val S : Parser[String, String] =
   123 lazy val S : Parser[String, String] =
   109   ("1" ~ S ~ S) ==> { case ((x, y), z) => x + y + z } || ""
   124   ("1" ~ S ~ S) ==> { case ((x, y), z) => x + y + z } || ""
   110 
   125