exps/both.scala
changeset 312 8b0b414e71b0
parent 311 8b8db9558ecf
child 314 20a57552d722
--- a/exps/both.scala	Sun Feb 17 22:15:06 2019 +0000
+++ b/exps/both.scala	Wed Feb 20 00:00:30 2019 +0000
@@ -42,6 +42,7 @@
 def CHAR(c: Char) = PRED(_ == c, c.toString)
 def ALT(r1: Rexp, r2: Rexp) = ALTS(List(r1, r2))
 def PLUS(r: Rexp) = SEQ(r, STAR(r))
+val ANYCHAR = PRED(_ => true, ".")
 
 // annotated regular expressions
 abstract class ARexp 
@@ -529,6 +530,71 @@
   env(blexing2_simp(r, s)).map(esc2)
 
 
+// Parser for regexes
+
+case class Parser(s: String) {
+  var i = 0
+  
+  def peek() = s(i)
+  def eat(c: Char) = 
+    if (c == s(i)) i = i + 1 else throw new Exception("Expected " + c + " got " + s(i))
+  def next() = { i = i + 1; s(i - 1) }
+  def more() = s.length - i > 0
+
+  def Regex() : Rexp = {
+    val t = Term();
+    if (more() && peek() == '|') {
+      eat ('|') ; 
+      ALT(t, Regex()) 
+    } 
+    else t
+  }
+
+  def Term() : Rexp = {
+    var f : Rexp = 
+      if (more() && peek() != ')' && peek() != '|') Factor() else ONE;
+    while (more() && peek() != ')' && peek() != '|') {
+      f = SEQ(f, Factor()) ;
+    }
+    f
+  }
+
+  def Factor() : Rexp = {
+    var b = Base();
+    while (more() && peek() == '*') {
+      eat('*') ;
+      b = STAR(b) ;
+    }
+    while (more() && peek() == '?') {
+      eat('?') ;
+      b = ALT(b, ONE) ;
+    }
+    while (more() && peek() == '+') {
+      eat('+') ;
+      b = SEQ(b, STAR(b)) ;
+    }
+    b
+  }
+
+  def Base() : Rexp = {
+    peek() match {
+      case '(' => { eat('(') ; val r = Regex(); eat(')') ; r }   // if groups should be groups RECD("",r) }
+      case '.' => { eat('.'); ANYCHAR }
+      case _ => CHAR(next())
+    }
+  }
+}
+
+// two simple examples for the regex parser
+
+println("two simple examples for the regex parser")
+
+println(string(Parser("a|(bc)*").Regex()))
+println(string(Parser("(a|b)*(babab(a|b)*bab|bba(a|b)*bab)(a|b)*").Regex()))
+
+
+
+System.exit(0)
 
 //   Testing
 //============