progs/comb1.scala
changeset 672 e0d76f7f0688
parent 667 412556272333
child 673 715b46eee102
equal deleted inserted replaced
671:83e38043ed78 672:e0d76f7f0688
    48 }
    48 }
    49 
    49 
    50 val NumParser = RegexParser("[0-9]+".r)
    50 val NumParser = RegexParser("[0-9]+".r)
    51 def StringParser(s: String) = RegexParser(Regex.quote(s).r)
    51 def StringParser(s: String) = RegexParser(Regex.quote(s).r)
    52 
    52 
    53 // NumParserInt2 transforms a "string integer" into an Int;
    53 // NumParserInt2 transforms a "string integer" into an actual Int;
    54 // needs new, because FunParser is not a case class
    54 // needs new, because FunParser is not a case class
    55 val NumParserInt2 = new FunParser(NumParser, (s: String) => s.toInt)
    55 val NumParserInt2 = new FunParser(NumParser, (s: String) => s.toInt)
    56 
    56 
    57 
    57 
    58 // convenience
    58 // convenience
    73     new SeqParser[String, String, S](s, q)
    73     new SeqParser[String, String, S](s, q)
    74   def ~ (r: String) = 
    74   def ~ (r: String) = 
    75     new SeqParser[String, String, String](s, r)
    75     new SeqParser[String, String, String](s, r)
    76 }
    76 }
    77 
    77 
    78 // NumParserInt can now be written as
    78 // NumParserInt can now be written as _ ===> _
       
    79 // the first part is the parser, and the second the 
       
    80 // semantic action
    79 val NumParserInt = NumParser ==> (s => s.toInt)
    81 val NumParserInt = NumParser ==> (s => s.toInt)
    80 
    82 
    81 
    83 
       
    84 // palindromes
    82 lazy val Pal : Parser[String, String] = 
    85 lazy val Pal : Parser[String, String] = 
    83   (("a" ~ Pal ~ "a") ==> { case ((x, y), z) => x + y + z } ||
    86   (("a" ~ Pal ~ "a") ==> { case ((x, y), z) => x + y + z } ||
    84    ("b" ~ Pal ~ "b") ==> { case ((x, y), z) => x + y + z } || "a" || "b" || "")
    87    ("b" ~ Pal ~ "b") ==> { case ((x, y), z) => x + y + z } || "a" || "b" || "")
    85 
    88 
    86 Pal.parse_all("abaaaba")
    89 Pal.parse_all("abaaaba")
    87 Pal.parse_all("abacba")
    90 Pal.parse_all("abacba")
    88 Pal.parse("abaaaba")
    91 Pal.parse("abaaaba")
    89 
    92 
    90 println("Palindrome: " + Pal.parse_all("abaaaba"))
    93 println("Palindrome: " + Pal.parse_all("abaaaba"))
    91 
    94 
    92 // well-nested parentheses parser (transforms '(' -> '{' , ')' -> '}' )
    95 // parser for well-nested parentheses (transforms '(' -> '{' , ')' -> '}' )
    93 lazy val P : Parser[String, String] = 
    96 lazy val P : Parser[String, String] = 
    94   "(" ~ P ~ ")" ~ P ==> { case (((_, x), _), y) => "{" + x + "}" + y } || ""
    97   "(" ~ P ~ ")" ~ P ==> { case (((_, x), _), y) => "{" + x + "}" + y } || ""
    95 
    98 
    96 P.parse_all("(((()()))())")
    99 P.parse_all("(((()()))())")
    97 P.parse_all("(((()()))()))")
   100 P.parse_all("(((()()))()))")
    98 P.parse_all(")(")
   101 P.parse_all(")(")
    99 P.parse_all("()")
   102 P.parse_all("()")
   100 
   103 
       
   104 // just counts parentheses
   101 lazy val PC : Parser[String, Int] = 
   105 lazy val PC : Parser[String, Int] = 
   102   ("(" ~ PC ~ ")" ~ PC ==> { case (((_, x), _), y) => x + y + 2 } || 
   106   ("(" ~ PC ~ ")" ~ PC ==> { case (((_, x), _), y) => x + y + 2 } || 
   103    "" ==> { (s) => 0 })
   107    "" ==> { (s) => 0 })
   104 
   108 
   105 PC.parse_all("(((()()))())")
   109 PC.parse_all("(((()()))())")
   106 P.parse_all("(((()()))()))")
   110 P.parse_all("(((()()))()))")
   107 
   111 
   108 // Arithmetic Expressions (Terms and Factors)
   112 // Arithmetic Expressions (Terms and Factors)
       
   113 // (because it is mutually recursive, you need :paste 
       
   114 //  for munching this definition in the REPL)
   109 
   115 
   110 lazy val E: Parser[String, Int] = 
   116 lazy val E: Parser[String, Int] = 
   111   (T ~ "+" ~ E) ==> { case ((x, y), z) => x + z } ||
   117   (T ~ "+" ~ E) ==> { case ((x, y), z) => x + z } ||
   112   (T ~ "-" ~ E) ==> { case ((x, y), z) => x - z } || T 
   118   (T ~ "-" ~ E) ==> { case ((x, y), z) => x - z } || T 
   113 lazy val T: Parser[String, Int] = 
   119 lazy val T: Parser[String, Int] = 
   191 (One || Two).parse("111")
   197 (One || Two).parse("111")
   192 
   198 
   193 
   199 
   194 
   200 
   195 
   201 
   196 
   202 // a problem with the arithmetic expression parser -> gets 
   197 // a problem with the parser -> gets slow with nestedness
   203 // slow with deep nestedness
   198 E.parse("1")
   204 E.parse("1")
   199 E.parse("(1)")
   205 E.parse("(1)")
   200 E.parse("((1))")
   206 E.parse("((1))")
   201 E.parse("(((1)))")
   207 E.parse("(((1)))")
   202 E.parse("((((1))))")
   208 E.parse("((((1))))")