[augeas-devel] [PATCH 3 of 4] Add subtraction of regular expressions to the language
David Lutterkort
dlutter at redhat.com
Fri May 9 19:59:28 UTC 2008
7 files changed, 89 insertions(+), 5 deletions(-)
src/lexer.l | 2 -
src/parser.y | 13 +++++---
src/regexp.c | 1
src/syntax.c | 46 +++++++++++++++++++++++++++++
src/syntax.h | 1
tests/modules/fail_regexp_minus_empty.aug | 9 +++++
tests/modules/pass_regexp_minus.aug | 22 +++++++++++++
# HG changeset patch
# User David Lutterkort <dlutter at redhat.com>
# Date 1210363161 25200
# Node ID 57b32b999e8beedd1a014553d1b8a49c12f36b55
# Parent a23b4e8f59df90d2a83e30ac0d9bae32cfc30e93
Add subtraction of regular expressions to the language
It is now possible to say something like
let re = /[a-z]+/ - "baseurl"
The '-' operator is only defined between regexps.
diff -r a23b4e8f59df -r 57b32b999e8b src/lexer.l
--- a/src/lexer.l Fri May 09 12:59:20 2008 -0700
+++ b/src/lexer.l Fri May 09 12:59:21 2008 -0700
@@ -90,7 +90,7 @@ ARROW ->
return REGEXP;
}
- [|*?+()=:;\.\[\]{}] return yytext[0];
+ [|*?+()=:;\.\[\]{}-] return yytext[0];
module return KW_MODULE;
let return KW_LET;
diff -r a23b4e8f59df -r 57b32b999e8b src/parser.y
--- a/src/parser.y Fri May 09 12:59:20 2008 -0700
+++ b/src/parser.y Fri May 09 12:59:21 2008 -0700
@@ -68,7 +68,7 @@ typedef struct info YYLTYPE;
}
%type<term> start decls
-%type<term> exp composeexp unionexp catexp appexp rexp aexp
+%type<term> exp composeexp unionexp minusexp catexp appexp rexp aexp
%type<term> param param_list
%type<string> qid id autoload
%type<type> type atype
@@ -188,12 +188,17 @@ composeexp: composeexp ';' unionexp
| unionexp
{ $$ = $1; }
-unionexp: unionexp '|' catexp
+unionexp: unionexp '|' minusexp
{ $$ = make_binop(A_UNION, $1, $3, &@$); }
- | catexp
+ | minusexp
{ $$ = $1; }
| tree_const
{ $$ = make_tree_value($1, &@1); }
+
+minusexp: minusexp '-' catexp
+ { $$ = make_binop(A_MINUS, $1, $3, &@$); }
+ | catexp
+ { $$ = $1; }
catexp: catexp '.' appexp
{ $$ = make_binop(A_CONCAT, $1, $3, &@$); }
@@ -383,7 +388,7 @@ static struct term *make_binop(enum term
struct term *left, struct term *right,
struct info *locp) {
assert(tag == A_COMPOSE || tag == A_CONCAT
- || tag == A_UNION || tag == A_APP);
+ || tag == A_UNION || tag == A_APP || tag == A_MINUS);
struct term *term = make_term_locp(tag, locp);
term->left = left;
term->right = right;
diff -r a23b4e8f59df -r 57b32b999e8b src/regexp.c
--- a/src/regexp.c Fri May 09 12:59:20 2008 -0700
+++ b/src/regexp.c Fri May 09 12:59:21 2008 -0700
@@ -133,6 +133,7 @@ regexp_minus(struct info *info, struct r
}
result = make_regexp(info, s);
+ s = NULL;
done:
fa_free(fa);
diff -r a23b4e8f59df -r 57b32b999e8b src/syntax.c
--- a/src/syntax.c Fri May 09 12:59:20 2008 -0700
+++ b/src/syntax.c Fri May 09 12:59:21 2008 -0700
@@ -191,6 +191,7 @@ static void free_term(struct term *term)
break;
case A_COMPOSE:
case A_UNION:
+ case A_MINUS:
case A_CONCAT:
case A_APP:
case A_LET:
@@ -1096,6 +1097,9 @@ static int check_exp(struct term *term,
case A_UNION:
result = check_binop("union", term, ctx, 2, t_regexp, t_lens);
break;
+ case A_MINUS:
+ result = check_binop("minus", term, ctx, 1, t_regexp);
+ break;
case A_COMPOSE:
result = check_compose(term, ctx);
break;
@@ -1312,6 +1316,45 @@ static struct value *compile_union(struc
return v;
}
+static struct value *compile_minus(struct term *exp, struct ctx *ctx) {
+ struct value *v1 = compile_exp(exp->info, exp->left, ctx);
+ if (EXN(v1))
+ return v1;
+ struct value *v2 = compile_exp(exp->info, exp->right, ctx);
+ if (EXN(v2)) {
+ unref(v1, value);
+ return v2;
+ }
+
+ struct type *t = exp->type;
+ struct info *info = exp->info;
+ struct value *v;
+
+ v1 = coerce(v1, t);
+ v2 = coerce(v2, t);
+ if (t->tag == T_REGEXP) {
+ struct regexp *re1 = v1->regexp;
+ struct regexp *re2 = v2->regexp;
+ struct regexp *re = regexp_minus(info, re1, re2);
+ if (re == NULL) {
+ v = make_exn_value(info,
+ "Regular expression subtraction 'r1 - r2' failed");
+ exn_printf_line(v, "r1: /%s/", re1->pattern->str);
+ exn_printf_line(v, "r2: /%s/", re2->pattern->str);
+ } else {
+ v = make_value(V_REGEXP, ref(info));
+ v->regexp = re;
+ }
+ } else {
+ fatal_error(info, "Tried to subtract a %s and a %s to yield a %s",
+ type_name(exp->left->type), type_name(exp->right->type),
+ type_name(t));
+ }
+ unref(v1, value);
+ unref(v2, value);
+ return v;
+}
+
static struct value *compile_compose(struct term *exp, struct ctx *ctx) {
struct type *t = exp->type;
struct info *info = exp->info;
@@ -1508,6 +1551,9 @@ static struct value *compile_exp(struct
break;
case A_UNION:
v = compile_union(exp, ctx);
+ break;
+ case A_MINUS:
+ v = compile_minus(exp, ctx);
break;
case A_CONCAT:
v = compile_concat(exp, ctx);
diff -r a23b4e8f59df -r 57b32b999e8b src/syntax.h
--- a/src/syntax.h Fri May 09 12:59:20 2008 -0700
+++ b/src/syntax.h Fri May 09 12:59:21 2008 -0700
@@ -59,6 +59,7 @@ enum term_tag {
A_LET, /* local LET .. IN binding */
A_COMPOSE,
A_UNION,
+ A_MINUS,
A_CONCAT,
A_APP,
A_VALUE,
diff -r a23b4e8f59df -r 57b32b999e8b tests/modules/fail_regexp_minus_empty.aug
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/modules/fail_regexp_minus_empty.aug Fri May 09 12:59:21 2008 -0700
@@ -0,0 +1,9 @@
+module Fail_regexp_minus_empty =
+
+ (* This fails since the result of the subtraction is the empty set *)
+ (* which we can not represent as a regular expression. *)
+ let re = "a" - /[a-z]/
+
+(* Local Variables: *)
+(* mode: caml *)
+(* End: *)
diff -r a23b4e8f59df -r 57b32b999e8b tests/modules/pass_regexp_minus.aug
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/modules/pass_regexp_minus.aug Fri May 09 12:59:21 2008 -0700
@@ -0,0 +1,22 @@
+module Pass_regexp_minus =
+
+ let word = /[a-z]+/
+ let no_baseurl = word - "baseurl"
+
+ let eq = del "=" "="
+
+ let l1 = [ key no_baseurl . eq . store /[a-z]+/ ]
+ let l2 = [ key "baseurl" . eq . store /[0-9]+/ ]
+
+ let lns = ((l1 | l2) . del "\n" "\n")*
+
+ test lns get "foo=abc\nbaseurl=123\n" =
+ { "foo" = "abc" }
+ { "baseurl" = "123" }
+
+ test lns get "baseurl=abc\n" = *
+
+
+(* Local Variables: *)
+(* mode: caml *)
+(* End: *)
More information about the augeas-devel
mailing list