diff -r 0d309fafa9f0 -r bb24d4e207b6 progs/comb1.scala --- a/progs/comb1.scala Fri Oct 26 16:14:10 2018 +0100 +++ b/progs/comb1.scala Fri Oct 26 17:13:41 2018 +0100 @@ -38,7 +38,6 @@ } import scala.util.matching.Regex - case class RegexParser(reg: Regex) extends Parser[String, String] { def parse(sb: String) = reg.findPrefixMatchOf(sb) match { case None => Set() @@ -47,12 +46,13 @@ } val NumParser = RegexParser("[0-9]+".r) -def StringParser(s: String) = RegexParser(s.r) +def StringParser(s: String) = RegexParser(Regex.quote(s).r) +val NumParserInt = NumParser ==> (s => s.toInt) // convenience implicit def string2parser(s: String) = StringParser(s) -//implicit def char2parser(c: Char) = CharParser(c) +implicit def char2parser(c: Char) = CharParser(c) implicit def ParserOps[I<% Seq[_], T](p: Parser[I, T]) = new { def | (q : => Parser[I, T]) = new AltParser[I, T](p, q) @@ -70,25 +70,19 @@ new SeqParser[String, String, String](s, r) } -val c = new CharParser('c') -lazy val cn = c ==> (c => c.toInt) -val f = (c: Char) => c.toInt -c.parse("cb") -(c ==> f).parse("cb") - -// a parse palindromes lazy val Pal : Parser[String, String] = - (("a" ~ Pal ~ "a") ==> { case ((x, y), z) => x + y + z } || - ("b" ~ Pal ~ "b") ==> { case ((x, y), z) => x + y + z } || "a" || "b" || "") + (("a" ~ Pal ~ "a") ==> { case ((x, y), z) => x + y + z } | + ("b" ~ Pal ~ "b") ==> { case ((x, y), z) => x + y + z } | "a" | "b" | "") Pal.parse_all("abaaaba") +Pal.parse("abaaaba") println("Palindrome: " + Pal.parse_all("abaaaba")) // well-nested parenthesis parser lazy val P : Parser[String, String] = - "(" ~ P ~ ")" ~ P ==> { case (((u, x), y), z) => "{" + x + "}" + z } || "" + "(" ~ P ~ ")" ~ P ==> { case (((_, x), _), y) => "{" + x + "}" + y } | "" P.parse_all("(((()()))())") P.parse_all("(((()()))()))") @@ -98,15 +92,16 @@ // arithmetic expressions lazy val E: Parser[String, Int] = - (T ~ "+" ~ E) ==> { case ((x, y), z) => x + z } || - (T ~ "-" ~ E) ==> { case ((x, y), z) => x - z } || T + (T ~ "+" ~ E) ==> { case ((x, y), z) => x + z } | + (T ~ "-" ~ E) ==> { case ((x, y), z) => x - z } | T lazy val T: Parser[String, Int] = - ((F ~ "*" ~ T) ==> { case ((x, y), z) => x * z } || F) + (F ~ "*" ~ T) ==> { case ((x, y), z) => x * z } | F lazy val F: Parser[String, Int] = - ("(" ~ E ~ ")") ==> { case ((x, y), z) => y } || NumParser + ("(" ~ E ~ ")") ==> { case ((x, y), z) => y } | NumParserInt -println(E.parse("4*2+3")) +println(E.parse_all("4*2+3")) +println(E.parse_all("4*(2+3)")) println(E.parse_all("4/2+3")) println(E.parse("1 + 2 * 3")) println(E.parse_all("(1+2)+3")) @@ -116,18 +111,18 @@ // no left-recursion allowed, otherwise will loop lazy val EL: Parser[String, Int] = - ((EL ~ "+" ~ EL) ==> { case ((x, y), z) => x + z} || - (EL ~ "*" ~ EL) ==> { case ((x, y), z) => x * z} || - ("(" ~ EL ~ ")") ==> { case ((x, y), z) => y} || - NumParser) + (EL ~ "+" ~ EL ==> { case ((x, y), z) => x + z} | + EL ~ "*" ~ EL ==> { case ((x, y), z) => x * z} | + "(" ~ EL ~ ")" ==> { case ((x, y), z) => y} | + NumParserInt) -//println(E.parse_all("1+2+3")) +//println(EL.parse_all("1+2+3")) // a repetition parser def RepParser[I <% Seq[_], T](p: => Parser[I, T]): Parser[I, List[T]] = { - p ==> { case x => x :: Nil } || + p ==> { case x => x :: Nil } | p ~ RepParser(p) ==> { case (x, y) => x :: y } } @@ -140,12 +135,12 @@ // non-ambiguous vs ambiguous grammars lazy val S : Parser[String, String] = - ("1" ~ S ~ S) ==> { case ((x, y), z) => x + y + z } || "" + ("1" ~ S ~ S) ==> { case ((x, y), z) => x + y + z } | "" S.parse("1" * 15) lazy val U : Parser[String, String] = - ("1" ~ U) ==> { case (x, y) => x + y } || "" + ("1" ~ U) ==> { case (x, y) => x + y } | "" U.parse("1" * 15) @@ -157,7 +152,7 @@ U.parse_all("1" * 100 + "0") lazy val UCount : Parser[String, Int] = - ("1" ~ UCount) ==> { case (x, y) => y + 1 } || + ("1" ~ UCount) ==> { case (x, y) => y + 1 } | "" ==> { (x) => 0 } UCount.parse("11111") @@ -177,38 +172,7 @@ (One ~ One ~ One).parse("111") (One ~ One ~ One ~ One).parse("1111") -(One || Two).parse("111") - - -for (x <- List(1, 2, 3, 4)) println(x) -for (x <- List(1, 2, 3, 4); if (2 < x)) yield (x.toString + x.toString) -for (x <- List("2", "1", "3", "4", "1")) yield (x + x + x) - -(1, "one", '1')._3 -for ((x, y) <- List((1, "one"), (2, "two"), (3, "three"), (4,"many")); if (y == "many")) - yield (x.toString + y) +(One | Two).parse("111") -// Example section for lazy evaluation -def square(n: Int) = { - n * n -} - -square(4 + 3 + 5) - -def bar(): Int = { - bar() - 3 -} - -//would loop -square(bar()) - -// lazy -def foo(n: => Int) = { - print("finished") -} - -foo(bar()) -