Compare commits
No commits in common. "77a083125424e8b0f31a4d3ac6dac163557131cc" and "a10f3db4fc1d30bae4edc990bcd5418277ee127a" have entirely different histories.
77a0831254
...
a10f3db4fc
|
|
@ -1,58 +0,0 @@
|
||||||
datatype regex {
|
|
||||||
Empty,
|
|
||||||
Lit of string,
|
|
||||||
Cat of (regex, regex),
|
|
||||||
Alt of (regex, regex),
|
|
||||||
Star of regex
|
|
||||||
}
|
|
||||||
|
|
||||||
datatype 'a list {
|
|
||||||
Empty,
|
|
||||||
Cons of ('a, 'a list)
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check if a regex matches the null string
|
|
||||||
typecheck nullable? : regex -> bool
|
|
||||||
def nullable? <Empty> = false
|
|
||||||
| nullable? <Lit s> = string_null? s
|
|
||||||
| nullable? <Cat l r> = logical_and (nullable? l) (nullable? r)
|
|
||||||
| nullable? <Alt l r> = logical_or (nullable? l) (nullable? r)
|
|
||||||
| nullable? <Star _> = true
|
|
||||||
|
|
||||||
# Check if a regex represents the empty language
|
|
||||||
typecheck unsatisfiable? : regex -> bool
|
|
||||||
def unsatisfiable? <Empty> = true
|
|
||||||
| unsatisfiable? <Lit _> = false
|
|
||||||
| unsatisfiable? <Cat l r> = logical_or (unsatisfiable? l) (unsatisfiable? r)
|
|
||||||
| unsatisfiable? <Alt l r> = logical_and (unsatisfiable? l) (unsatisfiable? r)
|
|
||||||
| unsatisfiable? <Star _> = false
|
|
||||||
|
|
||||||
# Regex derivative with respect to a character
|
|
||||||
typecheck derive : char -> regex -> regex
|
|
||||||
def derive c <Empty> = Empty
|
|
||||||
| derive c <Lit s> =
|
|
||||||
match string_null? s {
|
|
||||||
case true -> Empty
|
|
||||||
case false ->
|
|
||||||
match equal (string_head s) c {
|
|
||||||
case true -> Lit (string_tail s)
|
|
||||||
case false -> Empty
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
| derive c <Alt l r> = Alt (derive c l) (derive c r)
|
|
||||||
| derive c <Star r> = Cat (derive c r) (Star r)
|
|
||||||
| derive c <Cat l r> =
|
|
||||||
match nullable? l {
|
|
||||||
case true -> Alt (Cat (derive c l) r) (derive c r)
|
|
||||||
case false -> Cat (derive c l) r
|
|
||||||
}
|
|
||||||
|
|
||||||
# Let us leverage the regex derivative algorithm to define a regex matcher
|
|
||||||
typecheck match_regex : string -> regex -> bool
|
|
||||||
def match_regex str regex =
|
|
||||||
let
|
|
||||||
def match_regex1 <Empty> r = nullable? regex
|
|
||||||
| match_regex1 <Cons c cs> r = match_regex1 cs (derive c cs)
|
|
||||||
in
|
|
||||||
match_regex1 (string_to_list str) regex
|
|
||||||
|
|
@ -175,7 +175,7 @@ static void parse_datatype_constructor(struct parser *p, struct constructor_list
|
||||||
static struct decl *parse_datatype_decl(struct parser *p) {
|
static struct decl *parse_datatype_decl(struct parser *p) {
|
||||||
struct var_list *params = parse_def_var_list(p);
|
struct var_list *params = parse_def_var_list(p);
|
||||||
if (cur_tok(p) != tok_ident) {
|
if (cur_tok(p) != tok_ident) {
|
||||||
report_error(p, "Invalid datatype name `%s`, expected an identifier.\n", token_descr(cur_tok(p)));
|
report_error(p, "Invalid datatype name, expected an identifier.\n");
|
||||||
}
|
}
|
||||||
char *datatype_name = cur_lexeme(p);
|
char *datatype_name = cur_lexeme(p);
|
||||||
consume(p);
|
consume(p);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue