25 case class Right(v: Val) extends Val |
25 case class Right(v: Val) extends Val |
26 case class Stars(vs: List[Val]) extends Val |
26 case class Stars(vs: List[Val]) extends Val |
27 case class Rec(x: String, v: Val) extends Val |
27 case class Rec(x: String, v: Val) extends Val |
28 |
28 |
29 |
29 |
30 // Convenience typing |
30 // Convenience for typing |
31 def charlist2rexp(s : List[Char]): Rexp = s match { |
31 def charlist2rexp(s : List[Char]): Rexp = s match { |
32 case Nil => ONE |
32 case Nil => ONE |
33 case c::Nil => CHAR(c) |
33 case c::Nil => CHAR(c) |
34 case c::s => SEQ(CHAR(c), charlist2rexp(s)) |
34 case c::s => SEQ(CHAR(c), charlist2rexp(s)) |
35 } |
35 } |
36 |
36 |
37 implicit def string2rexp(s : String) : Rexp = |
37 implicit def string2rexp(s : String) : Rexp = |
38 charlist2rexp(s.toList) |
38 charlist2rexp(s.toList) |
39 |
39 |
40 implicit def RexpOps(r: Rexp) = new { |
40 extension (r: Rexp) { |
41 def | (s: Rexp) = ALT(r, s) |
41 def | (s: Rexp) = ALT(r, s) |
42 def % = STAR(r) |
42 def % = STAR(r) |
43 def ~ (s: Rexp) = SEQ(r, s) |
43 def ~ (s: Rexp) = SEQ(r, s) |
44 } |
44 } |
45 |
45 |
46 implicit def stringOps(s: String) = new { |
46 extension (s: String) { |
47 def | (r: Rexp) = ALT(s, r) |
47 def | (r: Rexp) = ALT(s, r) |
48 def | (r: String) = ALT(s, r) |
48 def | (r: String) = ALT(s, r) |
49 def % = STAR(s) |
49 def % = STAR(s) |
50 def ~ (r: Rexp) = SEQ(s, r) |
50 def ~ (r: Rexp) = SEQ(s, r) |
51 def ~ (r: String) = SEQ(s, r) |
51 def ~ (r: String) = SEQ(s, r) |
80 case STAR(r) => SEQ(der(c, r), STAR(r)) |
80 case STAR(r) => SEQ(der(c, r), STAR(r)) |
81 |
81 |
82 case RECD(_, r1) => der(c, r1) |
82 case RECD(_, r1) => der(c, r1) |
83 case RANGE(s) => if (s.contains(c)) ONE else ZERO |
83 case RANGE(s) => if (s.contains(c)) ONE else ZERO |
84 case PLUS(r1) => SEQ(der(c, r1), STAR(r1)) |
84 case PLUS(r1) => SEQ(der(c, r1), STAR(r1)) |
85 case OPTIONAL(r1) => ALT(der(c, r1), ZERO) |
85 case OPTIONAL(r1) => der(c, r1) |
86 case NTIMES(r, i) => |
86 case NTIMES(r, i) => |
87 if (i == 0) ZERO else SEQ(der(c, r), NTIMES(r, i - 1)) |
87 if (i == 0) ZERO else SEQ(der(c, r), NTIMES(r, i - 1)) |
88 } |
88 } |
89 |
89 |
90 // Flatten |
90 // Flatten |
117 case SEQ(r1, r2) => Sequ(mkeps(r1), mkeps(r2)) |
117 case SEQ(r1, r2) => Sequ(mkeps(r1), mkeps(r2)) |
118 case STAR(r) => Stars(Nil) |
118 case STAR(r) => Stars(Nil) |
119 case RECD(x, r) => Rec(x, mkeps(r)) |
119 case RECD(x, r) => Rec(x, mkeps(r)) |
120 |
120 |
121 case PLUS(r) => Stars(List(mkeps(r))) // the first copy must match the empty string |
121 case PLUS(r) => Stars(List(mkeps(r))) // the first copy must match the empty string |
122 case OPTIONAL(r) => Right(Empty) |
122 case OPTIONAL(r) => if (nullable(r)) Stars(List(mkeps(r))) else Stars(Nil) |
123 case NTIMES(r, i) => Stars(List.fill(i)(mkeps(r))) |
123 case NTIMES(r, i) => Stars(List.fill(i)(mkeps(r))) |
124 } |
124 } |
125 |
125 |
126 // Inj |
126 // Inj |
127 def inj(r: Rexp, c: Char, v: Val) : Val = (r, v) match { |
127 def inj(r: Rexp, c: Char, v: Val) : Val = (r, v) match { |
134 case (CHAR(d), Empty) => Chr(c) |
134 case (CHAR(d), Empty) => Chr(c) |
135 case (RECD(x, r1), _) => Rec(x, inj(r1, c, v)) |
135 case (RECD(x, r1), _) => Rec(x, inj(r1, c, v)) |
136 |
136 |
137 case (RANGE(_), Empty) => Chr(c) |
137 case (RANGE(_), Empty) => Chr(c) |
138 case (PLUS(r), Sequ(v1, Stars(vs))) => Stars(inj(r, c, v1)::vs) |
138 case (PLUS(r), Sequ(v1, Stars(vs))) => Stars(inj(r, c, v1)::vs) |
139 case (OPTIONAL(r), Left(v1)) => Left(inj(r, c, v1)) |
139 case (OPTIONAL(r), v1) => Stars(List(inj(r, c, v1))) |
140 case (NTIMES(r, n), Sequ(v1, Stars(vs))) => Stars(inj(r, c, v1)::vs) |
140 case (NTIMES(r, n), Sequ(v1, Stars(vs))) => Stars(inj(r, c, v1)::vs) |
141 } |
141 } |
142 |
142 |
143 // Rectification functions |
143 // Rectification functions |
144 def F_ID(v: Val): Val = v |
144 def F_ID(v: Val): Val = v |
197 } |
197 } |
198 |
198 |
199 def lexing_simp(r: Rexp, s: String) = env(lex_simp(r, s.toList)) |
199 def lexing_simp(r: Rexp, s: String) = env(lex_simp(r, s.toList)) |
200 |
200 |
201 // Language specific code |
201 // Language specific code |
202 val KEYWORD : Rexp = "while" | "if" | "then" | "else" | "do" | "for" | "to" | "true" | "false" | "read" | "write" | "skip" |
202 // Language specific code |
|
203 val KEYWORD : Rexp = "while" | "if" | "then" | "else" | "do" | "for" | "upto" | "true" | "false" | "read" | "write" | "skip" | "break" |
203 val OP : Rexp = "+" | "-" | "*" | "%" | "/" | "==" | "!=" | ">" | "<" | ">=" | "<=" | ":=" | "&&" | "||" |
204 val OP : Rexp = "+" | "-" | "*" | "%" | "/" | "==" | "!=" | ">" | "<" | ">=" | "<=" | ":=" | "&&" | "||" |
204 val LET: Rexp = RANGE(('A' to 'Z').toSet ++ ('a' to 'z')) |
205 val LET: Rexp = RANGE(('A' to 'Z').toSet ++ ('a' to 'z').toSet) |
205 val SYM : Rexp = LET | RANGE(Set('.', '_', '>', '<', '=', ';', ',', ':')) |
206 val SYM : Rexp = RANGE(Set('.', '_', '>', '<', '=', ';', ',', ':', ')', '(')) |
206 val PARENS : Rexp = "(" | "{" | ")" | "}" |
207 val PARENS : Rexp = "(" | "{" | ")" | "}" |
207 val SEMI : Rexp = ";" |
208 val SEMI : Rexp = ";" |
208 val WHITESPACE : Rexp = PLUS(" ") | "\n" | "\t" | "\r" |
209 val WHITESPACE : Rexp = PLUS(" ") | "\n" | "\t" | "\r" |
209 val DIGIT : Rexp = RANGE(('0' to '9').toSet) |
210 val DIGIT : Rexp = RANGE(('0' to '9').toSet) |
210 val DIGIT1 : Rexp = RANGE(('1' to '9').toSet) |
211 val DIGIT1 : Rexp = RANGE(('1' to '9').toSet) |
211 val STRING : Rexp = "\"" ~ (SYM | " " | "\\n" | DIGIT).% ~ "\"" |
212 val STRING : Rexp = "\"" ~ (LET | SYM | DIGIT | " " | "\\n").% ~ "\"" |
212 val ID : Rexp = LET ~ (LET | "_" | DIGIT).% |
213 val ID : Rexp = LET ~ (LET | "_" | DIGIT).% |
213 val NUM : Rexp = "0" | (DIGIT1 ~ DIGIT.%) |
214 val NUM : Rexp = "0" | (DIGIT1 ~ DIGIT.%) |
214 val EOL : Rexp = "\n" | "\r\n" |
215 val EOL : Rexp = "\n" | "\r\n" |
215 val COMMENT : Rexp = "//" ~ (SYM | PARENS | " " | DIGIT).% ~ EOL |
216 val COMMENT : Rexp = "//" ~ (LET | SYM | PARENS | " " | DIGIT).% ~ EOL |
216 |
217 |
217 val WHILE_REGS = (("k" $ KEYWORD) | |
218 val WHILE_REGS = (("k" $ KEYWORD) | |
218 ("o" $ OP) | |
219 ("o" $ OP) | |
219 ("str" $ STRING) | |
220 ("str" $ STRING) | |
220 ("p" $ PARENS) | |
221 ("p" $ PARENS) | |