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), Left(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 |
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 val KEYWORD : Rexp = "while" | "if" | "then" | "else" | "do" | "for" | "to" | "true" | "false" | "read" | "write" | "skip" |
203 val OP : Rexp = "+" | "-" | "*" | "%" | "/" | "==" | "!=" | ">" | "<" | ">=" | "<=" | ":=" | "&&" | "||" |
203 val OP : Rexp = "+" | "-" | "*" | "%" | "/" | "==" | "!=" | ">" | "<" | ">=" | "<=" | ":=" | "&&" | "||" |
204 val LET: Rexp = RANGE(('A' to 'Z').toSet ++ ('a' to 'z')) |
204 val LET: Rexp = RANGE(('A' to 'Z').toSet ++ ('a' to 'z').toSet) |
205 val SYM : Rexp = (LET | RANGE(Set('.', '_', '>', '<', '=', ';', ',', ':'))) |
205 val SYM : Rexp = RANGE(Set('.', '_', '>', '<', '=', ';', ',', ':', ')', '(')) |
206 val PARENS : Rexp = "(" | "{" | ")" | "}" |
206 val PARENS : Rexp = "(" | "{" | ")" | "}" |
207 val SEMI : Rexp = ";" |
207 val SEMI : Rexp = ";" |
208 val WHITESPACE : Rexp = PLUS(" ") | "\n" | "\t" | "\r" |
208 val WHITESPACE : Rexp = PLUS(" ") | "\n" | "\t" | "\r" |
209 val DIGIT : Rexp = RANGE(('0' to '9').toSet) |
209 val DIGIT : Rexp = RANGE(('0' to '9').toSet) |
210 val DIGIT1 : Rexp = RANGE(('1' to '9').toSet) |
210 val DIGIT1 : Rexp = RANGE(('1' to '9').toSet) |
211 val STRING : Rexp = "\"" ~ (SYM | " " | "\\n" | DIGIT).% ~ "\"" |
211 val STRING : Rexp = "\"" ~ (LET | SYM | DIGIT | " " | "\\n").% ~ "\"" |
212 val ID : Rexp = LET ~ (LET | "_" | DIGIT).% |
212 val ID : Rexp = LET ~ (LET | "_" | DIGIT).% |
213 val NUM : Rexp = "0" | (DIGIT1 ~ DIGIT.%) |
213 val NUM : Rexp = "0" | (DIGIT1 ~ DIGIT.%) |
214 val EOL : Rexp = "\n" | "\r\n" |
214 val EOL : Rexp = "\n" | "\r\n" |
215 val COMMENT : Rexp = "//" ~ (SYM | PARENS | " " | DIGIT).% ~ EOL |
215 val COMMENT : Rexp = "//" ~ (LET | SYM | PARENS | " " | DIGIT).% ~ EOL |
216 |
216 |
217 val WHILE_REGS = (("k" $ KEYWORD) | |
217 val WHILE_REGS = (("k" $ KEYWORD) | |
218 ("o" $ OP) | |
218 ("o" $ OP) | |
219 ("str" $ STRING) | |
219 ("str" $ STRING) | |
220 ("p" $ PARENS) | |
220 ("p" $ PARENS) | |
222 ("w" $ WHITESPACE) | |
222 ("w" $ WHITESPACE) | |
223 ("i" $ ID) | |
223 ("i" $ ID) | |
224 ("n" $ NUM) | |
224 ("n" $ NUM) | |
225 ("c" $ COMMENT)).% |
225 ("c" $ COMMENT)).% |
226 |
226 |
227 // Token |
227 |
|
228 |
|
229 def esc(raw: String): String = { |
|
230 import scala.reflect.runtime.universe._ |
|
231 Literal(Constant(raw)).toString |
|
232 } |
|
233 |
|
234 def escape(tks: List[(String, String)]) = |
|
235 tks.map{ case (s1, s2) => (s1, esc(s2))} |
|
236 |
|
237 |
|
238 // Tokens |
228 abstract class Token extends Serializable |
239 abstract class Token extends Serializable |
229 case class T_KEYWORD(s: String) extends Token |
240 case class T_KEYWORD(s: String) extends Token |
230 case class T_OP(s: String) extends Token |
241 case class T_OP(s: String) extends Token |
231 case class T_STRING(s: String) extends Token |
242 case class T_STRING(s: String) extends Token |
232 case class T_PAREN(s: String) extends Token |
243 case class T_PAREN(s: String) extends Token |