[augeas-devel] augeas: master - * src/lens.h: add a recursive lens combinator

David Lutterkort lutter at fedoraproject.org
Fri Jan 15 01:31:20 UTC 2010


Gitweb:        http://git.fedorahosted.org/git/augeas.git?p=augeas.git;a=commitdiff;h=69304e5edf7713a06f1c8ad1528839d474761c52
Commit:        69304e5edf7713a06f1c8ad1528839d474761c52
Parent:        dd26b7c77331b5beb6e319bc168da05c953443ae
Author:        David Lutterkort <lutter at redhat.com>
AuthorDate:    Fri Dec 18 15:44:44 2009 -0800
Committer:     David Lutterkort <lutter at redhat.com>
CommitterDate: Thu Jan 14 14:48:38 2010 -0800

* src/lens.h: add a recursive lens combinator

---
 src/lens.c |    5 +++--
 src/lens.h |   18 +++++++++++++++++-
 2 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/src/lens.c b/src/lens.c
index 895178e..9f408fc 100644
--- a/src/lens.c
+++ b/src/lens.c
@@ -47,7 +47,7 @@ static struct value *typecheck_maybe(struct info *info, struct lens *l);
 /* Lens names for pretty printing */
 static const char *const tags[] = {
     "del", "store", "key", "label", "seq", "counter", "concat", "union",
-    "subtree", "star", "maybe"
+    "subtree", "star", "maybe", "rec"
 };
 
 static const struct string digits_string = {
@@ -59,7 +59,8 @@ char *format_lens(struct lens *l) {
     char *inf = format_info(l->info);
     char *result;
 
-    xasprintf(&result, "%s[%s]", tags[l->tag - L_DEL], inf);
+    xasprintf(&result, "%s[%s]%s", tags[l->tag - L_DEL], inf,
+              l->recursive ? "R" : "r");
     free(inf);
     return result;
 }
diff --git a/src/lens.h b/src/lens.h
index d378e02..0641fb3 100644
--- a/src/lens.h
+++ b/src/lens.h
@@ -37,7 +37,8 @@ enum lens_tag {
     L_UNION,
     L_SUBTREE,
     L_STAR,
-    L_MAYBE
+    L_MAYBE,
+    L_REC
 };
 
 /* A lens. The way the type information is computed is a little
@@ -49,6 +50,19 @@ enum lens_tag {
  *         can produce, or NULL if no label is produced
  * VTYPE - the 'value' type, matching the value that this lens
  *         can produce, or NULL if no value is produce
+ *
+ * We distinguish between regular and recursive (context-free) lenses. Only
+ * L_REC and the combinators can be marked recursive.
+ *
+ * Types are computed at different times, depending on whether the lens is
+ * recursive or not. For non-recursive lenses, types are computed when the
+ * lens is constructed by one of the LNS_MAKE_* functions; for recursive
+ * lenses, we never compute an explicit ctype (since regular approximations
+ * of it are pretty much useless), we do however compute regular
+ * approximations of the ktype, vtype, and atype in LNS_CHECK_REC. That
+ * means that recursive lenses accept context free languages in the string
+ * -> tree direction, but only regular tree languages in the tree -> string
+ * direction.
  */
 struct lens {
     unsigned int              ref;
@@ -60,6 +74,7 @@ struct lens {
     struct regexp            *vtype;
     unsigned int              value : 1;
     unsigned int              key : 1;
+    unsigned int              recursive : 1;
     unsigned int              consumes_value : 1;
     union {
         /* Primitive lenses */
@@ -73,6 +88,7 @@ struct lens {
             unsigned int nchildren;
             struct lens **children;
         };
+        struct lens *body;          /* L_REC */
     };
 };
 




More information about the augeas-devel mailing list