--- a/progs/parser-combinators/comb1.sc Sat Nov 04 18:28:09 2023 +0000
+++ b/progs/parser-combinators/comb1.sc Sat Nov 11 10:08:33 2023 +0000
@@ -20,6 +20,7 @@
if is(tl).isEmpty) yield hd
}
+
// parser combinators
@@ -39,7 +40,7 @@
// map parser
class MapParser[I : IsSeq, T, S](p: => Parser[I, T],
- f: T => S) extends Parser[I, S] {
+ f: T => S) extends Parser[I, S] {
def parse(in: I) = for ((hd, tl) <- p.parse(in)) yield (f(hd), tl)
}
@@ -51,7 +52,11 @@
if (in != "" && in.head == c) Set((c, in.tail)) else Set()
}
-CharParser('a').parse("abc")
+val ap = CharParser('a')
+val bp = CharParser('b')
+
+val abp = SeqParser(ap, bp)
+MapParser(abp, ab => s"$ab").parse("abc")
// an atomic parser for parsing strings according to a regex
import scala.util.matching.Regex
@@ -67,14 +72,14 @@
val NumParser = RegexParser("[0-9]+".r)
def StrParser(s: String) = RegexParser(Regex.quote(s).r)
-NumParser.parse("a123a123bc")
+NumParser.parse("123a123bc")
StrParser("else").parse("elsethen")
// 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)
+val NumParserInt = MapParser(NumParser, (s: String) => s.toInt)
NumParserInt.parse("123abc")
// the following string interpolation allows us to write
@@ -111,6 +116,7 @@
val NumParserInt2 = NumParser.map(_.toInt)
+val x = 1 + 3
// A parser for palindromes (just returns them as string)
// since the parser is recursive it needs to be lazy
@@ -121,8 +127,8 @@
}
// examples
-Pal.parse_all("abaaaba")
-Pal.parse("abaaaba")
+Pal.parse_all("abacaba")
+Pal.parse("abacaaba")
println("Palindrome: " + Pal.parse_all("abaaaba"))
@@ -143,6 +149,9 @@
// A parser for arithmetic expressions (Terms and Factors)
+"1 + 2 * 3"
+"(1 + 2) * 3"
+{
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 }
@@ -150,12 +159,12 @@
(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"))
println(E.parse_all("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"))