4 import scala.io.Source |
4 import scala.io.Source |
5 |
5 |
6 abstract class Rexp |
6 abstract class Rexp |
7 case object ZERO extends Rexp |
7 case object ZERO extends Rexp |
8 case object ONE extends Rexp |
8 case object ONE extends Rexp |
9 case class CHAR(c: Char) extends Rexp |
9 case class CHARS(f: Char => Boolean) extends Rexp |
10 case class ALT(r1: Rexp, r2: Rexp) extends Rexp |
10 case class ALT(r1: Rexp, r2: Rexp) extends Rexp |
11 case class SEQ(r1: Rexp, r2: Rexp) extends Rexp |
11 case class SEQ(r1: Rexp, r2: Rexp) extends Rexp |
12 case class STAR(r: Rexp) extends Rexp |
12 case class STAR(r: Rexp) extends Rexp |
13 case class RECD(x: String, r: Rexp) extends Rexp |
13 case class RECD(x: String, r: Rexp) extends Rexp |
14 case class CRANGE(cs: String) extends Rexp |
|
15 case class PLUS(r: Rexp) extends Rexp |
14 case class PLUS(r: Rexp) extends Rexp |
16 case class OPT(r: Rexp) extends Rexp |
15 case class OPT(r: Rexp) extends Rexp |
17 case class NTIMES(r: Rexp, n: Int) extends Rexp |
16 case class NTIMES(r: Rexp, n: Int) extends Rexp |
18 |
17 |
19 abstract class Val |
18 abstract class Val |
66 // nullable function: tests whether the regular |
65 // nullable function: tests whether the regular |
67 // expression can recognise the empty string |
66 // expression can recognise the empty string |
68 def nullable (r: Rexp) : Boolean = r match { |
67 def nullable (r: Rexp) : Boolean = r match { |
69 case ZERO => false |
68 case ZERO => false |
70 case ONE => true |
69 case ONE => true |
71 case CHAR(_) => false |
70 case CHARS(_) => false |
72 case ALT(r1, r2) => nullable(r1) || nullable(r2) |
71 case ALT(r1, r2) => nullable(r1) || nullable(r2) |
73 case SEQ(r1, r2) => nullable(r1) && nullable(r2) |
72 case SEQ(r1, r2) => nullable(r1) && nullable(r2) |
74 case STAR(_) => true |
73 case STAR(_) => true |
75 case RECD(_, r1) => nullable(r1) |
74 case RECD(_, r1) => nullable(r1) |
76 case CRANGE(_) => false |
|
77 case PLUS(r) => nullable(r) |
75 case PLUS(r) => nullable(r) |
78 case OPT(_) => true |
76 case OPT(_) => true |
79 case NTIMES(r, n) => if (n == 0) true else nullable(r) |
77 case NTIMES(r, n) => if (n == 0) true else nullable(r) |
80 } |
78 } |
81 |
79 |
82 // derivative of a regular expression w.r.t. a character |
80 // derivative of a regular expression w.r.t. a character |
83 def der (c: Char, r: Rexp) : Rexp = r match { |
81 def der (c: Char, r: Rexp) : Rexp = r match { |
84 case ZERO => ZERO |
82 case ZERO => ZERO |
85 case ONE => ZERO |
83 case ONE => ZERO |
86 case CHAR(d) => if (c == d) ONE else ZERO |
84 case CHARS(f) => if (f(c)) ONE else ZERO |
87 case ALT(r1, r2) => ALT(der(c, r1), der(c, r2)) |
85 case ALT(r1, r2) => ALT(der(c, r1), der(c, r2)) |
88 case SEQ(r1, r2) => |
86 case SEQ(r1, r2) => |
89 if (nullable(r1)) ALT(SEQ(der(c, r1), r2), der(c, r2)) |
87 if (nullable(r1)) ALT(SEQ(der(c, r1), r2), der(c, r2)) |
90 else SEQ(der(c, r1), r2) |
88 else SEQ(der(c, r1), r2) |
91 case STAR(r) => SEQ(der(c, r), STAR(r)) |
89 case STAR(r) => SEQ(der(c, r), STAR(r)) |
92 case RECD(_, r1) => der(c, r1) |
90 case RECD(_, r1) => der(c, r1) |
93 case CRANGE(cs) => if (cs.contains(c)) ONE else ZERO |
|
94 case PLUS(r) => SEQ(der(c, r), STAR(r)) |
91 case PLUS(r) => SEQ(der(c, r), STAR(r)) |
95 case OPT(r) => ALT(der(c, r), ZERO) |
92 case OPT(r) => ALT(der(c, r), ZERO) |
96 case NTIMES(r, n) => if (n == 0) ZERO else der(c, SEQ(r, NTIMES(r, n - 1))) |
93 case NTIMES(r, n) => if (n == 0) ZERO else SEQ(der(c, r), NTIMES(r, n - 1)) |
97 } |
94 } |
98 |
95 |
99 // derivative w.r.t. a string (iterates der) |
96 // derivative w.r.t. a string (iterates der) |
100 @tailrec |
97 @tailrec |
101 def ders (s: List[Char], r: Rexp) : Rexp = s match { |
98 def ders (s: List[Char], r: Rexp) : Rexp = s match { |
134 case SEQ(r1, r2) => Sequ(mkeps(r1), mkeps(r2)) |
131 case SEQ(r1, r2) => Sequ(mkeps(r1), mkeps(r2)) |
135 case STAR(r) => Stars(Nil) |
132 case STAR(r) => Stars(Nil) |
136 case RECD(x, r) => Rec(x, mkeps(r)) |
133 case RECD(x, r) => Rec(x, mkeps(r)) |
137 case PLUS(r) => Stars(List(mkeps(r))) |
134 case PLUS(r) => Stars(List(mkeps(r))) |
138 case OPT(_) => Right(Empty) |
135 case OPT(_) => Right(Empty) |
139 case NTIMES(r, n) => if (n == 0) Stars(Nil) else Stars(Nil.padTo(n, mkeps(r))) |
136 case NTIMES(r, n) => Stars(List.fill(n)(mkeps(r))) |
140 } |
137 } |
141 |
138 |
142 |
139 |
143 def inj(r: Rexp, c: Char, v: Val) : Val = (r, v) match { |
140 def inj(r: Rexp, c: Char, v: Val) : Val = (r, v) match { |
144 case (STAR(r), Sequ(v1, Stars(vs))) => Stars(inj(r, c, v1)::vs) |
141 case (STAR(r), Sequ(v1, Stars(vs))) => Stars(inj(r, c, v1)::vs) |
145 case (SEQ(r1, r2), Sequ(v1, v2)) => Sequ(inj(r1, c, v1), v2) |
142 case (SEQ(r1, r2), Sequ(v1, v2)) => Sequ(inj(r1, c, v1), v2) |
146 case (SEQ(r1, r2), Left(Sequ(v1, v2))) => Sequ(inj(r1, c, v1), v2) |
143 case (SEQ(r1, r2), Left(Sequ(v1, v2))) => Sequ(inj(r1, c, v1), v2) |
147 case (SEQ(r1, r2), Right(v2)) => Sequ(mkeps(r1), inj(r2, c, v2)) |
144 case (SEQ(r1, r2), Right(v2)) => Sequ(mkeps(r1), inj(r2, c, v2)) |
148 case (ALT(r1, r2), Left(v1)) => Left(inj(r1, c, v1)) |
145 case (ALT(r1, r2), Left(v1)) => Left(inj(r1, c, v1)) |
149 case (ALT(r1, r2), Right(v2)) => Right(inj(r2, c, v2)) |
146 case (ALT(r1, r2), Right(v2)) => Right(inj(r2, c, v2)) |
150 case (CHAR(d), Empty) => Chr(c) |
147 case (CHARS(_), Empty) => Chr(c) |
151 case (RECD(x, r1), _) => Rec(x, inj(r1, c, v)) |
148 case (RECD(x, r1), _) => Rec(x, inj(r1, c, v)) |
152 case (CRANGE(_), Empty) => Chr(c) |
|
153 case (PLUS(r), Sequ(v1, Stars(vs))) => Stars(inj(r, c, v1)::vs) |
149 case (PLUS(r), Sequ(v1, Stars(vs))) => Stars(inj(r, c, v1)::vs) |
154 case (OPT(r), Left(v1)) => Left(inj(r, c, v1)) |
150 case (OPT(r), Left(v1)) => Left(inj(r, c, v1)) |
155 case (NTIMES(r, n), Sequ(v1, Stars(vs))) => Stars(inj(r, c, v1)::vs) |
151 case (NTIMES(r, n), Sequ(v1, Stars(vs))) => Stars(inj(r, c, v1)::vs) |
156 case (NTIMES(r, n), Left(Sequ(v1, Stars(vs)))) => Stars(inj(r, c, v1)::vs) |
|
157 case (NTIMES(r, n), Right(Stars(v::vs))) => Stars(mkeps(r)::inj(r, c, v)::vs) |
|
158 } |
152 } |
159 |
153 |
160 // main unsimplified lexing function (produces a value) |
154 // main unsimplified lexing function (produces a value) |
161 def lex(r: Rexp, s: List[Char]) : Val = s match { |
155 def lex(r: Rexp, s: List[Char]) : Val = s match { |
162 case Nil => if (nullable(r)) mkeps(r) else throw new Exception("Not matched") |
156 case Nil => if (nullable(r)) mkeps(r) else throw new Exception("Not matched") |