updated
authorChristian Urban <christian.urban@kcl.ac.uk>
Sun, 29 Oct 2023 13:05:09 +0000
changeset 948 6bb67c2dcfd3
parent 947 dc31a099dc98
child 949 61797848eede
updated
progs/lexer/lex.sc
progs/parser-combinators/comb1.sc
progs/parser-combinators/comb2.sc
--- a/progs/lexer/lex.sc	Sun Oct 29 00:06:30 2023 +0100
+++ b/progs/lexer/lex.sc	Sun Oct 29 13:05:09 2023 +0000
@@ -46,13 +46,10 @@
   def ~ (s: Rexp) = SEQ(r, s)
 }
 
+// to use & for records, instead of $ which had
+// its precedence be changed in Scala 3
 extension (s: String) {
-  def | (r: Rexp) = ALT(s, r)
-  def | (r: String) = ALT(s, r)
-  def % = STAR(s)
-  def ~ (r: Rexp) = SEQ(s, r)
-  def ~ (r: String) = SEQ(s, r)
-  def $ (r: Rexp) = RECD(s, r)
+  def & (r: Rexp) = RECD(s, r)
 }
 
 val TEST = ("ab" | "ba").%
@@ -166,20 +163,20 @@
 val STRING: Rexp = "\"" ~ SYM.% ~ "\""
 
 
-val WHILE_REGS = (("k" $ KEYWORD) | 
-                  ("i" $ ID) | 
-                  ("o" $ OP) | 
-                  ("n" $ NUM) | 
-                  ("s" $ SEMI) | 
-                  ("str" $ STRING) |
-                  ("p" $ (LPAREN | RPAREN)) | 
-                  ("w" $ WHITESPACE)).%
+val WHILE_REGS = (("k" & KEYWORD) | 
+                  ("i" & ID) | 
+                  ("o" & OP) | 
+                  ("n" & NUM) | 
+                  ("s" & SEMI) | 
+                  ("str" & STRING) |
+                  ("p" & (LPAREN | RPAREN)) | 
+                  ("w" & WHITESPACE)).%
 
 val KY : Rexp = "if" | "read" | "write"
 val WH : Rexp = " " | "\n"
 
-val TRIV_REGS = (("k" $ KY) | 
-                  ("w" $ WHITESPACE)).%
+val TRIV_REGS = (("k" & KY) | 
+                  ("w" & WHITESPACE)).%
 
 // Two Simple While Tests
 //========================
@@ -201,8 +198,3 @@
   println(lexing(WHILE_REGS, prog2))
 }
 
-
-
-
-
-// runs with amm2 and amm3
--- a/progs/parser-combinators/comb1.sc	Sun Oct 29 00:06:30 2023 +0100
+++ b/progs/parser-combinators/comb1.sc	Sun Oct 29 13:05:09 2023 +0000
@@ -23,7 +23,6 @@
 // parser combinators
 
 
-
 // alternative parser
 class AltParser[I : IsSeq, T](p: => Parser[I, T], 
                               q: => Parser[I, T]) extends Parser[I, T] {
@@ -96,9 +95,11 @@
   def map[S](f: => T => S) = new MapParser[I, T, S](p, f)
 }
 
+// simple example of transforming the 
+// result into capital letters
 def toU(s: String) = s.map(_.toUpper)
 
-(p"ELSE").map(toU(_)).parse("ELSEifthen")  
+(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
@@ -112,6 +113,7 @@
 
 
 // A parser for palindromes (just returns them as string)
+//  since the parser is recursive it needs to be lazy
 lazy val Pal : Parser[String, String] = {
    (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" } || 
--- a/progs/parser-combinators/comb2.sc	Sun Oct 29 00:06:30 2023 +0100
+++ b/progs/parser-combinators/comb2.sc	Sun Oct 29 13:05:09 2023 +0000
@@ -14,9 +14,9 @@
 // it allows writing nested patterns as
 // case x ~ y ~ z => ...
 
+case class ~[+A, +B](x: A, y: B)
 
 
-case class ~[+A, +B](x: A, y: B)
 
 type IsSeq[I] = I => Seq[_]
 
@@ -45,7 +45,7 @@
 }
 
 // map parser
-class maparser[I : IsSeq, T, S](p: => Parser[I, T], 
+class MapParser[I : IsSeq, T, S](p: => Parser[I, T], 
                                 f: T => S) extends Parser[I, S] {
   def parse(in: I) = for ((hd, tl) <- p.parse(in)) yield (f(hd), tl)
 }
@@ -70,7 +70,7 @@
 }
 
 
-// atomic parser for numbers (transformed into ints)
+// atomic parser for numbers (transformed into Ints)
 case object NumParser extends Parser[String, Int] {
   val reg = "[0-9]+".r
   def parse(sb: String) = reg.findPrefixOf(sb) match {
@@ -95,7 +95,7 @@
 extension [I : IsSeq, T](p: Parser[I, T]) {
   def ||(q : => Parser[I, T]) = new AltParser[I, T](p, q)
   def ~[S] (q : => Parser[I, S]) = new SeqParser[I, T, S](p, q)
-  def map[S](f: => T => S) = new maparser[I, T, S](p, f)
+  def map[S](f: => T => S) = new MapParser[I, T, S](p, f)
 }
 
 
@@ -134,8 +134,8 @@
   (Fa ~ p"/" ~ Te).map[AExp]{ case x ~ _ ~ z => Aop("/", x, z) } || Fa  
 lazy val Fa: Parser[String, AExp] = 
    (p"(" ~ AExp ~ p")").map{ case _ ~ y ~ _ => y } || 
-   IdParser.map(Var) || 
-   NumParser.map(Num)
+   IdParser.map(Var(_)) || 
+   NumParser.map(Num(_))
 
 // boolean expressions with some simple nesting
 lazy val BExp: Parser[String, BExp] =