diff -r 8b8db9558ecf -r 8b0b414e71b0 exps/both.scala --- 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 //============