/*
 ******************************************************************************
 * Copyright (C) 2005-2006, 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.sourceforge.net/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);
}

