]> granicus.if.org Git - icu/commitdiff
ICU-10723 delete C++ RandomCollatorTest
authorMarkus Scherer <markus.icu@gmail.com>
Wed, 26 Feb 2014 19:33:44 +0000 (19:33 +0000)
committerMarkus Scherer <markus.icu@gmail.com>
Wed, 26 Feb 2014 19:33:44 +0000 (19:33 +0000)
X-SVN-Rev: 35238

icu4c/source/test/intltest/rndmcoll.cpp [deleted file]
icu4c/source/test/intltest/rndmcoll.h [deleted file]
icu4c/source/test/intltest/tscoll.cpp
icu4c/source/test/intltest/wbnf.cpp [deleted file]
icu4c/source/test/intltest/wbnf.h [deleted file]

diff --git a/icu4c/source/test/intltest/rndmcoll.cpp b/icu4c/source/test/intltest/rndmcoll.cpp
deleted file mode 100644 (file)
index be15570..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- ******************************************************************************
- * Copyright (C) 2005-2007, International Business Machines Corporation and   *
- * others. All Rights Reserved.                                               *
- ******************************************************************************
- */
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <time.h>
-#include "rndmcoll.h"
-#include "wbnf.h"
-
-
-#if !UCONFIG_NO_COLLATION
-
-//Raymond: Following comments are copied from Java implementation
-//
-// each rule can be:
-//      "[" command "]"
-//      "& [" position "]"
-//      "&" before chars
-//      relation "[variable top]"
-//      relation (chars "|")? chars ("/" chars)?
-// plus, a reset must come before a relation
-
-
-static const char collationBNF[] =
-    "$s = ' '? 50%;" 
-    "$crlf = '\r\n';" 
-
-    "$alternateOptions = non'-'ignorable | shifted;" 
-    "$onoff = on | off;" 
-    "$caseFirstOptions = off | upper | lower;" 
-    "$strengthOptions = '1' | '2' | '3' | '4' | 'I';" 
-    "$commandList = '['"
-    " ( alternate ' ' $alternateOptions"
-    " | backwards' 2'"
-    " | normalization ' ' $onoff "
-    " | caseLevel ' ' $onoff "
-    " | hiraganaQ ' ' $onoff"
-    " | caseFirst ' ' $caseFirstOptions"
-    " | strength ' ' $strengthOptions"
-    " ) ']';" 
-    "$command = $commandList $crlf;" 
-
-    "$ignorableTypes = (tertiary | secondary | primary) ' ' ignorable;" 
-    "$allTypes = variable | regular | implicit | trailing | $ignorableTypes;" 
-    "$positionList = '[' (first | last) ' ' $allTypes ']';"
-
-    "$beforeList = '[before ' ('1' | '2' | '3') ']';"
-
-    "$relationList = ("
-    "   '<'"
-    " | '<<'"
-    " | ';'" 
-    " | '<<<'"
-    " | ','" 
-    " | '='"
-    ");"
-    "$string = $chars{1,5}~@;" 
-    "$chars = a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z| '<'| '&'| '['| ']';"
-    "$rel1 = '[variable top]' $s;" 
-    "$p1 = ($string $s '|' $s)? 25%;" 
-    "$p2 = ('/' $s $string $s)? 25%;" 
-    "$rel2 = $p1 $string $s $p2;" 
-    "$relation = $relationList $s ($rel1 | $rel2) $crlf;" 
-
-    "$reset = '&' $s ($beforeList $s)? 10% ($positionList 1% | $string 10%) $crlf;" 
-    "$mostRules = $command 1% | $reset 5% | $relation 25%;"
-    "$root = $command{0,5} $reset $mostRules{1,20};";
-
-
-void RandomCollatorTest::Test2(){
-    // See ticket 5747 about reenabling this test.
-    errln("TestWbnf is incorrectly implemented.\nThis test should be modeled to use the existing test frame work for naming tests.\n");
-    TestWbnf();
-}
-
-
-void RandomCollatorTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* ){
-    if (exec) logln("TestSuite RandomCollatorTest: ");
-    switch (index) {
-        TESTCASE(0, Test);
-        TESTCASE(1, Test2);
-        default: name = ""; break;
-    }
-}
-
-/*
-class TestColltorCompare{
-public:
-    UBool operator()(Collator &coll, int count = 1000){
-        UnicodeString a(test_string.get_a_string());
-        UnicodeString b(test_string.get_a_string());
-        UnicodeString c(test_string.get_a_string());
-        do{
-            if (check_transitivity(coll, a, b, c)){
-                a = b;
-                b = c;
-                c = UnicodeString(test_string.get_a_string());
-            }
-        }while(count-- >= 0 );
-
-        return FALSE;
-    }
-    TestColltorCompare():test_string("$s = $c{1,8};", "$s", "$c", new Magic_SelectOneChar("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ[]&<")){
-    }
-private:
-    UBool check_transitivity(const Collator & coll, const UnicodeString &a, const UnicodeString &b, const UnicodeString &c){
-        int ab = coll.compare(a,b), ba = coll.compare(b,a);
-        int bc = coll.compare(b,c), cb = coll.compare(c,b);
-        int ca = coll.compare(c,a), ac = coll.compare(a,c);
-        //       a
-        //      / \ 
-        //     b - c
-        //
-        if (//counter-clockwise, maximum
-              (ab >=0 && bc >=0 && ac <0)
-            ||(bc >=0 && ca >=0 && ba <0)
-            ||(ca >=0 && ab >=0 && cb <0)
-
-            //counter-clockwise, minimum
-            ||(ab <=0 && bc <=0 && ca >0)
-            ||(bc <=0 && ca <=0 && ba >0)
-            ||(ca <=0 && ab <=0 && cb >0)
-            ){
-                return FALSE;
-            }
-          return TRUE;
-    }
-
-    LanguageGenerator test_string;
-};*/
-
-void RandomCollatorTest::Test(){
-    // See ticket 5747 about reenabling this test.
-    errln("This test needs to be fixed.\n");
-
-    LanguageGenerator test_rule;
-    if (test_rule.parseBNF(collationBNF, "$root", TRUE) != LanguageGenerator::OK){
-        errln("The test code itself is wrong.");
-        return;
-    };
-
-    //TestColltorCompare coll_test;
-
-    static const int CONSTRUCT_RANDOM_COUNT = 1000;
-    int i;
-    for (i=0; i < CONSTRUCT_RANDOM_COUNT; i++){
-        const char * rule = test_rule.next();
-        logln("\n-----------------------------------%d\n",i);
-        logln(UnicodeString(rule, strlen(rule)));
-
-        UnicodeString newRule(rule);    // potential bug
-        UErrorCode status = U_ZERO_ERROR;
-        logln(   "===========================================\n");
-        fwrite(rule, strlen(rule),1,stdout);
-        logln("\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n");
-
-        Collator * c = new RuleBasedCollator(newRule,status);
-
-        if (U_FAILURE(status)) {
-            errln( "Could not create Collator for the %d(th) generated rule.\n"
-                   "Error Name: %s\n"
-                   "The rule is ",
-                   i, u_errorName(status));
-            return;
-        }
-
-        delete c;
-    }
-}
-
-#endif /* #if !UCONFIG_NO_COLLATION */
-
diff --git a/icu4c/source/test/intltest/rndmcoll.h b/icu4c/source/test/intltest/rndmcoll.h
deleted file mode 100644 (file)
index d216af3..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/********************************************************************
- * COPYRIGHT: 
- * Copyright (c) 2005-2006, International Business Machines Corporation and
- * others. All Rights Reserved.
- ********************************************************************/
-
-/**
- * RandomCollatorTest is ported from RandomCollatorTest.java of ICU4J
- */
-
-#ifndef _RANDCOLL
-#define _RANDCOLL
-
-#include "unicode/utypes.h"
-
-#if !UCONFIG_NO_COLLATION
-
-#include "tscoll.h"
-
-class RandomCollatorTest: public IntlTestCollator {
-public:
-    virtual void runIndexedTest( int32_t index, UBool exec, const char* &name, char* par = NULL );
-    void Test();
-    void Test2();
-};
-
-#endif /* #if !UCONFIG_NO_COLLATION */
-
-#endif /* _RANDCOLL */ 
index 6e29105804321815f6854dc9a5a08b87ac319cfb..8b1c43c523a98b905292a3e652f651f8c002efb1 100644 (file)
@@ -80,7 +80,6 @@ void IntlTestCollator::runIndexedTest( int32_t index, UBool exec, const char* &n
     TESTCASE_AUTO_CLASS(UCAConformanceTest);
     TESTCASE_AUTO_CLASS(CollationServiceTest);
     TESTCASE_AUTO_CLASS(CollationFinnishTest); // removed by weiv - we have changed Finnish collation
-      //TESTCASE_AUTO_CLASS(RandomCollatorTest); // See ticket 5747 about reenabling this test.
     TESTCASE_AUTO_CLASS(SSearchTest);
 #if !UCONFIG_NO_NORMALIZATION
     TESTCASE_AUTO_CLASS(AlphabeticIndexTest);
diff --git a/icu4c/source/test/intltest/wbnf.cpp b/icu4c/source/test/intltest/wbnf.cpp
deleted file mode 100644 (file)
index 7d08de7..0000000
+++ /dev/null
@@ -1,1771 +0,0 @@
-/*
- ******************************************************************************
- * Copyright (C) 2005-2007, International Business Machines Corporation and   *
- * others. All Rights Reserved.                                               *
- ******************************************************************************
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <time.h>
-
-#include "wbnf.h"
-    
-// Most of this code is meant to test the test code. It's a self test.
-// Normally this isn't run.
-#define TEST_WBNF_TEST 0
-
-///////////////////////////////////////////////////////////
-//
-// Constants and the most basic helper classes
-//
-    
-static const char DIGIT_CHAR[] = "0123456789";
-static const char WHITE_SPACE[] = {'\t', ' ', '\r', '\n', 0};
-static const char ALPHABET[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
-static const char SPECIAL[] = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~";
-
-static inline UBool isInList(const char c /*in*/, const char list[] /*in*/){
-    const char * p = list;
-    for (;*p != 0 && *p != c; p++);
-    return *p?TRUE:FALSE;
-}
-static inline UBool isDigit(char c) {return isInList(c, DIGIT_CHAR);}
-static inline UBool isWhiteSpace(char c) {return isInList(c, WHITE_SPACE);}
-static inline UBool isAlphabet(char c) {return isInList(c, ALPHABET);}
-static inline UBool isSpecialAsciiChar(char c) {return isInList(c,SPECIAL);}
-
-    
-
-///////////////////////////////////////////////////////////
-//
-// Helper classes
-//
-    
-class Buffer_byte{
-// Utility class, can be treated as an auto expanded array. no boundary check.
-
-    typedef char byte;
-    byte * start;
-    byte * current;
-    int buffer_size; // size unit is byte
-public:
-    inline int content_size(){return current - start;} // size unit is byte
-
-private:
-    inline void expand(int add_size = 100){ // size unit is byte
-        int new_size = buffer_size + add_size;
-
-        int cs_snap = content_size();         
-        start = (byte *) realloc(start, new_size);   // may change the value of start
-        current = start + cs_snap;
-
-        memset(current, 0, add_size);
-        buffer_size = new_size;
-    }
-
-    inline void expand_to(int size){
-        int r = size - buffer_size;
-        if (r > 0) {
-            expand(r);  // simply expand, no block alignment
-        }
-    }
-    Buffer_byte(const Buffer_byte &);
-    Buffer_byte & operator = (const Buffer_byte &);
-public:
-    Buffer_byte():start(NULL),current(start),buffer_size(0){
-        expand();
-    }
-    ~Buffer_byte(){
-        free(start);
-    }
-
-    inline void reset(){
-        start != NULL ? memset(start, 0, buffer_size) : 0;
-        current = start;
-    }
-
-    // Using memory copy method to append a C array to buffer, 
-    inline void append(const void * c, int size){ // size unit is byte
-        expand_to(content_size() + size) ;
-        memcpy(current, c, size);
-        current = current + size;
-    }
-    
-    byte * buffer(){
-        return start;
-    }
-};
-    
-/*
-  The class(es) try to work as bulid-in array, so it overloads these two operators
-    operator type *();
-    type & operator[];
-  The first is used to auto type convert, the latter is used to select member.
-
-  A small trick is the class does not overload the address-of operator. This 
-  behavior is different from bulid-in array, but it give us the opportunity 
-  to get the address of the class itself.
-*/
-//template<typename type>
-//    class BUFFER{
-//       typedef BUFFER name;
-#define BUFFER(type, name)\
-    class name {\
-    private:\
-       Buffer_byte buf;\
-    public:\
-        name & reset() {buf.reset(); return *this;}\
-        name & append(type c) {buf.append(&c, sizeof(type)); return *this;}\
-        name & append_array(const type * p, int size) {buf.append(p, sizeof(type)*size); return *this;}\
-        type & operator [] (int i) { return ((type *) buf.buffer())[i];}\
-        operator type *(){return (type *) buf.buffer();} \
-        int content_size(){return buf.content_size() / sizeof(type);}\
-    }
-    
-
-class Pick{
-/* The Pick is the basic language generator element*/
-public:
-    // generate a string accroding the syntax 
-    // Return a null-terminated c-string. The buffer is owned by callee.
-    virtual const char* next() = 0; 
-    virtual ~Pick(){};
-};
-
-//typedef BUFFER<char> Buffer_char;
-//typedef BUFFER<int> Buffer_int;
-//typedef BUFFER<Pick *> Buffer_pPick;
-BUFFER(char, Buffer_char);
-BUFFER(int, Buffer_int);
-BUFFER(Pick *, Buffer_pPick);
-
-class SymbolTable{
-/* Helper class.
-* It's a mapping table between 'variable name' and its 'active Pick object'
-*/
-private:
-    Buffer_char  name_buffer;   // var names storage space
-
-    Buffer_int   names;         // points to name (offset in name_buffer)
-    Buffer_pPick refs;          // points to Pick
-
-    int get_index(const char *const var_name){
-        int len = names.content_size();
-        for (int i=0; i< len; i++){
-            if (strcmp(var_name, name_buffer + names[i]) == 0){
-                return i;
-            }
-        }
-        return -1;
-    }
-
-public:
-    enum RESULT {EMPTY, NO_VAR, NO_REF, HAS_REF};
-
-    RESULT find(const char *const var_name /*[in] c-string*/, Pick * * ref = NULL /*[out] Pick* */){
-        if (!var_name) return EMPTY; // NULL name
-
-        int i = get_index(var_name);
-        if (i == -1){
-            return NO_VAR;   // new name
-        }
-        if (!refs[i]){  // exist name, no ref
-            return NO_REF;
-        } else {
-            if (ref) {
-                *ref = refs[i];
-            }
-            return HAS_REF;   // exist name, has ref
-        }
-    }
-
-    void put(const char *const var_name, Pick *const var_ref = NULL){
-        int i = get_index(var_name);
-        switch(find(var_name)){
-            case EMPTY:    // NULL name
-                break;
-            case NO_VAR:    // new name
-                int offset;
-                offset = name_buffer.content_size();
-                name_buffer.append_array(var_name, strlen(var_name) + 1);
-                names.append(offset);
-                refs.append(var_ref);
-                break;
-            case NO_REF:    // exist name, no ref
-                refs[i] = var_ref;    // link definition with variable
-                break;
-            case HAS_REF:    // exist name, has ref
-                if (var_ref){
-                    refs[i] = var_ref;
-                }
-                break;
-            default:
-                ; // ASSERT(FALSE);
-        }
-        return;
-    }
-
-    UBool is_complete(){
-        int n = names.content_size();
-        for (int i=0; i<n; ++i){
-            if (refs[i] == NULL){
-                return FALSE;
-            }
-        }
-        return TRUE;
-    }
-
-    void reset(){
-        names.reset();
-        name_buffer.reset();
-
-        // release memory here
-        int s = refs.content_size();
-        for (int i=0; i < s; i++){
-            delete refs[i]; // TOFIX: point alias/recursion problem
-        }
-        refs.reset();
-    }
-
-    ~SymbolTable(){
-        reset();
-    }
-};
-
-
-/*
-// Document of class Escaper
-//
-// ATTENTION: 
-// From http://icu-project.org/userguide/Collate_Customization.html.
-// We get the precedence of escape/quote operations
-//
-//     (highest) 1. backslash               \
-//               2. two single quotes       ''
-//               3. quoting                 ' '
-//
-// ICU Collation should accept following as the same string.
-//
-// 1)  'ab'c        _
-// 2)  a\bc          \
-// 3)  a'b'\c        |- They are equal.
-// 4)  abc          _/
-//
-// From "two single quotes", we have following deductions
-//    D1. empty quoting is illgal. (obviously)
-//    D2. no contact operation between two quotings   
-//              '.''.'      is not ..   it is .'.
-//    D3. "two single quotes" cannot contact two quoting simultaneously
-//              '..''''.'   is not ..'. it is ..''.
-//       NOTICE:
-//        "two single quotes" can contact before one quoting
-//              '''.'       is '.
-//        "two single quotes" can literally contact after one quoting
-//        But, from syntax, it's one quoting including a "two single quotes"
-//              '.'''       is .'
-//    D4. "two single quotes" cannot solely be included in quoting
-//              ''''        is not '    it is ''
-//       NOTICE:  These are legal
-//              '.''.'      is .'.
-//              '.'''       is .'
-//
-//                 dicision
-//                    /\
-//                   /__\
-//      output buffer    input buffer
-// 
-// To make our dicision (within an atom operation) without caring input and output buffer,
-// following calling pattern (within an atom operation) shall be avoided
-//
-//    P1 open_quoting()  then close_quoting()    (direct violation)   D1
-//    P2 close_quoting() then open_quoting()     (direct violation)   D2
-//    P3 empty open_quoting()                    (indirect violation) D1, D4
-//    P4 empty close_quoting()                   (indirect violation) D2, D3
-//    P5 open_quoting()  then two single quotes  (indirect violation) D4
-//    P6 close_quoting() then two single quotes  (indirect violation) D3
-//
-// two single quotes escaping will not open_ or close_ quoting()
-// The choice will not lose some quoing forms.
-//
-// For open_quoting(), 
-// we may get this form quoting     '''         P5
-// It may raise a bug               ''''x
-// If we expect
-//      '''.'       let the next char open the quoting
-//      '.''.'      the quoting is already opened by preceding char
-//
-// For close_quoting()
-// we will get this form quoting    '.'''       P6
-// It may raise a bug               '.''''.'
-// If we expect          
-//      '.'''\.     let the next char close the quoting
-//      '.''''.'    the expectation is wrong!  using  '.'\''.' instead
-//
-// It's a hard work to re-adjust generation opportunity for various escaping form.
-// We just simply ignore it.
-*/
-class Escaper{
-public:
-    enum CHOICE {YES, NO, RAND};
-    enum ESCAPE_FORM {BSLASH_ONLY, QUOTE_ONLY, QUOTE_AND_BSLAH, RAND_ESC};
-private:
-    class Bool{ // A wrapper class for CHOICE, to auto adapter UBool class
-        private:
-            const CHOICE tag;
-        public:
-            Bool(CHOICE flag=RAND):tag(flag){}
-            operator UBool() {   // conversion operator
-                return tag == RAND ? rand()%2 : tag == YES;
-                //if (tag == RAND){
-                //    return rand()%2 == 1;
-                //} else {
-                //    return tag == YES ? TRUE : FALSE;
-                //}
-            }
-    };
-public:
-    Escaper(CHOICE escapeLiteral = RAND,
-        CHOICE twoQuotesEscape = RAND,
-        ESCAPE_FORM escapeForm = RAND_ESC):
-        escape_form(escapeForm),
-        escape_literal(escapeLiteral),
-        two_quotes_escape(twoQuotesEscape),
-        is_quoting(FALSE){}
-private:
-    Buffer_char str;
-    ESCAPE_FORM escape_form;
-    Bool escape_literal;
-    Bool two_quotes_escape;
-    UBool quote_escape;
-    UBool bslash_escape;
-    UBool is_quoting;
-
-    void set_options(){
-        ESCAPE_FORM t = escape_form == RAND_ESC ? (ESCAPE_FORM) (rand()%3) : escape_form;
-        switch (t){
-                case BSLASH_ONLY :
-                    bslash_escape = TRUE; quote_escape = FALSE; break;
-                case QUOTE_ONLY:
-                    bslash_escape = FALSE;quote_escape = TRUE;  break;
-                case QUOTE_AND_BSLAH:
-                    bslash_escape = TRUE; quote_escape = TRUE;  break;
-                default:
-                    ;// error
-        }
-    }
-
-    void reset(){
-        str.reset();
-        is_quoting = FALSE;
-    }
-
-    inline void open_quoting(){ 
-        if(is_quoting){
-            // do nothing
-        } else {
-            str.append('\'');
-            is_quoting = TRUE;
-        }
-    }
-    inline void close_quoting(){
-        if(is_quoting){
-            str.append('\'');
-            is_quoting = FALSE;
-        } else {
-            // do nothing
-        }
-    }
-
-    // str  [in]    null-terminated c-string
-    void append(const char * strToAppend){
-        for(;*strToAppend != 0; strToAppend++){
-            append(*strToAppend);
-        }
-    }
-
-    inline void append(const char c){
-        set_options();
-
-        if (c == '\\'){
-            quote_escape ? open_quoting() : close_quoting();
-            //bslash_escape always true here
-            str.append('\\');
-            str.append('\\');
-        } else if (c == '\''){
-            if (two_quotes_escape){     // quoted using two single quotes
-                // See documents in anonymous.design
-                str.append('\'');
-                str.append('\'');
-            } else{
-                quote_escape ? open_quoting() : close_quoting();
-                //bslash_escape always true here
-                str.append('\\');
-                str.append('\'');
-            }
-        } else if (isSpecialAsciiChar(c) || isWhiteSpace(c)){
-            quote_escape  ? open_quoting()   : close_quoting();
-            if (bslash_escape) str.append('\\');
-            str.append(c);
-        } else { //if (isAlphabet(c) || isDigit(c) || TRUE){ // treat others as literal
-            if (escape_literal){
-                quote_escape  ? open_quoting()   : close_quoting();
-                if (bslash_escape)  str.append('\\');
-                str.append(c);
-            } else {
-                close_quoting();
-                str.append(c);
-            }
-        }
-    }
-
-public:
-    // Return a null-terminate c-string. The buffer is owned by callee.
-    char * operator()(const char * literal /*c-string*/){
-        str.reset();
-        for(;*literal != 0; literal++){
-            append(*literal);
-        }
-        close_quoting();    // P4 exception, to close whole quoting
-        return str;
-    }
-};
-    
-class WeightedRand{
-// Return a random number in [0, size)
-// Every number has different chance (aka weight) to be selected.
-private:
-    Buffer_int weights;
-    double total;
-    WeightedRand(const WeightedRand &);
-    WeightedRand & operator = (const WeightedRand &);
-public:
-    WeightedRand(Buffer_int * weight_list = NULL, int size = 0){
-        if ( weight_list == NULL){
-            for (int i=0; i<size; ++i) weights.append(DEFAULT_WEIGHT);
-        } else {
-            int s = weight_list->content_size();
-            if (s < size){
-                weights.append_array( (*weight_list),s);
-                for (int i=s; i<size; ++i) weights.append(DEFAULT_WEIGHT);
-            } else { // s >= size
-                weights.append_array( (*weight_list),size);
-            }
-        }
-        total = 0;
-        int c = weights.content_size();
-        for (int i=0; i<c; ++i){
-            total += weights[i];
-        }
-    }
-
-    void append(int weight){
-        weights.append(weight);
-        total += weight;
-    }
-
-    // Give a random number with the consideration of weight.
-    // Every random number is associated with a weight.
-    // It identifies the chance to be selected, 
-    // larger weight has more chance to be selected.
-    //
-    //
-    //  ______________________   every slot has equal chance
-    //
-    //  [____][_][___][______]   each item has different slots, hence different chance
-    //
-    //
-    //  The algorithms to generate the number is illustrated by preceding figure.
-    //  First, a slot is selected by rand(). Then we translate the slot to corresponding item.
-    //
-    int next(){
-        // get a random in [0,1]
-        double reference_mark = (double)rand() / (double)RAND_MAX;
-
-        // get the slot's index, 0 <= mark <= total;
-        double mark = total * reference_mark;
-
-        // translate the slot to corresponding item
-        int i=0;
-        for (;;){
-            mark -= weights[i];  // 0 <= mark <= total
-            if (mark <= 0)
-                break;
-            i++;
-        }
-        return i;
-    }
-};
-    
-///////////////////////////////////////////////////////////
-//
-// The parser result nodes
-//
-    
-class Literal : public Pick {
-public:
-    virtual const char* next(){
-        return str;
-    }
-    Literal(const char * s /*c-string*/){
-        str.append_array(s, strlen(s) + 1);
-    }
-private:
-    Buffer_char str; //null-terminated c-string
-};
-
-class Variable : public Pick {
-public:
-    Variable(SymbolTable * symbols, const char * varName, Pick * varRef = NULL){
-        this->var_name.append_array(varName, strlen(varName) + 1);
-        if ((symbol_table = symbols)){
-            symbol_table->put(varName, varRef);
-        }
-    }
-
-    operator const char *(){
-        return var_name;
-    }
-
-    virtual const char* next(){
-        if (symbol_table){
-            Pick * var_ref = NULL;
-            symbol_table->find(var_name, &var_ref);
-            if (var_ref) {
-                return var_ref->next();
-            }
-        }
-        return "";  // dumb string
-    }
-private:
-    Buffer_char var_name;
-    SymbolTable * symbol_table;
-};
-
-class Quote : public Pick{
-public:
-    Quote(Pick & base):item(base),e(Escaper::NO, Escaper::NO, Escaper::BSLASH_ONLY){
-    }
-    virtual const char* next(){
-        return e(item.next());
-    }
-private:
-    Pick & item;
-    Buffer_char str;
-    Escaper e;
-};
-
-
-class Morph : public Pick{
-/*
-The difference between morph and an arbitrary random string is that 
-a morph changes slowly. When we build collation rules, for example, 
-it is a much better test if the strings we use are all in the same 
-'neighborhood'; they share many common characters.
-*/
-public:
-    Morph(Pick & base):item(base){}
-
-    virtual const char* next(){
-        current.reset();
-        const char * s = item.next();
-        current.append_array(s, strlen(s) + 1);
-        if  (last.content_size() == 0) {
-            str.reset();
-            last.reset();
-            str.append_array(current, current.content_size());
-            last.append_array(current, current.content_size());
-        } else {
-            morph();
-        }
-        return str;
-    }
-private:
-    Pick & item;
-    Buffer_char str;
-    Buffer_char last;
-    Buffer_char current;
-
-    char * p_last;
-    char * p_curr;
-
-    void copy_curr(){
-        if (*p_curr) {
-            str.append(*p_curr);
-            p_curr++;
-        }
-    }
-
-    void copy_last(){
-        if (*p_last) {
-            str.append(*p_last);
-            p_last++;
-        }
-    }
-
-    // copy 0, 1, or 2 character(s) to str
-    void copy(){
-        static WeightedRand wr(& Buffer_int().append(DEFAULT_WEIGHT * 10), 5);
-
-        switch (wr.next()){
-            case 0: // copy last  -- has 10 times chance than others
-                copy_last();
-                break;
-            case 1: // copy both
-                copy_curr();
-                copy_last();
-                break;
-            case 2: // copy both
-                copy_last();
-                copy_curr();
-                break;
-            case 3:
-                copy_curr();
-                break;
-            case 4:  // copy nothing
-                break;
-            default:
-                // ASSERT(FALSE);
-                ;
-        }
-    }
-
-    void morph(void){
-        int min = strlen(last);
-        int max = strlen(current);
-        if (min > max){
-            int temp  = min;
-            min = max;
-            max = temp;
-        }
-
-        int len = min + rand()%(max - min + 1); // min + [0, diff]
-        p_curr = current;
-        p_last = last;
-        str.reset();
-
-        for (; str.content_size()<len && *p_curr && *p_last;){
-            copy(); // copy 0, 1, or 2 character(s) to str
-        }
-
-        if (str.content_size() == len) {
-            str.append(0);
-            final();
-            return;
-        }
-
-        if (str.content_size() > len) { // if the last copy copied two characters
-            str[len]=0;
-            final();
-            return;
-        }
-
-        // str.content_size() < len
-        if (*p_last) {
-            for (; str.content_size() < len; copy_last());
-        } else if (*p_curr){
-            for (; str.content_size() < len; copy_curr());
-        }
-
-        int last_len = last.content_size();
-        for (;str.content_size() < len;){
-            str.append(last[rand()%last_len]);
-        }
-        str.append(0);
-        final();
-    }
-
-    void final(){
-        last.reset();
-        last.append_array(current, current.content_size());
-    }
-};
-
-class Sequence : public Pick {
-public:
-    virtual const char* next(){
-        str.reset();
-        int s = items.content_size();
-        for(int i=0; i < s; i++){
-            const char * t = items[i]->next();
-            str.append_array(t, strlen(t));
-        }
-        str.append(0); // terminal null
-        return str;
-    }
-
-    void append (Pick * node){
-        items.append(node);
-    }
-
-    virtual ~Sequence(){
-        int s = items.content_size();
-        for(int i=0; i < s; i++){
-            //How can assure the item is got from heap?
-            //Let's assume it.
-            delete items[i]; // TOFIX: point alias/recursion problem
-            items[i] = NULL;
-        }
-    }
-private:
-    Buffer_pPick items;
-    Buffer_char  str; //null-terminated c-string
-};
-
-class Repeat : public Pick {
-private:
-    Pick * item;
-    Buffer_char str;
-    WeightedRand wr;
-    int min;
-    int max;
-    int select_a_count(){
-        return min + wr.next();
-    }
-public:
-    virtual const char* next(){
-        str.reset();
-        int c = select_a_count();
-        for(int i=0; i< c; i++){
-            const char * t = item->next();
-            str.append_array(t, strlen(t));
-        }
-        str.append(0);
-        return str;
-    }
-
-    Repeat(Pick * base, int minCount =0, int maxCount = 1, Buffer_int * weights = NULL):
-        wr(weights, maxCount-minCount +1) {
-        this->item = base;
-        this->min = minCount;
-        this->max = maxCount;
-    }
-    virtual ~Repeat(){
-        delete item;  // TOFIX: point alias/recursion problem
-        item = NULL;
-    }
-};
-
-
-class Alternation : public Pick {
-public:
-    virtual const char* next(){
-        str.reset();
-        int i = wr.next();
-        const char * t = items[i]->next();
-        str.append_array(t, strlen(t) + 1);
-        return str;
-    }
-    virtual ~Alternation(){
-        int s = items.content_size();
-        for(int i=0; i < s; i++){
-            delete items[i];  // TOFIX: point alias/recursion problem
-            items[i] = NULL;
-        }
-    }
-
-    Alternation & append (Pick * node, int weight = DEFAULT_WEIGHT){
-        items.append(node);
-        wr.append(weight);
-        return *this;
-    }
-private:
-    Buffer_pPick items;
-    Buffer_char str; // null-terminated c-string
-    WeightedRand wr;
-};
-    
-///////////////////////////////////////////////////////////
-//
-// The parser
-//
-
-enum TokenType {STRING, VAR, NUMBER, STREAM_END, ERROR, QUESTION, STAR, PLUS, LBRACE, RBRACE, LPAR, RPAR, SEMI, EQ, COMMA, BAR, AT, WAVE, PERCENT};
-
-class Scanner{
-friend int DumpScanner(Scanner & s, UBool dumb);
-private:
-    const char * source;
-    const char * working;
-    const char * history; // for debug
-    enum StateType {START, IN_NUM, IN_VAR_FIRST, IN_VAR, IN_QUOTE, IN_QUOTE_BSLASH, IN_BSLASH, IN_STRING, DONE};
-    StateType state;
-    void terminated(TokenType t){
-        working--;       // return the peeked character
-        tokenType = t;
-        token.append(0); // close buffer
-        state = DONE;
-    }
-public:
-    // the buffer of "source" is owned by caller
-    Scanner(const char *src/*[in] c-string*/ = NULL):source(src){
-        working = src;
-        history = working;
-        state = DONE;
-        tokenType = ERROR;
-    }
-
-    //void setSource(const char *const src /*[in] c-string*/){
-    //    *(&const_cast<const char *>(source)) = src;
-    //}
-
-    Buffer_char token;
-    TokenType tokenType;
-
-    TokenType getNextToken(){
-        token.reset();
-        state = START;
-        history = working; // for debug
-        while (state != DONE){
-            char c = *working++;
-            if (c == 0 && state != START){//avoid buffer overflow. for IN_QUOE, IN_ESCAPE
-                terminated(ERROR);
-                break; // while
-            }
-            switch(state){
-                case START:
-                    tokenType = ERROR;
-                    switch(c){
-                        case '?'  : tokenType = QUESTION; break;
-                        case '*'  : tokenType = STAR; break;
-                        case '+'  : tokenType = PLUS; break;
-                        case '{'  : tokenType = LBRACE; break;
-                        case '}'  : tokenType = RBRACE; break;
-                        case '('  : tokenType = LPAR; break;
-                        case ')'  : tokenType = RPAR; break;
-                        case ';'  : tokenType = SEMI; break;
-                        case '='  : tokenType = EQ; break;
-                        case ','  : tokenType = COMMA; break;
-                        case '|'  : tokenType = BAR; break;
-                        case '@'  : tokenType = AT; break;
-                        case '~'  : tokenType = WAVE; break;
-                        case '%'  : tokenType = PERCENT; break;
-                        case 0    : tokenType = STREAM_END; working-- /*avoid buffer overflow*/; break;
-                    }
-                    if (tokenType != ERROR){
-                        token.append(c);
-                        token.append(0);
-                        state = DONE;
-                        break; // START
-                    }
-                    switch(c){
-                        case '$'  : state = IN_VAR_FIRST; token.append(c); break;
-                        case '\'' : state = IN_QUOTE;     break;
-                        case '\\' : state = IN_BSLASH;    break;
-                        default:
-                            if (isWhiteSpace(c)){    // state = START;   //do nothing
-                            } else if (isDigit(c)){     state = IN_NUM;    token.append(c);
-                            } else if (isAlphabet(c)){  state = IN_STRING; token.append(c);
-                            } else {terminated(ERROR);}
-                    }
-                    break;//START
-                case IN_NUM:
-                    if (isDigit(c)){
-                        token.append(c);
-                    } else {
-                        terminated(NUMBER);
-                    }
-                    break;//IN_NUM
-                case IN_VAR_FIRST:
-                    if (isAlphabet(c)){
-                        token.append(c);
-                        state = IN_VAR;
-                    } else {
-                        terminated(ERROR);
-                    }
-                    break; // IN_VAR_FISRT
-                case IN_VAR:
-                    if (isAlphabet(c) || isDigit(c)){
-                        token.append(c);
-                    } else {
-                        terminated(VAR);
-                    }
-                    break;//IN_VAR
-                case IN_STRING:
-                    // About the scanner's behavior for STRING, AT, and ESCAPE:
-                    // All of them can be contacted with each other. 
-                    // This means the scanner will eat up as much as possible strings
-                    //   (STRING, AT, and ESCAPE) at one time, with no regard of their
-                    //   combining sequence.
-                    //
-                    if (c == '\''){
-                        state = IN_QUOTE; // the first time we see single quote
-                    } else if (c =='\\'){ // back slash character
-                        state = IN_BSLASH;
-                    } else if (isAlphabet(c) || isDigit(c)){
-                        token.append(c);
-                    } else{
-                        terminated(STRING);
-                    }
-                    break;//IN_STRING
-                case IN_QUOTE:
-                    if (c == '\''){ // the second time we see single quote
-                        state = IN_STRING; // see document in IN_STRING
-                    } else if ( c== '\\') { // backslah escape in quote
-                        state = IN_QUOTE_BSLASH;
-                    } else {
-                        token.append(c);  // eat up everything, includes back slash
-                    }
-                    break;//IN_QUOTE
-                case IN_QUOTE_BSLASH:
-                case IN_BSLASH:
-                    switch (c){
-                        case 'n'  : token.append('\n'); break;
-                        case 'r'  : token.append('\r'); break;
-                        case 't'  : token.append('\t'); break;
-                        case '\'' : token.append('\''); break;
-                        case '\\' : token.append('\\'); break;
-                        default: token.append(c); // unknown escaping, treat it as literal
-                    }
-                    if (state == IN_BSLASH){
-                        state = IN_STRING; // see document in IN_STRING
-                    } else { // state == IN_QUOTE_BSLASH
-                        state = IN_QUOTE;
-                    }
-                    break;//IN_BSLASH
-                case DONE:  /* should never happen */
-                default:
-                    working--;
-                    tokenType = ERROR;
-                    state = DONE;
-                    break;
-            }//switch(state) 
-        }//while (state != DONE)
-
-        return tokenType;
-    }
-};//class Scanner
-
-class Parser{
-friend UBool TestParser();
-friend class TestParserT;
-friend class LanguageGenerator_impl;
-private:
-    Scanner s;
-    TokenType & token;
-    int min_max;   // for the evil infinite
-    
-    UBool match(TokenType expected){
-        if (token == expected) {
-            token = s.getNextToken();
-            return TRUE;
-        } else {
-            //s.dumpCurrentPoint();
-            return FALSE;
-        }
-    }
-
-    UBool weight(int & value){
-        if (token == NUMBER){
-            int temp = atoi(s.token);
-            match(NUMBER);
-            if (match(PERCENT)){
-                value = temp;
-                return TRUE;
-            }
-        }
-        return FALSE;
-    }
-
-    UBool repeat (Pick* &node /*in,out*/){
-        if (node == NULL) return FALSE;
-
-        int count = -2;
-        int min = -2;
-        int max = -2;
-        UBool question = FALSE;
-        switch (token){
-            case QUESTION:
-                match(QUESTION);
-                min = 0;
-                max = 1;
-                count = 2;
-                question = TRUE;
-                break;
-            case STAR:
-                match(STAR);
-                min = 0;
-                max = -1;
-                count = -1;
-                break;
-            case PLUS:
-                match(PLUS);
-                min = 1;
-                max = -1;
-                count = -1;
-                break;
-            case LBRACE:
-                match(LBRACE);
-                if (token != NUMBER){
-                    return FALSE;
-                }else {
-                    min = atoi(s.token);
-                    match(NUMBER);
-                    if (token == RBRACE){
-                        match(RBRACE);
-                        max = min;
-                        count = 1;
-                    } else if (token == COMMA) {
-                        match(COMMA);
-                        if (token == RBRACE){
-                            match(RBRACE);
-                            max = -1;
-                            count = -1;
-                        } else if (token == NUMBER) {
-                            max = atoi(s.token);
-                            match(NUMBER);
-                            count = max - min + 1;
-                            if (!match(RBRACE)) {
-                                return FALSE;
-                            }
-                        } else {
-                            return FALSE;
-                        }
-                    } else {
-                        return FALSE;
-                    }
-                }
-                break;
-            default:
-                return FALSE;
-        }
-
-        if (count == -2 || min == -2 || max == -2){
-            //ASSERT(FALSE);
-            return FALSE;
-        }
-
-        // eat up following weights
-        Buffer_int weights;
-        int w;
-        while (weight(w)){
-            weights.append(w);
-        }
-
-        // for the evil infinite
-        min_max = min_max > min ? min_max : min;
-        min_max = min_max > max ? min_max : max;
-        if (min_max > PSEUDO_INFINIT){
-            return FALSE; // PSEUDO_INFINIT is less than the real maximum
-        }
-        if (max == -1){ // the evil infinite
-            max = PSEUDO_INFINIT;
-        }
-        // for the strange question mark
-        if (question && weights.content_size() > 0){
-            Buffer_int w2;
-            w2.append(DEFAULT_WEIGHT - weights[0]).append(weights[0]);
-            node = new Repeat(node,min,max,&w2);
-            return TRUE;
-        }
-        node = new Repeat(node,min,max,&weights);
-        return TRUE;
-    }
-
-    UBool core(Pick* &node /*out*/){
-        if (node != NULL) return FALSE; //assert node == NULL
-
-        switch(token){
-            case LPAR:
-                match(LPAR);
-                if(defination(node) && match(RPAR)){
-                    return TRUE;
-                }
-                return FALSE;
-            case VAR:
-                node = new Variable(&symbols, s.token);
-                match(VAR);
-                return TRUE;
-            case STRING:
-                node = new Literal(s.token);
-                match(STRING);
-                return TRUE;
-            default:
-                return FALSE;
-        }
-    }
-    UBool modified(Pick* &node /*out*/){
-        if (node != NULL) return FALSE; //assert node == NULL
-
-        if (!core(node)) {
-            return FALSE;
-        }
-
-        for (;;){
-            switch(token){
-                case WAVE:
-                    match(WAVE);
-                    node = new Morph(*node);
-                    break;
-                case AT:
-                    match(AT);
-                    node = new Quote(*node);
-                    break;
-                case QUESTION:
-                case STAR:
-                case PLUS:
-                case LBRACE:
-                    if (!repeat(node)) return FALSE;
-                    break;
-                case SEMI:      // rule definiation closed
-                case RPAR:      // within parenthesis (core closed)
-                case BAR:       // in alternation
-                case NUMBER:    // in alternation, with weight
-                case LPAR:      // in sequence
-                case VAR:       // in sequence
-                case STRING:    // in sequence
-                    return TRUE;
-                default:
-                    return FALSE;
-            }
-        }
-    }
-
-
-    UBool sequence_list(Pick* &node /*in,out*/){
-        if (node == NULL) return FALSE; // assert node != NULL
-
-        Sequence* seq = new Sequence();
-        Pick * n = node;
-
-        while (token == VAR || token == STRING || token == LPAR){
-            seq->append(n);
-            n = NULL;
-            if (modified(n)){
-                // go on
-            } else {
-                goto FAIL;
-            }
-        }
-
-        if (token == SEMI || token == RPAR || token == BAR){
-            seq->append(n);
-            node = seq;
-            return TRUE;
-        }
-FAIL:
-        delete seq;
-        return FALSE;
-
-    }
-
-    UBool sequence(Pick* &node /*out*/){
-        if (node != NULL) return FALSE; //assert node == NULL
-
-        if (!modified(node)) {
-            return FALSE;
-        }
-
-        if (token == VAR || token == STRING || token == LPAR){
-            return sequence_list(node);
-        } else {
-            return TRUE; // just a modified
-        }
-    }
-
-    UBool alternation_list(Pick* &node /*in,out*/){
-        if (node == NULL) return FALSE; // assert node != NULL
-
-        Alternation * alt = new Alternation();
-        Pick * n = node;
-        int w = DEFAULT_WEIGHT;
-
-        while (token == NUMBER || token == BAR){
-            if(token == NUMBER) {
-                if (weight(w)){ 
-                    if (token == BAR){ 
-                        // the middle item, go on
-                    } else {
-                        // the last item or encounter error
-                        break; //while
-                    } 
-                } else {
-                    goto FAIL;
-                }
-            } // else token == BAR
-            match(BAR);
-            alt->append(n,w);
-
-            n = NULL;
-            w = DEFAULT_WEIGHT;
-            if (sequence(n)){
-                // go on
-            } else {
-                goto FAIL;
-            }
-        }
-
-        if (token == SEMI || token == RPAR) {
-            alt->append(n,w);
-            node = alt;
-            return TRUE;
-        }
-FAIL:
-        delete alt;
-        return FALSE;
-    }
-
-    UBool alternation(Pick* &node /*out*/){
-        if (node != NULL) return FALSE; //assert node == NULL
-
-        // 'sequence' has higher precedence than 'alternation'
-        if (!sequence(node)){
-            return FALSE;
-        }
-
-        if (token == BAR || token == NUMBER){ // find a real alternation1, create it.
-            return alternation_list(node);
-        } else {
-            return TRUE;    // just a sequence_old
-        }
-    }
-
-
-    UBool defination(Pick* &node /*out*/){
-        if (node != NULL) return FALSE; //assert node == NULL
-        return alternation(node);
-    }
-
-    UBool rule(){
-        if (token == VAR){
-            Buffer_char name;
-            name.append_array(s.token, strlen(s.token) + 1);
-            match(VAR);
-
-            if (match(EQ)){
-                Pick * t = NULL;
-                if(defination(t)){
-                    symbols.put(name, t);
-                    return match(SEMI);
-                }
-            }
-        }
-        return FALSE;
-    }
-public:
-    UBool rules(){
-        symbols.reset();
-        token = s.getNextToken();
-        while (rule()){
-        }
-        if (token == STREAM_END){
-            return TRUE;
-        } else {
-            //s.dumpCurrentPoint();
-            return FALSE;
-        }
-    }
-
-public:
-    SymbolTable symbols;
-
-    Parser(const char *const source):s(source), token(s.tokenType){
-        min_max = -2;
-    }
-    UBool parse(){
-        return rules();
-    }
-
-}; // class Parser
-        
-
-///////////////////////////////////////////////////////////
-//
-// 
-//
-
-int DumpScanner(Scanner & s, UBool dump = TRUE){
-    int len = strlen(s.source);
-    int error_start_offset = s.history - s.source;
-    if (dump){
-        printf("\n=================== DumpScanner ================\n");
-        fwrite(s.source, len, 1, stdout);
-        printf("\n-----parsed-------------------------------------\n");
-        fwrite(s.source, s.history - s.source, 1, stdout);
-        printf("\n-----current------------------------------------\n");
-        fwrite(s.history, s.working - s.history, 1, stdout);
-        printf("\n-----unparsed-----------------------------------\n");
-        fwrite(s.working, (s.source + len - s.working), 1, stdout);
-        printf("\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n");
-    }
-    return error_start_offset;
-}
-
-class LanguageGenerator_impl{
-public:
-    LanguageGenerator_impl(const char *const bnf_definition, const char *const top_node)
-        :par(bnf_definition), top_node_name(top_node){
-        srand((unsigned)time( NULL ));
-    }
-
-    LanguageGenerator::PARSE_RESULT parseBNF(UBool debug = TRUE){
-        if (par.parse()){
-            if (par.symbols.find(top_node_name, &top_node_ref) == SymbolTable::HAS_REF) {
-                if (par.symbols.is_complete()) {
-                    return LanguageGenerator::OK;
-                } else {
-                    if (debug) printf("The bnf definition is incomplete.\n");
-                    return LanguageGenerator::INCOMPLETE;
-                }
-            } else {
-                if (debug) printf("No top node is found.\n");
-                return LanguageGenerator::NO_TOP_NODE;
-            }
-        } else {
-            if(debug) {
-                printf("The bnf definition is wrong\n");
-                DumpScanner(par.s, TRUE);
-            }
-            return LanguageGenerator::BNF_DEF_WRONG;
-        }
-    }
-    const char * next(){
-        return top_node_ref->next();
-    }
-
-private:
-    Parser par;
-    const char *const top_node_name;
-    Pick * top_node_ref;
-};
-
-LanguageGenerator::LanguageGenerator():lang_gen(NULL){
-}
-
-LanguageGenerator::~LanguageGenerator(){
-    delete lang_gen;
-}
-
-LanguageGenerator::PARSE_RESULT LanguageGenerator::parseBNF(const char *const bnf_definition /*in*/, const char *const top_node/*in*/, UBool debug){
-    if (lang_gen){
-        delete lang_gen;
-    }
-    lang_gen = new LanguageGenerator_impl(bnf_definition, top_node);
-    PARSE_RESULT r = lang_gen->parseBNF(debug);
-    if (r != OK){
-        delete lang_gen;
-        lang_gen = NULL;
-        return r;
-    } else {
-        return r;
-    }
-}
-const char *LanguageGenerator::next(){ // Return a null-terminated c-string. The buffer is owned by callee.
-    if (lang_gen){
-        return lang_gen->next();
-    }else { 
-        return "";
-    }
-}
-
-///////////////////////////////////////////////////////////
-//
-// The test code for WBNF
-//
-
-#define CALL(fun) \
-    if (fun()){ \
-        printf("Pass: " #fun "\n");\
-    } else { \
-        printf("FAILED: !!! " #fun " !!!\n"); \
-    }
-
-#define DUMP_R(fun, var, times) \
-    {printf("\n========= " #fun " =============\n"); \
-    for (int i=0; i<times; i++) { \
-        const char * t = var.next();\
-        fwrite(t,strlen(t),1,stdout); \
-        printf("\n");   \
-    }   \
-    printf("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n");}
-
-
-
-#if TEST_WBNF_TEST    
-static UBool TestQuote(){
-    const char *const str = "This ' A !,z| qq [] .new\tline";
-    //const char *const str_r = "This \\' A '!,'z'|' qq '[]' '.'new\tline";
-    ////
-    //// :(  we must quote our string to following C syntax
-    ////     cannot type the literal here, it makes our code rather human unreadable
-    ////     very very unconformable!
-    ////
-    ///* 
-    //*/
-
-    //const char *const s1    =   "ab'c";
-    //const char (* s1_r1) [] = { "ab''c",    // ab''c
-    //                            "ab\\'c",   // ab\'c
-    //                           };//
-    ///*
-    // .      '.'     \.
-    // ..     \.\.    '.'\.   '.'\.   '..'    // '.''.'  wrong
-    //*/
-
-    //const char *const s2    =   "a..'.b";       // a..'.b
-    //const char (*s2_r) []   = { "a'..''.'b"     // a'..''.'b   
-    //                           ,"a'..\\'.'b"    // a'..\'.'b
-    //                           ,"a'..'\\''.'b"  // a'..'\''.'b
-    //                          };//
-
-    //const char *const s3    =   "a..\\.b";      // a..\.b
-    //const char (*s3_r) []   = { "a'..\\\\.'b"   // a'..\\.'b
-    //                           ,"a'..'\\\\'.'b" // a'..'\\'.'b
-    //                          };//
-
-    //                            // no catact operation, no choice, must be compact
-
-    srand((unsigned)time( NULL ));
-    
-    //Escaper l(Escaper::NO, Escaper::NO, Escaper::RAND_ESC);
-    Pick *p = new Literal(str);
-    Quote q(*p);
-
-    DUMP_R(TestQuote, (*p), 1);
-    DUMP_R(TestQuote, q, 20);
-    return FALSE;
-}
-static UBool TestLiteral(){
-    const char * s = "test string99.";
-    Literal n(s);
-    const char * r = n.next();
-    return strcmp(s,r) == 0;
-}
-
-static UBool TestSequence(){
-    Sequence seq;
-    seq.append(new Literal("abc "));
-    seq.append(new Literal(", s"));
-
-    return strcmp(seq.next(), "abc , s") == 0;
-}
-static UBool TestAlternation(){
-    srand((unsigned)time( NULL ));
-    Alternation alt;
-    alt.append(new Literal("aaa_10%"),10);
-    alt.append(new Literal("bbb_0%"),0);
-    alt.append(new Literal("ccc_10%"),10);
-    alt.append(new Literal("ddddddd_50%"),50);
-
-    DUMP_R(TestAlternation, alt, 50);
-
-    return FALSE;
-}
-
-static UBool TestBuffer(){
-    Buffer_int t;
-    t.append(1).append(0).append(5);
-    int s = t.content_size();
-    for (int i=0; i<s; ++i){
-        printf("%d\n", t[i]);
-    }
-    return FALSE;
-}
-
-static UBool TestWeightedRand(){
-    srand((unsigned)time( NULL ));
-    Buffer_int t;
-    t.append(1).append(0).append(5);
-    WeightedRand wr(&Buffer_int().append(10).append(0).append(50),4);
-//    WeightedRand wr(&t,3);
-    for (int i=0; i< 50; ++i){
-        printf("%d\n", wr.next());
-    }
-    return FALSE;
-}
-
-static UBool TestRepeat(){
-    srand((unsigned)time( NULL ));
-    Repeat rep(new Literal("aaa1-5 "), 1, 5);
-    DUMP_R(TestRepeat, rep, 50);
-
-    Repeat r2(new Literal("b{1,3}1%0%5% "), 1, 3, &Buffer_int().append(1).append(0).append(5));
-    DUMP_R(TestRepeat, r2, 50);
-
-    Repeat r3(new Literal("aaa5-5 "), 5, 5);
-    DUMP_R(TestRepeat, r3, 50);
-
-    return FALSE;
-}
-
-static UBool TestVariable(){
-    SymbolTable tab;
-    Pick * value = new Literal("string1");
-    Variable var1(&tab, "x", value);
-
-    Variable var2(&tab, "y");
-//    tab.put(var2, value); // TOFIX: point alias/recursion problem
-    Pick * value2 = new Literal("string2");
-    tab.put(var2, value2);
-
-    Pick * value3 = new Literal("string3");
-    Variable var3(&tab, "z");
-    tab.put("z", value3);
-
-    UBool pass;
-    pass = strcmp(var1.next(), value->next()) == 0;
-    pass = pass && strcmp(var2.next(), value2->next()) == 0;
-    pass = pass && strcmp(var3.next(), value3->next()) == 0;
-    return pass;
-}
-
-static UBool TestSymbolTable(){
-    Literal * n1 = new Literal("string1");
-    Literal * n2 = new Literal("string2");
-    SymbolTable t;
-    t.put("abc", n1);
-    t.put("$aaa", n2);
-//    t.put("alias", n1);  // TOFIX: point alias/recursion problem
-    t.put("bbb");
-
-    UBool pass;
-    pass = t.find(NULL) == SymbolTable::EMPTY;
-    pass = pass && t.find("ccc") == SymbolTable::NO_VAR;
-    pass = pass && t.find("bbb") == SymbolTable::NO_REF;
-    pass = pass && t.find("abc") == SymbolTable::HAS_REF;
-    pass = pass && t.find("$aaa") == SymbolTable::HAS_REF;
-
-    t.reset();
-    pass = pass && t.find("abc") == SymbolTable::NO_VAR;
-    return pass;
-}
-
-
-static UBool TestScanner(void){
-    //const char str1[] = "$root = $command{0,5} $reset $mostRules{1,20};";
-    //const char str1_r[][20] = {"$root", "=", "$command", "{", "0", ",", "5", "}", 
-    //    "$reset", "$mostRules", "{", "1", ",", "20", "}", ";"};
-
-    const char str2[] = "$p2 =(\\\\ $s $string $s)? 25%;";
-    const char str2_r[][20] = {"$p2", "=", "(", "\\", "$s", "$string", "$s", ")", "?", "25", "%", ";"};
-
-    const char *str = str2;
-    const char (*str_r)[20] = str2_r;
-    int tokenNum = sizeof(str2_r)/sizeof(char[20]);
-
-    Scanner t(str);
-    UBool pass = TRUE;
-    t.getNextToken();
-    int i = 0;
-    while (pass){
-        if (t.tokenType == STREAM_END){
-            pass = pass? i == tokenNum : FALSE;
-            break;//while
-        } else if (t.tokenType == ERROR){
-            pass = FALSE;
-            break;//while
-        } else {
-            pass = strcmp( &(t.token[0]), str_r[i++]) == 0;
-            t.getNextToken();
-        }
-    }
-
-    //const char ts[] = "$commandList = '['"
-    //" ( alternate ' ' $alternateOptions"
-    //" | backwards ' 2'"
-    //" | normalization ' ' $onoff "
-    //" | caseLevel ' ' $onoff "
-    //" | hiraganaQ ' ' $onoff"
-    //" | caseFirst ' ' $caseFirstOptions"
-    //" | strength ' ' $strengthOptions"
-    //" ) ']';" ;
-
-    //Scanner t2(ts);
-    //pass = TRUE;
-    //do {
-    //    t2.getNextToken();
-    //    if (t2.tokenType == ERROR){
-    //        DumpScanner(t2);
-    //        return FALSE;
-    //    }
-    //}while (t.tokenType != STREAM_END);
-
-    return pass;
-}
-
-class TestParserT {
-public:
-UBool operator () (const char *const str, const int exp_error_offset = -1, const UBool dump = TRUE){
-    Parser par(str);
-    if (par.rules()){
-        if ( exp_error_offset == -1){
-            return TRUE;
-        }else {
-            DumpScanner(par.s,dump);
-            return FALSE;
-        }
-    }else {
-        return DumpScanner(par.s, dump) == exp_error_offset;
-    }
-}
-};
-
-UBool TestParser(){
-    TestParserT test;
-
-    UBool pass = TRUE;
-    pass = pass && test ("$s = ' ' ? 50%;");
-    pass = pass && test("$x = ($var {1,2}) 3%;");         // legal
-    pass = pass && test("$x = $var {1,2} 3% | b 4%;");    // legal
-    pass = pass && test("$x = $var {1,2} 3%;");           // legal
-    pass = pass && test("$m = $c ? 2% 4% | $r 5% | $n 25%;"); // legal
-    pass = pass && test("$a = b ? 2% | c 5%;");               // legal
-    pass = pass && test("$x = A B 5% C 10% | D;", 8, FALSE);  // illegal 5%
-    pass = pass && test("$x = aa 45% | bb 5% cc;", 19, FALSE);// illegal cc
-    pass = pass && test("$x = (b 5%) (c 6%);");               // legal
-    pass = pass && test("$x = (b 5%) c 6%;", 13, FALSE);      // illegal 6%
-    pass = pass && test("$x = b 5% (c 6%);", 9, FALSE);       // illegal (c 6%)
-    pass = pass && test("$x = b 5% c 6%;", 9, FALSE);         // illegal c 6%
-    pass = pass && test("$x = b 5%;");                        // legal
-    pass = pass && test("$x = aa 45% | bb 5% cc;", 19, FALSE);// illegal cc
-    pass = pass && test("$x = a | b  | c 4% | d 5%;");        // legal
-    pass = pass && test("$s = ' ' ? 50% abc;");               // legal
-    pass = pass && test("$s =  a | c d | e f;");              // legal
-    pass = pass && test( "$z = q 0% | p 1% | r 100%;");         // legal How to check parsed tree??
-
-    pass = pass && test("$s = ' ' ? 50%;");
-    pass = pass && test("$relationList = '<' | '<<' |  ';' | '<<<' | ',' | '=';");
-    pass = pass && test("$p1 = ($string $s '|' $s)? 25%;");
-    pass = pass && test("$p2 = (\\\\ $s $string $s)? 25%;");
-    pass = pass && test("$rel2 = $p1 $string $s $p2;");
-    pass = pass && test("$relation = $relationList $s ($rel1 | $rel2) $crlf;");
-    pass = pass && test("$command = $commandList $crlf;");
-    pass = pass && test("$reset = '&' $s ($beforeList $s)? 10% ($positionList 100% | $string 10%) $crlf;");
-    pass = pass && test("$mostRules = $command 1% | $reset 5% | $relation 25%;");
-    pass = pass && test("$root = $command{0,5} $reset $mostRules{1,20};");
-
-    const char collationBNF[] =
-    "$s = ' '? 50%;" 
-    "$crlf = '\r\n';" 
-
-    "$alternateOptions = non'-'ignorable | shifted;" 
-    "$onoff = on | off;" 
-    "$caseFirstOptions = off | upper | lower;" 
-    "$strengthOptions = '1' | '2' | '3' | '4' | 'I';" 
-    "$commandList = '['"
-    " ( alternate ' ' $alternateOptions"
-    " | backwards ' 2'"
-    " | normalization ' ' $onoff "
-    " | caseLevel ' ' $onoff "
-    " | hiraganaQ ' ' $onoff"
-    " | caseFirst ' ' $caseFirstOptions"
-    " | strength ' ' $strengthOptions"
-    " ) ']';" 
-    "$command = $commandList $crlf;" 
-
-    "$ignorableTypes = (tertiary | secondary | primary) ' ' ignorable;" 
-    "$allTypes = variable | regular | implicit | trailing | $ignorableTypes;" 
-    "$positionList = '[' (first | last) ' ' $allTypes ']';"
-
-    "$beforeList = '[before ' ('1' | '2' | '3') ']';"
-
-    "$relationList = ("
-    "   '<'"
-    " | '<<'"
-    " | ';'" 
-    " | '<<<'"
-    " | ','" 
-    " | '='"
-    ");"
-    "$string = $magic;" 
-    "$rel1 = '[variable top]' $s;" 
-    "$p1 = ($string $s '|' $s)? 25%;" 
-    "$p2 = (\\\\ $s $string $s)? 25%;" 
-    "$rel2 = $p1 $string $s $p2;" 
-    "$relation = $relationList $s ($rel1 | $rel2) $crlf;" 
-
-    "$reset = '&' $s ($beforeList $s)? 10% ($positionList 1% | $string 10%) $crlf;" 
-    "$mostRules = $command 1% | $reset 5% | $relation 25%;"
-    "$root = $command{0,5} $reset $mostRules{1,20};"
-    ;
-    
-    pass = pass && test(collationBNF);
-
-
-    return pass;
-}
-
-static UBool TestMorph(){
-    srand((unsigned)time( NULL ));
-
-    Alternation * alt = new Alternation();
-
-    (*alt)
-    .append(new Literal("a")).append(new Literal("b")).append(new Literal("c"))
-    .append(new Literal("d")).append(new Literal("e")).append(new Literal("f"))
-    .append(new Literal("g")).append(new Literal("h")).append(new Literal("i"))
-    .append(new Literal("j")).append(new Literal("k")).append(new Literal("l"))
-    .append(new Literal("m")).append(new Literal("n")).append(new Literal("o"))
-    ;
-
-    Repeat * rep = new Repeat( alt ,5,5 );
-    Morph m( *rep);
-
-//    DUMP_R(TestMorph,(*rep),20);
-    DUMP_R(TestMorph,m,100);
-
-    return FALSE;
-}
-
-#endif
-
-static UBool TestLanguageGenerator(){
-    //LanguageGenerator g;
-    //const char *const s = "$s = p 0% | q 1%;";
-    //g.parseBNF(s, "$s");
-    UBool pass;
-    //= strcmp("q", g.next()) == 0;
-
-    const char *const def = 
-        //"$a = $b;"
-        //"$b = $c;"
-        //"$c = $t;"
-        //"$t = abc $z{1,2};"
-        //"$k = a | b | c | d | e | f | g ;"
-        //"$z = q 0% | p 1% | r 1%;"
-        "$x = a ? 0%;"
-        ; // end of string
-//    const char * s = "abczz";
-//
-//
-    LanguageGenerator g;
-    pass = g.parseBNF(def, "$x",TRUE);
-////    LanguageGenerator g(collationBNF, "$root", "$magic", new MagicNode());
-//  
-    if (pass != LanguageGenerator::OK) return FALSE;
-    
-    DUMP_R(TestLanguageGenerator, g, 20);
-    return pass;
-
-    ////UBool pass = strcmp(s,r) == 0;
-
-    //if (pass){
-    //    printf("TestRandomLanguageGenerator passed.\n");
-    //} else {
-    //    printf("TestRandomLanguageGenerator FAILED!!!\n");
-    //}
-    //return pass;
-}
-
-void TestWbnf(void){
-    srand((unsigned)time( NULL ));
-
-    //CALL(TestLiteral);
-    //CALL(TestSequence);
-    //CALL(TestSymbolTable);
-    //CALL(TestVariable);
-
-    //TestRepeat();
-    //TestAlternation();
-    //TestMorph();
-
-    //TestQuote();
-    //TestBuffer();
-    //TestWeightedRand();
-
-    //CALL(TestScanner);
-    //CALL(TestParser);
-    CALL(TestLanguageGenerator);
-}
-
diff --git a/icu4c/source/test/intltest/wbnf.h b/icu4c/source/test/intltest/wbnf.h
deleted file mode 100644 (file)
index 7b76f8f..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- ******************************************************************************
- * Copyright (C) 2005, International Business Machines Corporation and   *
- * others. All Rights Reserved.                                               *
- ******************************************************************************
- */
-/*
-  WBNF, Weighted BNF, is an extend BNF. The most difference between WBNF 
-  and standard BNF is the WBNF accepts weight for its alternation items.
-  The weight specifies the opportunity it will be selected.
-
-  The purpose of WBNF is to help generate a random string from a given grammar
-  which can be described with standard BNF. The introduction of 'weight'
-  is to guide the generator to give the specific parts different chances to be 
-  generated.
-
-  Usually, the user gives LanguageGenerator the grammar description in WBNF,
-  then LanguageGenerator will generate a random string on every next() call.
-  The return code of parseBNF() can help user to determine the error,
-  either in the grammar description or in the WBNF parser itself.
-
-
-  The grammar of WBNF itself can be described in standard BNF, 
-  
-    escaping        = _single character with a leading back slash, either inside or outside quoting_
-    quoting         = _quoted with a pair of single quotation marks_
-    string          = string alphabet | string digit | string quoting | string escaping |
-                      alphabet | quoting | escaping
-    alphabet        = 
-    digit           = 
-    integer         = integer digit | digit
-    weight          = integer %
-    weight-list     = weight-list weight | weight
-    var             = var alphabet | var digit | $ alphabet
-
-    var-defs        = var-defs var-def | var-def
-    var-def         = var '=' definition;
-
-    alternation     = alternation '|' alt-item | alt-item 
-    alt-item        = sequence | sequence weight
-
-    sequence        = sequence modified | modified
-
-    modified        = core | morph | quote | repeat
-    morph           = modified ~
-    quote           = modified @
-    repeat          = modified quantifier | modified quantifier weight-list
-    quantifier      = ? | * | + | { integer , integer} | {integer, } | {integer}
-
-    core            = var | string | '(' definition ')'
-
-    definition      = core | modified | sequence | alternation
-    definition      = alternation
-
-    Remarks:
-    o Following characters are literals in preceding definition
-      but are syntax symbols in WBNF
-
-      % $ ~ @ ? * + { } ,
-
-    o Following character are syntax symbols in preceding definition
-              (sapce) contact operation, or separators to increase readability
-      =       definition
-      |       selection operation
-      ( )     precedence select
-      ' '     override special-character to plain character
-
-    o the definition of 'escaping' and 'quoting' are preceding definition text
-    o infinite is actually a predefine value PSEUDO_INFINIT defined in this file 
-    o if weight is not presented in "alt-item' and 'repeat',
-      a default weight DEFAULT_WEIGHT defined in this file is used
-
-    o * == {0,  }
-      + == {1,  }
-      ? == {0, 1}
-
-    o the weight-list for repeat assigns the weights for repeat itmes one by one
-      
-      demo{1,3} 30% 40% 100%  ==  (demo)30% | (demodemo)40% | (demodemodemo)100%
-
-      To find more explain of the weight-list, please see the LIMITATION of the grammar
-
-    o but the weight-list for question mark has different meaning
-
-      demo ? 30%   != demo{0,1} 30% 100%
-      demo ? 30%   == demo{0,1} 70% 30%
-      
-      the 70% is calculated from (DEFAULT_WEIGHT - weight)
-
-
-  Known LIMITATION of the grammar
-    For 'repeat', the parser will eat up as much as possible weights at one time,
-    discard superfluous weights if it is too much,
-    fill insufficient weights with default weight if it is too less.
-    This behavior means following definitions are equal
-
-        demo{1,3} 30% 40% 100%
-        demo{1,3} 30% 40% 100% 50%
-        demo{1,3} 30% 40%
-
-    This behavior will cause a little confusion when defining an alternation
-
-        demo{1,3} 30% 40% 100% 50% | show 20%
-
-    is interpreted as 
-
-        (demo{1,3} 30% 40% 100%) 100% | show 20%
-
-    not 
-
-        (demo{1,3} 30% 40% 100%) 50% | show 20%
-
-    to get an expected definition, please use parentheses.
-
-  Known LIMITATION of current implement
-    Due to the well known point alias problem, current Parser will be effectively
-    crashed if the definition looks like
-
-        $a = demo;
-        $b = $a;
-        $c = $a;
-    or
-        $a = demo;
-        $b = $a $a;
-    or 
-        $a = demo;
-        $b = $b $a;
-
-    The crash will occur at delete operation in destructor or other memory release code.
-    Several plans are on hard to fix the problem. Use a smart point with reference count,
-    or use a central memory management solution. But now, it works well with collation 
-    monkey test, which is the only user for WBNF.
-*/
-
-#ifndef _WBNF
-#define _WBNF
-
-#include "unicode/utypes.h"
-
-const int DEFAULT_WEIGHT = 100;
-const int PSEUDO_INFINIT = 200;
-
-class LanguageGenerator_impl;
-
-class LanguageGenerator{
-    LanguageGenerator_impl * lang_gen;
-public:
-    enum PARSE_RESULT {OK, BNF_DEF_WRONG, INCOMPLETE, NO_TOP_NODE};
-    LanguageGenerator();
-    ~LanguageGenerator();
-    PARSE_RESULT parseBNF(const char *const bnf_definition /*in*/, const char *const top_node/*in*/, UBool debug=FALSE);
-    const char *next(); /* Return a null-terminated c-string. The buffer is owned by callee. */
-};
-
-void TestWbnf(void);
-
-#endif /* _WBNF */