--- a/progs/parser-combinators/comb1.sc Thu Nov 10 23:49:29 2022 +0000
+++ b/progs/parser-combinators/comb1.sc Tue Nov 15 11:34:33 2022 +0000
@@ -50,6 +50,7 @@
if (in != "" && in.head == c) Set((c, in.tail)) else Set()
}
+CharParser('c').parse("abc")
// an atomic parser for parsing strings according to a regex
import scala.util.matching.Regex
@@ -65,23 +66,27 @@
val NumParser = RegexParser("[0-9]+".r)
def StrParser(s: String) = RegexParser(Regex.quote(s).r)
+NumParser.parse("a123a123bc")
+StrParser("else").parse("eelsethen")
// NumParserInt transforms a "string integer" into a propper Int
// (needs "new" because MapParser is not a case class)
val NumParserInt = new MapParser(NumParser, (s: String) => s.toInt)
-
+NumParserInt.parse("123abc")
// the following string interpolation allows us to write
// StrParser(_some_string_) more conveniently as
//
// p"<_some_string_>"
+
implicit def parser_interpolation(sc: StringContext) = new {
def p(args: Any*) = StrParser(sc.s(args:_*))
}
-
+
+(p"else").parse("elsethen")
// more convenient syntax for parser combinators
implicit def ParserOps[I : IsSeq, T](p: Parser[I, T]) = new {
@@ -90,6 +95,10 @@
def map[S](f: => T => S) = new MapParser[I, T, S](p, f)
}
+def toU(s: String) = s.map(_.toUpper)
+
+(p"ELSE").map(toU(_)).parse("ELSEifthen")
+
// these implicits allow us to use an infix notation for
// sequences and alternatives; we also can write the usual
// map for a MapParser
@@ -101,9 +110,11 @@
val NumParserInt2 = NumParser.map(_.toInt)
+
+
// A parser for palindromes (just returns them as string)
lazy val Pal : Parser[String, String] = {
- ((p"a" ~ Pal) ~ p"a").map{ case ((x, y), z) => s"$x$y$z" } ||
+ (p"a" ~ Pal ~ p"a").map{ case ((x, y), z) => s"$x$y$z" } ||
(p"b" ~ Pal ~ p"b").map{ case ((x, y), z) => s"$x$y$z" } ||
p"a" || p"b" || p""
}
@@ -130,7 +141,7 @@
println(P.parse_all("()"))
// A parser for arithmetic expressions (Terms and Factors)
-
+{
lazy val E: Parser[String, Int] = {
(T ~ p"+" ~ E).map{ case ((x, _), z) => x + z } ||
(T ~ p"-" ~ E).map{ case ((x, _), z) => x - z } || T }
@@ -138,7 +149,7 @@
(F ~ p"*" ~ T).map{ case ((x, _), z) => x * z } || F }
lazy val F: Parser[String, Int] = {
(p"(" ~ E ~ p")").map{ case ((_, y), _) => y } || NumParserInt }
-
+}
println(E.parse_all("1+3+4"))
println(E.parse("1+3+4"))
println(E.parse_all("4*2+3"))