]> granicus.if.org Git - flex/commitdiff
Added ccl union operator.
authorJohn Millaway <john43@users.sourceforge.net>
Tue, 28 Mar 2006 20:47:11 +0000 (20:47 +0000)
committerJohn Millaway <john43@users.sourceforge.net>
Tue, 28 Mar 2006 20:47:11 +0000 (20:47 +0000)
Added test in test suite for ccl union operator.
Documented ccl union operator.
Removed crufty ccl cache to prevent parser problems.

ccl.c
doc/flex.texi
flexdef.h
parse.y
scan.l
sym.c
tests/test-ccl/scanner.l
tests/test-ccl/test.input

diff --git a/ccl.c b/ccl.c
index d23611d254c8d454820c299e5f13f63616a409d1..8d66bb62b18f4e0aa6540d9676b2db664e41c6d3 100644 (file)
--- a/ccl.c
+++ b/ccl.c
@@ -151,6 +151,37 @@ ccl_set_diff (int a, int b)
     return d;
 }
 
+/* ccl_set_union - create a new ccl as the set union of the two given ccls. */
+int
+ccl_set_union (int a, int b)
+{
+    int  d, i;
+
+    /* create new class  */
+    d = cclinit();
+
+    /* Add all of a */
+    for (i = 0; i < ccllen[a]; ++i)
+               ccladd (d, ccltbl[cclmap[a] + i]);
+
+    /* Add all of b */
+    for (i = 0; i < ccllen[b]; ++i)
+               ccladd (d, ccltbl[cclmap[b] + i]);
+
+    /* debug */
+    if (0){
+        fprintf(stderr, "ccl_set_union (%d + %d = %d", a, b, d);
+            fprintf(stderr, "\n    ");
+            dump_cclp (stderr, a);
+            fprintf(stderr, "\n    ");
+            dump_cclp (stderr, b);
+            fprintf(stderr, "\n    ");
+            dump_cclp (stderr, d);
+        fprintf(stderr, "\n)\n");
+    }
+    return d;
+}
+
 
 /* cclinit - return an empty ccl */
 
index 04aff51d5fdd946b40dcd489ffb2beaf8e4d7e20..54be0731f770a8a447014e68bf5ccdfdf2178345 100644 (file)
@@ -997,6 +997,13 @@ just the single character @samp{a}). The @samp{@{-@}} operator is left
 associative, so @samp{[abc]@{-@}[b]@{-@}[c]} is the same as @samp{[a]}. Be careful
 not to accidently create an empty set, which will never match.
 
+@item
+
+The @samp{@{+@}} operator computes the union of two character classes. For
+example, @samp{[a-z]@{+@}[0-9]} is the same as @samp{[a-z0-9]}. This operator
+is useful when preceded by the result of a difference operation, as in,
+@samp{[[:alpha:]]@{-@}[[:lower:]]@{+@}[q]}, which is equivalent to
+@samp{[A-Zq]} in the "C" locale.
 
 @cindex trailing context, limits of
 @cindex ^ as non-special character in patterns
index 413657811c13cc16845f311a031b3cb7f76f5016..2b3b7601d699de20754a54e46879a9f78aa25729 100644 (file)
--- a/flexdef.h
+++ b/flexdef.h
@@ -725,6 +725,7 @@ extern void ccladd PROTO ((int, int));      /* add a single character to a ccl */
 extern int cclinit PROTO ((void));     /* make an empty ccl */
 extern void cclnegate PROTO ((int));   /* negate a ccl */
 extern int ccl_set_diff (int a, int b); /* set difference of two ccls. */
+extern int ccl_set_union (int a, int b); /* set union of two ccls. */
 
 /* List the members of a set of characters in CCL form. */
 extern void list_character_set PROTO ((FILE *, int[]));
diff --git a/parse.y b/parse.y
index e66deb85b1cd63635d0cc318f9dc25cf03609a08..251cc721f73132feb43a93b32dd033f1e04c557e 100644 (file)
--- a/parse.y
+++ b/parse.y
@@ -10,7 +10,7 @@
 %token CCE_NEG_ALNUM CCE_NEG_ALPHA CCE_NEG_BLANK CCE_NEG_CNTRL CCE_NEG_DIGIT CCE_NEG_GRAPH
 %token CCE_NEG_LOWER CCE_NEG_PRINT CCE_NEG_PUNCT CCE_NEG_SPACE CCE_NEG_UPPER CCE_NEG_XDIGIT
 
-%left CCL_OP_DIFF
+%left CCL_OP_DIFF CCL_OP_UNION
 
 /*
  *POSIX and AT&T lex place the
@@ -760,7 +760,6 @@ singleton   :  singleton '*'
 
                |  fullccl
                        {
-                       if ( ! cclsorted )
                                /* Sort characters for fast searching.  We
                                 * use a shell sort since this list could
                                 * be large.
@@ -810,7 +809,8 @@ singleton   :  singleton '*'
                        }
                ;
 fullccl:
-        fullccl CCL_OP_DIFF braceccl  { $$ = ccl_set_diff ($1, $3); }
+        fullccl CCL_OP_DIFF  braceccl  { $$ = ccl_set_diff  ($1, $3); }
+    |   fullccl CCL_OP_UNION braceccl  { $$ = ccl_set_union ($1, $3); }
     |   braceccl
     ;
 
diff --git a/scan.l b/scan.l
index 5af40a75e8f827ea9cff32789484d8954012a61c..e06279fc6c9a60fc5a0a362fd572dbb14244e403 100644 (file)
--- a/scan.l
+++ b/scan.l
@@ -621,7 +621,12 @@ M4QEND      "]]"
                        /* Check to see if we've already encountered this
                         * ccl.
                         */
-                       if ( (cclval = ccllookup( (Char *) nmstr )) != 0 )
+                       if (0 /* <--- This "0" effectively disables the reuse of a
+                   * character class (purely based on its source text).
+                   * The reason it was disabled is so yacc/bison can parse
+                   * ccl operations, such as ccl difference and union.
+                   */
+                &&  (cclval = ccllookup( (Char *) nmstr )) != 0 )
                                {
                                if ( input() != ']' )
                                        synerr( _( "bad character class" ) );
@@ -647,6 +652,7 @@ M4QEND      "]]"
                                }
                        }
     "{-}"       return CCL_OP_DIFF;
+    "{+}"       return CCL_OP_UNION;
 
 
     /* Check for :space: at the end of the rule so we don't
diff --git a/sym.c b/sym.c
index 7aecae99763b534f99f0c3e44e8dc0fbbde02948..8d0b2e9e6f683f8a9a84424b6c2289060fba5182 100644 (file)
--- a/sym.c
+++ b/sym.c
@@ -168,7 +168,6 @@ static struct hash_entry *findsym (sym, table, table_size)
        return &empty_entry;
 }
 
-
 /* hashfunct - compute the hash value for "str" and hash size "hash_size" */
 
 static int hashfunct (str, hash_size)
index 914795c1bd5472ad6103862a0b2aae69f9df080c..330278a7234ff644cc25d48c755cecffd7dadef5 100644 (file)
 ^"abcd-bc:"([abcd]{-}[bc])+@abcd-bc@\n          printf("OK: %s", yytext); ++yylineno; return 1;
 ^"abcde-b-c:"([abcde]{-}[b]{-}[c])+@abcde-b-c@\n    printf("OK: %s", yytext); ++yylineno; return 1;
 ^"^XY-^XYZ:"([^XY]{-}[^XYZ])+@^XY-^XYZ@\n    printf("OK: %s", yytext); ++yylineno; return 1;
+
+^"a+d:"([[:alpha:]]{+}[[:digit:]])+"@a+d@"\n    a_ok();
+^"a-u+Q:"([[:alpha:]]{-}[[:upper:]]{+}[Q])+"@a-u+Q@"\n    a_ok();
+
 ^"ia:"(?i:a)+@ia@\n                          printf("OK: %s", yytext); ++yylineno; return 1;
 ^"iabc:"(?i:abc)+@iabc@\n                    printf("OK: %s", yytext); ++yylineno; return 1;
 ^"ia-c:"(?i:[a-c]+)@ia-c@\n                             printf("OK: %s", yytext); ++yylineno; return 1;
index f38b4d6a698c54f2652509c77e55fe35c79b2ca6..b318fe6f874769840b635cfa923aff85aca42fe3 100644 (file)
@@ -13,6 +13,8 @@ l-xyz:abcdefghijklmnopqrstuvw@l-xyz@
 abcd-bc:aaaaddddaaaa@abcd-bc@
 abcde-b-c:aaaaddddeeee@abcde-b-c@
 ^XY-^XYZ:ZZZZZZZZZZZ@^XY-^XYZ@
+a+d:abc0123xyz789@a+d@
+a-u+Q:abcQQQQxyz@a-u+Q@
 ia:AaAa@ia@
 iabc:ABCabcAbCaBc@iabc@
 ia-c:ABCabcAbCaBc@ia-c@