1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ****************************************************************************** 3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Copyright (C) 2005-2007, International Business Machines Corporation and * 4ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * others. All Rights Reserved. * 5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ****************************************************************************** 6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <stdio.h> 9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <string.h> 10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <stdlib.h> 11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <time.h> 12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "wbnf.h" 14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Most of this code is meant to test the test code. It's a self test. 16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Normally this isn't run. 17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define TEST_WBNF_TEST 0 18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/////////////////////////////////////////////////////////// 20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Constants and the most basic helper classes 22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const char DIGIT_CHAR[] = "0123456789"; 25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const char WHITE_SPACE[] = {'\t', ' ', '\r', '\n', 0}; 26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const char ALPHABET[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const char SPECIAL[] = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"; 28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic inline UBool isInList(const char c /*in*/, const char list[] /*in*/){ 30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char * p = list; 31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (;*p != 0 && *p != c; p++); 32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return *p?TRUE:FALSE; 33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic inline UBool isDigit(char c) {return isInList(c, DIGIT_CHAR);} 35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic inline UBool isWhiteSpace(char c) {return isInList(c, WHITE_SPACE);} 36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic inline UBool isAlphabet(char c) {return isInList(c, ALPHABET);} 37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic inline UBool isSpecialAsciiChar(char c) {return isInList(c,SPECIAL);} 38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/////////////////////////////////////////////////////////// 42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Helper classes 44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass Buffer_byte{ 47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Utility class, can be treated as an auto expanded array. no boundary check. 48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru typedef char byte; 50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru byte * start; 51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru byte * current; 52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int buffer_size; // size unit is byte 53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic: 54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inline int content_size(){return current - start;} // size unit is byte 55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruprivate: 57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inline void expand(int add_size = 100){ // size unit is byte 58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int new_size = buffer_size + add_size; 59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int cs_snap = content_size(); 61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru start = (byte *) realloc(start, new_size); // may change the value of start 62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru current = start + cs_snap; 63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru memset(current, 0, add_size); 65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru buffer_size = new_size; 66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inline void expand_to(int size){ 69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int r = size - buffer_size; 70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (r > 0) { 71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru expand(r); // simply expand, no block alignment 72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Buffer_byte(const Buffer_byte &); 75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Buffer_byte & operator = (const Buffer_byte &); 76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic: 77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Buffer_byte():start(NULL),current(start),buffer_size(0){ 78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru expand(); 79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ~Buffer_byte(){ 81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru free(start); 82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inline void reset(){ 85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru start != NULL ? memset(start, 0, buffer_size) : 0; 86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru current = start; 87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // Using memory copy method to append a C array to buffer, 90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inline void append(const void * c, int size){ // size unit is byte 91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru expand_to(content_size() + size) ; 92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru memcpy(current, c, size); 93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru current = current + size; 94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru byte * buffer(){ 97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return start; 98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru The class(es) try to work as bulid-in array, so it overloads these two operators 103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru operator type *(); 104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru type & operator[]; 105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru The first is used to auto type convert, the latter is used to select member. 106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru A small trick is the class does not overload the address-of operator. This 108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru behavior is different from bulid-in array, but it give us the opportunity 109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru to get the address of the class itself. 110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//template<typename type> 112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// class BUFFER{ 113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// typedef BUFFER name; 114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define BUFFER(type, name)\ 115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru class name {\ 116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru private:\ 117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Buffer_byte buf;\ 118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru public:\ 119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru name & reset() {buf.reset(); return *this;}\ 120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru name & append(type c) {buf.append(&c, sizeof(type)); return *this;}\ 121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru name & append_array(const type * p, int size) {buf.append(p, sizeof(type)*size); return *this;}\ 122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru type & operator [] (int i) { return ((type *) buf.buffer())[i];}\ 123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru operator type *(){return (type *) buf.buffer();} \ 124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int content_size(){return buf.content_size() / sizeof(type);}\ 125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass Pick{ 129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* The Pick is the basic language generator element*/ 130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic: 131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // generate a string accroding the syntax 132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // Return a null-terminated c-string. The buffer is owned by callee. 133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual const char* next() = 0; 134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual ~Pick(){}; 135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//typedef BUFFER<char> Buffer_char; 138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//typedef BUFFER<int> Buffer_int; 139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//typedef BUFFER<Pick *> Buffer_pPick; 140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruBUFFER(char, Buffer_char); 141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruBUFFER(int, Buffer_int); 142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruBUFFER(Pick *, Buffer_pPick); 143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass SymbolTable{ 145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Helper class. 146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* It's a mapping table between 'variable name' and its 'active Pick object' 147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruprivate: 149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Buffer_char name_buffer; // var names storage space 150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Buffer_int names; // points to name (offset in name_buffer) 152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Buffer_pPick refs; // points to Pick 153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int get_index(const char *const var_name){ 155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int len = names.content_size(); 156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int i=0; i< len; i++){ 157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (strcmp(var_name, name_buffer + names[i]) == 0){ 158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return i; 159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return -1; 162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic: 165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru enum RESULT {EMPTY, NO_VAR, NO_REF, HAS_REF}; 166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru RESULT find(const char *const var_name /*[in] c-string*/, Pick * * ref = NULL /*[out] Pick* */){ 168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!var_name) return EMPTY; // NULL name 169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int i = get_index(var_name); 171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (i == -1){ 172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NO_VAR; // new name 173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!refs[i]){ // exist name, no ref 175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NO_REF; 176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (ref) { 178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *ref = refs[i]; 179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return HAS_REF; // exist name, has ref 181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void put(const char *const var_name, Pick *const var_ref = NULL){ 185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int i = get_index(var_name); 186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru switch(find(var_name)){ 187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case EMPTY: // NULL name 188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case NO_VAR: // new name 190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int offset; 191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru offset = name_buffer.content_size(); 192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru name_buffer.append_array(var_name, strlen(var_name) + 1); 193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru names.append(offset); 194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru refs.append(var_ref); 195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case NO_REF: // exist name, no ref 197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru refs[i] = var_ref; // link definition with variable 198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case HAS_REF: // exist name, has ref 200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (var_ref){ 201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru refs[i] = var_ref; 202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru default: 205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ; // ASSERT(FALSE); 206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool is_complete(){ 211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int n = names.content_size(); 212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int i=0; i<n; ++i){ 213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (refs[i] == NULL){ 214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void reset(){ 221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru names.reset(); 222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru name_buffer.reset(); 223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // release memory here 225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int s = refs.content_size(); 226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int i=0; i < s; i++){ 227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete refs[i]; // TOFIX: point alias/recursion problem 228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru refs.reset(); 230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ~SymbolTable(){ 233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru reset(); 234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Document of class Escaper 240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ATTENTION: 242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// From http://icu-project.org/userguide/Collate_Customization.html. 243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// We get the precedence of escape/quote operations 244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// (highest) 1. backslash \ 246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 2. two single quotes '' 247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 3. quoting ' ' 248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ICU Collation should accept following as the same string. 250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 1) 'ab'c _ 252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 2) a\bc \ 253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 3) a'b'\c |- They are equal. 254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 4) abc _/ 255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// From "two single quotes", we have following deductions 257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// D1. empty quoting is illgal. (obviously) 258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// D2. no contact operation between two quotings 259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// '.''.' is not .. it is .'. 260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// D3. "two single quotes" cannot contact two quoting simultaneously 261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// '..''''.' is not ..'. it is ..''. 262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// NOTICE: 263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// "two single quotes" can contact before one quoting 264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// '''.' is '. 265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// "two single quotes" can literally contact after one quoting 266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// But, from syntax, it's one quoting including a "two single quotes" 267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// '.''' is .' 268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// D4. "two single quotes" cannot solely be included in quoting 269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// '''' is not ' it is '' 270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// NOTICE: These are legal 271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// '.''.' is .'. 272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// '.''' is .' 273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// dicision 275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// /\ 276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// /__\ 277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// output buffer input buffer 278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// To make our dicision (within an atom operation) without caring input and output buffer, 280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// following calling pattern (within an atom operation) shall be avoided 281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// P1 open_quoting() then close_quoting() (direct violation) D1 283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// P2 close_quoting() then open_quoting() (direct violation) D2 284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// P3 empty open_quoting() (indirect violation) D1, D4 285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// P4 empty close_quoting() (indirect violation) D2, D3 286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// P5 open_quoting() then two single quotes (indirect violation) D4 287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// P6 close_quoting() then two single quotes (indirect violation) D3 288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// two single quotes escaping will not open_ or close_ quoting() 290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// The choice will not lose some quoing forms. 291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// For open_quoting(), 293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// we may get this form quoting ''' P5 294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// It may raise a bug ''''x 295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// If we expect 296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// '''.' let the next char open the quoting 297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// '.''.' the quoting is already opened by preceding char 298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// For close_quoting() 300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// we will get this form quoting '.''' P6 301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// It may raise a bug '.''''.' 302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// If we expect 303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// '.'''\. let the next char close the quoting 304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// '.''''.' the expectation is wrong! using '.'\''.' instead 305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// It's a hard work to re-adjust generation opportunity for various escaping form. 307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// We just simply ignore it. 308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass Escaper{ 310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic: 311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru enum CHOICE {YES, NO, RAND}; 312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru enum ESCAPE_FORM {BSLASH_ONLY, QUOTE_ONLY, QUOTE_AND_BSLAH, RAND_ESC}; 313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruprivate: 314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru class Bool{ // A wrapper class for CHOICE, to auto adapter UBool class 315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru private: 316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const CHOICE tag; 317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru public: 318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Bool(CHOICE flag=RAND):tag(flag){} 319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru operator UBool() { // conversion operator 320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return tag == RAND ? rand()%2 : tag == YES; 321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //if (tag == RAND){ 322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // return rand()%2 == 1; 323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //} else { 324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // return tag == YES ? TRUE : FALSE; 325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //} 326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru }; 328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic: 329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Escaper(CHOICE escapeLiteral = RAND, 330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru CHOICE twoQuotesEscape = RAND, 331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ESCAPE_FORM escapeForm = RAND_ESC): 332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru escape_form(escapeForm), 333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru escape_literal(escapeLiteral), 334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru two_quotes_escape(twoQuotesEscape), 335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru is_quoting(FALSE){} 336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruprivate: 337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Buffer_char str; 338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ESCAPE_FORM escape_form; 339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Bool escape_literal; 340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Bool two_quotes_escape; 341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool quote_escape; 342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool bslash_escape; 343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool is_quoting; 344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void set_options(){ 346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ESCAPE_FORM t = escape_form == RAND_ESC ? (ESCAPE_FORM) (rand()%3) : escape_form; 347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru switch (t){ 348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case BSLASH_ONLY : 349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru bslash_escape = TRUE; quote_escape = FALSE; break; 350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case QUOTE_ONLY: 351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru bslash_escape = FALSE;quote_escape = TRUE; break; 352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case QUOTE_AND_BSLAH: 353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru bslash_escape = TRUE; quote_escape = TRUE; break; 354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru default: 355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ;// error 356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void reset(){ 360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru str.reset(); 361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru is_quoting = FALSE; 362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inline void open_quoting(){ 365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(is_quoting){ 366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // do nothing 367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru str.append('\''); 369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru is_quoting = TRUE; 370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inline void close_quoting(){ 373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(is_quoting){ 374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru str.append('\''); 375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru is_quoting = FALSE; 376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // do nothing 378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // str [in] null-terminated c-string 382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void append(const char * strToAppend){ 383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for(;*strToAppend != 0; strToAppend++){ 384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru append(*strToAppend); 385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inline void append(const char c){ 389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru set_options(); 390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (c == '\\'){ 392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru quote_escape ? open_quoting() : close_quoting(); 393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //bslash_escape always true here 394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru str.append('\\'); 395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru str.append('\\'); 396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (c == '\''){ 397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (two_quotes_escape){ // quoted using two single quotes 398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // See documents in anonymous.design 399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru str.append('\''); 400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru str.append('\''); 401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else{ 402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru quote_escape ? open_quoting() : close_quoting(); 403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //bslash_escape always true here 404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru str.append('\\'); 405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru str.append('\''); 406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (isSpecialAsciiChar(c) || isWhiteSpace(c)){ 408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru quote_escape ? open_quoting() : close_quoting(); 409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (bslash_escape) str.append('\\'); 410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru str.append(c); 411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { //if (isAlphabet(c) || isDigit(c) || TRUE){ // treat others as literal 412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (escape_literal){ 413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru quote_escape ? open_quoting() : close_quoting(); 414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (bslash_escape) str.append('\\'); 415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru str.append(c); 416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru close_quoting(); 418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru str.append(c); 419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic: 424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // Return a null-terminate c-string. The buffer is owned by callee. 425ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char * operator()(const char * literal /*c-string*/){ 426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru str.reset(); 427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for(;*literal != 0; literal++){ 428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru append(*literal); 429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru close_quoting(); // P4 exception, to close whole quoting 431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return str; 432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass WeightedRand{ 436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Return a random number in [0, size) 437ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Every number has different chance (aka weight) to be selected. 438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruprivate: 439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Buffer_int weights; 440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru double total; 441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru WeightedRand(const WeightedRand &); 442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru WeightedRand & operator = (const WeightedRand &); 443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic: 444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru WeightedRand(Buffer_int * weight_list = NULL, int size = 0){ 445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if ( weight_list == NULL){ 446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int i=0; i<size; ++i) weights.append(DEFAULT_WEIGHT); 447ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int s = weight_list->content_size(); 449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (s < size){ 450ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru weights.append_array( (*weight_list),s); 451ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int i=s; i<size; ++i) weights.append(DEFAULT_WEIGHT); 452ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { // s >= size 453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru weights.append_array( (*weight_list),size); 454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 455ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru total = 0; 457ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int c = weights.content_size(); 458ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int i=0; i<c; ++i){ 459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru total += weights[i]; 460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 463ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void append(int weight){ 464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru weights.append(weight); 465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru total += weight; 466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 467ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 468ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // Give a random number with the consideration of weight. 469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // Every random number is associated with a weight. 470ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // It identifies the chance to be selected, 471ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // larger weight has more chance to be selected. 472ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // 473ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // 474ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // ______________________ every slot has equal chance 475ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // 476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // [____][_][___][______] each item has different slots, hence different chance 477ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // 478ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // 479ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // The algorithms to generate the number is illustrated by preceding figure. 480ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // First, a slot is selected by rand(). Then we translate the slot to corresponding item. 481ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // 482ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int next(){ 483ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // get a random in [0,1] 484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru double reference_mark = (double)rand() / (double)RAND_MAX; 485ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 486ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // get the slot's index, 0 <= mark <= total; 487ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru double mark = total * reference_mark; 488ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 489ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // translate the slot to corresponding item 490ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int i=0; 491ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (;;){ 492ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mark -= weights[i]; // 0 <= mark <= total 493ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (mark <= 0) 494ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 495ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru i++; 496ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 497ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return i; 498ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 499ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 500ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 501ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/////////////////////////////////////////////////////////// 502ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 503ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// The parser result nodes 504ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 505ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 506ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass Literal : public Pick { 507ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic: 508ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual const char* next(){ 509ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return str; 510ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 511ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Literal(const char * s /*c-string*/){ 512ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru str.append_array(s, strlen(s) + 1); 513ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 514ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruprivate: 515ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Buffer_char str; //null-terminated c-string 516ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 517ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 518ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass Variable : public Pick { 519ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic: 520ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Variable(SymbolTable * symbols, const char * varName, Pick * varRef = NULL){ 521ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru this->var_name.append_array(varName, strlen(varName) + 1); 522ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if ((symbol_table = symbols)){ 523ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru symbol_table->put(varName, varRef); 524ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 525ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 526ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 527ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru operator const char *(){ 528ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return var_name; 529ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 530ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 531ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual const char* next(){ 532ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (symbol_table){ 533ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Pick * var_ref = NULL; 534ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru symbol_table->find(var_name, &var_ref); 535ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (var_ref) { 536ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return var_ref->next(); 537ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 538ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 539ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return ""; // dumb string 540ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 541ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruprivate: 542ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Buffer_char var_name; 543ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru SymbolTable * symbol_table; 544ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 545ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 546ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass Quote : public Pick{ 547ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic: 548ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Quote(Pick & base):item(base),e(Escaper::NO, Escaper::NO, Escaper::BSLASH_ONLY){ 549ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 550ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual const char* next(){ 551ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return e(item.next()); 552ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 553ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruprivate: 554ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Pick & item; 555ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Buffer_char str; 556ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Escaper e; 557ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 558ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 559ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 560ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass Morph : public Pick{ 561ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 562ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruThe difference between morph and an arbitrary random string is that 563ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querua morph changes slowly. When we build collation rules, for example, 564ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruit is a much better test if the strings we use are all in the same 565ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru'neighborhood'; they share many common characters. 566ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 567ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic: 568ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Morph(Pick & base):item(base){} 569ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 570ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual const char* next(){ 571ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru current.reset(); 572ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char * s = item.next(); 573ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru current.append_array(s, strlen(s) + 1); 574ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (last.content_size() == 0) { 575ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru str.reset(); 576ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru last.reset(); 577ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru str.append_array(current, current.content_size()); 578ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru last.append_array(current, current.content_size()); 579ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 580ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru morph(); 581ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 582ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return str; 583ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 584ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruprivate: 585ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Pick & item; 586ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Buffer_char str; 587ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Buffer_char last; 588ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Buffer_char current; 589ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 590ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char * p_last; 591ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char * p_curr; 592ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 593ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void copy_curr(){ 594ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (*p_curr) { 595ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru str.append(*p_curr); 596ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru p_curr++; 597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 598ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 599ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 600ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void copy_last(){ 601ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (*p_last) { 602ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru str.append(*p_last); 603ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru p_last++; 604ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 605ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 606ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 607ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // copy 0, 1, or 2 character(s) to str 608ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void copy(){ 609ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru static WeightedRand wr(& Buffer_int().append(DEFAULT_WEIGHT * 10), 5); 610ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 611ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru switch (wr.next()){ 612ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case 0: // copy last -- has 10 times chance than others 613ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru copy_last(); 614ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 615ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case 1: // copy both 616ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru copy_curr(); 617ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru copy_last(); 618ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 619ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case 2: // copy both 620ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru copy_last(); 621ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru copy_curr(); 622ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 623ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case 3: 624ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru copy_curr(); 625ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 626ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case 4: // copy nothing 627ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 628ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru default: 629ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // ASSERT(FALSE); 630ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ; 631ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 632ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 633ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 634ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void morph(void){ 635ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int min = strlen(last); 636ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int max = strlen(current); 637ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (min > max){ 638ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int temp = min; 639ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru min = max; 640ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru max = temp; 641ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 642ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 643ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int len = min + rand()%(max - min + 1); // min + [0, diff] 644ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru p_curr = current; 645ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru p_last = last; 646ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru str.reset(); 647ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 648ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (; str.content_size()<len && *p_curr && *p_last;){ 649ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru copy(); // copy 0, 1, or 2 character(s) to str 650ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 651ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 652ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (str.content_size() == len) { 653ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru str.append(0); 654ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru final(); 655ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 656ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 657ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 658ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (str.content_size() > len) { // if the last copy copied two characters 659ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru str[len]=0; 660ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru final(); 661ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 662ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 663ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 664ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // str.content_size() < len 665ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (*p_last) { 666ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (; str.content_size() < len; copy_last()); 667ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (*p_curr){ 668ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (; str.content_size() < len; copy_curr()); 669ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 670ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 671ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int last_len = last.content_size(); 672ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (;str.content_size() < len;){ 673ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru str.append(last[rand()%last_len]); 674ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 675ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru str.append(0); 676ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru final(); 677ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 678ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 679ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void final(){ 680ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru last.reset(); 681ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru last.append_array(current, current.content_size()); 682ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 683ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 684ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 685ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass Sequence : public Pick { 686ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic: 687ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual const char* next(){ 688ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru str.reset(); 689ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int s = items.content_size(); 690ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for(int i=0; i < s; i++){ 691ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char * t = items[i]->next(); 692ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru str.append_array(t, strlen(t)); 693ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 694ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru str.append(0); // terminal null 695ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return str; 696ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 697ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 698ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void append (Pick * node){ 699ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru items.append(node); 700ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 701ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 702ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual ~Sequence(){ 703ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int s = items.content_size(); 704ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for(int i=0; i < s; i++){ 705ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //How can assure the item is got from heap? 706ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //Let's assume it. 707ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete items[i]; // TOFIX: point alias/recursion problem 708ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru items[i] = NULL; 709ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 710ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 711ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruprivate: 712ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Buffer_pPick items; 713ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Buffer_char str; //null-terminated c-string 714ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 715ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 716ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass Repeat : public Pick { 717ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruprivate: 718ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Pick * item; 719ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Buffer_char str; 720ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru WeightedRand wr; 721ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int min; 722ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int max; 723ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int select_a_count(){ 724ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return min + wr.next(); 725ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 726ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic: 727ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual const char* next(){ 728ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru str.reset(); 729ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int c = select_a_count(); 730ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for(int i=0; i< c; i++){ 731ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char * t = item->next(); 732ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru str.append_array(t, strlen(t)); 733ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 734ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru str.append(0); 735ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return str; 736ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 737ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 738ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Repeat(Pick * base, int minCount =0, int maxCount = 1, Buffer_int * weights = NULL): 739ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru wr(weights, maxCount-minCount +1) { 740ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru this->item = base; 741ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru this->min = minCount; 742ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru this->max = maxCount; 743ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 744ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual ~Repeat(){ 745ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete item; // TOFIX: point alias/recursion problem 746ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru item = NULL; 747ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 748ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 749ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 750ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 751ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass Alternation : public Pick { 752ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic: 753ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual const char* next(){ 754ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru str.reset(); 755ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int i = wr.next(); 756ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char * t = items[i]->next(); 757ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru str.append_array(t, strlen(t) + 1); 758ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return str; 759ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 760ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual ~Alternation(){ 761ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int s = items.content_size(); 762ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for(int i=0; i < s; i++){ 763ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete items[i]; // TOFIX: point alias/recursion problem 764ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru items[i] = NULL; 765ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 766ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 767ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 768ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Alternation & append (Pick * node, int weight = DEFAULT_WEIGHT){ 769ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru items.append(node); 770ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru wr.append(weight); 771ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return *this; 772ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 773ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruprivate: 774ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Buffer_pPick items; 775ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Buffer_char str; // null-terminated c-string 776ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru WeightedRand wr; 777ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 778ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 779ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/////////////////////////////////////////////////////////// 780ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 781ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// The parser 782ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 783ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 784ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruenum TokenType {STRING, VAR, NUMBER, STREAM_END, ERROR, QUESTION, STAR, PLUS, LBRACE, RBRACE, LPAR, RPAR, SEMI, EQ, COMMA, BAR, AT, WAVE, PERCENT}; 785ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 786ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass Scanner{ 787ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querufriend int DumpScanner(Scanner & s, UBool dumb); 788ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruprivate: 789ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char * source; 790ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char * working; 791ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char * history; // for debug 792ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru enum StateType {START, IN_NUM, IN_VAR_FIRST, IN_VAR, IN_QUOTE, IN_QUOTE_BSLASH, IN_BSLASH, IN_STRING, DONE}; 793ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru StateType state; 794ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void terminated(TokenType t){ 795ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru working--; // return the peeked character 796ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru tokenType = t; 797ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru token.append(0); // close buffer 798ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru state = DONE; 799ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 800ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic: 801ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // the buffer of "source" is owned by caller 802ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Scanner(const char *src/*[in] c-string*/ = NULL):source(src){ 803ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru working = src; 804ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru history = working; 805ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru state = DONE; 806ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru tokenType = ERROR; 807ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 808ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 809ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //void setSource(const char *const src /*[in] c-string*/){ 810ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // *(&const_cast<const char *>(source)) = src; 811ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //} 812ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 813ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Buffer_char token; 814ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru TokenType tokenType; 815ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 816ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru TokenType getNextToken(){ 817ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru token.reset(); 818ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru state = START; 819ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru history = working; // for debug 820ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (state != DONE){ 821ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char c = *working++; 822ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (c == 0 && state != START){//avoid buffer overflow. for IN_QUOE, IN_ESCAPE 823ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru terminated(ERROR); 824ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; // while 825ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 826ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru switch(state){ 827ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case START: 828ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru tokenType = ERROR; 829ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru switch(c){ 830ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case '?' : tokenType = QUESTION; break; 831ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case '*' : tokenType = STAR; break; 832ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case '+' : tokenType = PLUS; break; 833ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case '{' : tokenType = LBRACE; break; 834ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case '}' : tokenType = RBRACE; break; 835ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case '(' : tokenType = LPAR; break; 836ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case ')' : tokenType = RPAR; break; 837ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case ';' : tokenType = SEMI; break; 838ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case '=' : tokenType = EQ; break; 839ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case ',' : tokenType = COMMA; break; 840ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case '|' : tokenType = BAR; break; 841ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case '@' : tokenType = AT; break; 842ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case '~' : tokenType = WAVE; break; 843ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case '%' : tokenType = PERCENT; break; 844ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case 0 : tokenType = STREAM_END; working-- /*avoid buffer overflow*/; break; 845ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 846ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (tokenType != ERROR){ 847ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru token.append(c); 848ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru token.append(0); 849ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru state = DONE; 850ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; // START 851ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 852ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru switch(c){ 853ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case '$' : state = IN_VAR_FIRST; token.append(c); break; 854ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case '\'' : state = IN_QUOTE; break; 855ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case '\\' : state = IN_BSLASH; break; 856ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru default: 857ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (isWhiteSpace(c)){ // state = START; //do nothing 858ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (isDigit(c)){ state = IN_NUM; token.append(c); 859ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (isAlphabet(c)){ state = IN_STRING; token.append(c); 860ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else {terminated(ERROR);} 861ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 862ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break;//START 863ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case IN_NUM: 864ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (isDigit(c)){ 865ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru token.append(c); 866ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 867ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru terminated(NUMBER); 868ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 869ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break;//IN_NUM 870ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case IN_VAR_FIRST: 871ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (isAlphabet(c)){ 872ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru token.append(c); 873ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru state = IN_VAR; 874ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 875ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru terminated(ERROR); 876ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 877ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; // IN_VAR_FISRT 878ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case IN_VAR: 879ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (isAlphabet(c) || isDigit(c)){ 880ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru token.append(c); 881ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 882ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru terminated(VAR); 883ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 884ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break;//IN_VAR 885ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case IN_STRING: 886ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // About the scanner's behavior for STRING, AT, and ESCAPE: 887ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // All of them can be contacted with each other. 888ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // This means the scanner will eat up as much as possible strings 889ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // (STRING, AT, and ESCAPE) at one time, with no regard of their 890ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // combining sequence. 891ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // 892ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (c == '\''){ 893ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru state = IN_QUOTE; // the first time we see single quote 894ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (c =='\\'){ // back slash character 895ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru state = IN_BSLASH; 896ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (isAlphabet(c) || isDigit(c)){ 897ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru token.append(c); 898ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else{ 899ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru terminated(STRING); 900ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 901ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break;//IN_STRING 902ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case IN_QUOTE: 903ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (c == '\''){ // the second time we see single quote 904ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru state = IN_STRING; // see document in IN_STRING 905ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if ( c== '\\') { // backslah escape in quote 906ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru state = IN_QUOTE_BSLASH; 907ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 908ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru token.append(c); // eat up everything, includes back slash 909ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 910ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break;//IN_QUOTE 911ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case IN_QUOTE_BSLASH: 912ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case IN_BSLASH: 913ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru switch (c){ 914ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case 'n' : token.append('\n'); break; 915ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case 'r' : token.append('\r'); break; 916ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case 't' : token.append('\t'); break; 917ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case '\'' : token.append('\''); break; 918ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case '\\' : token.append('\\'); break; 919ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru default: token.append(c); // unknown escaping, treat it as literal 920ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 921ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (state == IN_BSLASH){ 922ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru state = IN_STRING; // see document in IN_STRING 923ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { // state == IN_QUOTE_BSLASH 924ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru state = IN_QUOTE; 925ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 926ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break;//IN_BSLASH 927ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case DONE: /* should never happen */ 928ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru default: 929ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru working--; 930ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru tokenType = ERROR; 931ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru state = DONE; 932ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 933ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru }//switch(state) 934ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru }//while (state != DONE) 935ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 936ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return tokenType; 937ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 938ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};//class Scanner 939ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 940ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass Parser{ 941ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querufriend UBool TestParser(); 942ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querufriend class TestParserT; 943ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querufriend class LanguageGenerator_impl; 944ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruprivate: 945ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Scanner s; 946ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru TokenType & token; 947ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int min_max; // for the evil infinite 948ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 949ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool match(TokenType expected){ 950ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (token == expected) { 951ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru token = s.getNextToken(); 952ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 953ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 954ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //s.dumpCurrentPoint(); 955ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 956ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 957ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 958ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 959ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool weight(int & value){ 960ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (token == NUMBER){ 961ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int temp = atoi(s.token); 962ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru match(NUMBER); 963ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (match(PERCENT)){ 964ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru value = temp; 965ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 966ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 967ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 968ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 969ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 970ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 971ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool repeat (Pick* &node /*in,out*/){ 972ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (node == NULL) return FALSE; 973ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 974ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int count = -2; 975ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int min = -2; 976ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int max = -2; 977ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool question = FALSE; 978ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru switch (token){ 979ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case QUESTION: 980ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru match(QUESTION); 981ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru min = 0; 982ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru max = 1; 983ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru count = 2; 984ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru question = TRUE; 985ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 986ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case STAR: 987ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru match(STAR); 988ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru min = 0; 989ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru max = -1; 990ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru count = -1; 991ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 992ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case PLUS: 993ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru match(PLUS); 994ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru min = 1; 995ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru max = -1; 996ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru count = -1; 997ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 998ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case LBRACE: 999ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru match(LBRACE); 1000ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (token != NUMBER){ 1001ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 1002ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru }else { 1003ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru min = atoi(s.token); 1004ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru match(NUMBER); 1005ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (token == RBRACE){ 1006ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru match(RBRACE); 1007ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru max = min; 1008ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru count = 1; 1009ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (token == COMMA) { 1010ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru match(COMMA); 1011ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (token == RBRACE){ 1012ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru match(RBRACE); 1013ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru max = -1; 1014ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru count = -1; 1015ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (token == NUMBER) { 1016ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru max = atoi(s.token); 1017ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru match(NUMBER); 1018ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru count = max - min + 1; 1019ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!match(RBRACE)) { 1020ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 1021ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1022ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1023ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 1024ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1025ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1026ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 1027ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1028ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1029ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1030ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru default: 1031ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 1032ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1033ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1034ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (count == -2 || min == -2 || max == -2){ 1035ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //ASSERT(FALSE); 1036ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 1037ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1038ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1039ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // eat up following weights 1040ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Buffer_int weights; 1041ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int w; 1042ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (weight(w)){ 1043ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru weights.append(w); 1044ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1045ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1046ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // for the evil infinite 1047ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru min_max = min_max > min ? min_max : min; 1048ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru min_max = min_max > max ? min_max : max; 1049ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (min_max > PSEUDO_INFINIT){ 1050ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; // PSEUDO_INFINIT is less than the real maximum 1051ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1052ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (max == -1){ // the evil infinite 1053ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru max = PSEUDO_INFINIT; 1054ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1055ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // for the strange question mark 1056ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (question && weights.content_size() > 0){ 1057ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Buffer_int w2; 1058ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru w2.append(DEFAULT_WEIGHT - weights[0]).append(weights[0]); 1059ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru node = new Repeat(node,min,max,&w2); 1060ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 1061ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1062ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru node = new Repeat(node,min,max,&weights); 1063ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 1064ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1065ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1066ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool core(Pick* &node /*out*/){ 1067ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (node != NULL) return FALSE; //assert node == NULL 1068ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1069ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru switch(token){ 1070ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case LPAR: 1071ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru match(LPAR); 1072ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(defination(node) && match(RPAR)){ 1073ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 1074ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1075ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 1076ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case VAR: 1077ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru node = new Variable(&symbols, s.token); 1078ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru match(VAR); 1079ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 1080ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case STRING: 1081ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru node = new Literal(s.token); 1082ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru match(STRING); 1083ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 1084ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru default: 1085ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 1086ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1087ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1088ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool modified(Pick* &node /*out*/){ 1089ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (node != NULL) return FALSE; //assert node == NULL 1090ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1091ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!core(node)) { 1092ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 1093ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1094ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1095ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (;;){ 1096ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru switch(token){ 1097ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case WAVE: 1098ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru match(WAVE); 1099ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru node = new Morph(*node); 1100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case AT: 1102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru match(AT); 1103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru node = new Quote(*node); 1104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case QUESTION: 1106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case STAR: 1107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case PLUS: 1108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case LBRACE: 1109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!repeat(node)) return FALSE; 1110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case SEMI: // rule definiation closed 1112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case RPAR: // within parenthesis (core closed) 1113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case BAR: // in alternation 1114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case NUMBER: // in alternation, with weight 1115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case LPAR: // in sequence 1116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case VAR: // in sequence 1117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case STRING: // in sequence 1118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 1119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru default: 1120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 1121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool sequence_list(Pick* &node /*in,out*/){ 1127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (node == NULL) return FALSE; // assert node != NULL 1128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Sequence* seq = new Sequence(); 1130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Pick * n = node; 1131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (token == VAR || token == STRING || token == LPAR){ 1133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru seq->append(n); 1134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru n = NULL; 1135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (modified(n)){ 1136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // go on 1137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru goto FAIL; 1139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (token == SEMI || token == RPAR || token == BAR){ 1143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru seq->append(n); 1144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru node = seq; 1145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 1146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruFAIL: 1148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete seq; 1149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 1150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool sequence(Pick* &node /*out*/){ 1154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (node != NULL) return FALSE; //assert node == NULL 1155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!modified(node)) { 1157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 1158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (token == VAR || token == STRING || token == LPAR){ 1161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return sequence_list(node); 1162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; // just a modified 1164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool alternation_list(Pick* &node /*in,out*/){ 1168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (node == NULL) return FALSE; // assert node != NULL 1169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Alternation * alt = new Alternation(); 1171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Pick * n = node; 1172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int w = DEFAULT_WEIGHT; 1173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (token == NUMBER || token == BAR){ 1175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(token == NUMBER) { 1176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (weight(w)){ 1177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (token == BAR){ 1178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // the middle item, go on 1179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // the last item or encounter error 1181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; //while 1182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru goto FAIL; 1185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } // else token == BAR 1187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru match(BAR); 1188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru alt->append(n,w); 1189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru n = NULL; 1191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru w = DEFAULT_WEIGHT; 1192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (sequence(n)){ 1193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // go on 1194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru goto FAIL; 1196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (token == SEMI || token == RPAR) { 1200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru alt->append(n,w); 1201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru node = alt; 1202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 1203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruFAIL: 1205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete alt; 1206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 1207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool alternation(Pick* &node /*out*/){ 1210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (node != NULL) return FALSE; //assert node == NULL 1211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // 'sequence' has higher precedence than 'alternation' 1213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!sequence(node)){ 1214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 1215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (token == BAR || token == NUMBER){ // find a real alternation1, create it. 1218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return alternation_list(node); 1219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; // just a sequence_old 1221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool defination(Pick* &node /*out*/){ 1226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (node != NULL) return FALSE; //assert node == NULL 1227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return alternation(node); 1228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool rule(){ 1231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (token == VAR){ 1232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Buffer_char name; 1233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru name.append_array(s.token, strlen(s.token) + 1); 1234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru match(VAR); 1235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (match(EQ)){ 1237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Pick * t = NULL; 1238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(defination(t)){ 1239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru symbols.put(name, t); 1240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return match(SEMI); 1241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 1245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic: 1247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool rules(){ 1248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru symbols.reset(); 1249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru token = s.getNextToken(); 1250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (rule()){ 1251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (token == STREAM_END){ 1253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 1254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //s.dumpCurrentPoint(); 1256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 1257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic: 1261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru SymbolTable symbols; 1262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Parser(const char *const source):s(source), token(s.tokenType){ 1264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru min_max = -2; 1265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool parse(){ 1267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return rules(); 1268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; // class Parser 1271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/////////////////////////////////////////////////////////// 1274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 1275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 1276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 1277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint DumpScanner(Scanner & s, UBool dump = TRUE){ 1279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int len = strlen(s.source); 1280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int error_start_offset = s.history - s.source; 1281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (dump){ 1282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru printf("\n=================== DumpScanner ================\n"); 1283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fwrite(s.source, len, 1, stdout); 1284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru printf("\n-----parsed-------------------------------------\n"); 1285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fwrite(s.source, s.history - s.source, 1, stdout); 1286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru printf("\n-----current------------------------------------\n"); 1287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fwrite(s.history, s.working - s.history, 1, stdout); 1288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru printf("\n-----unparsed-----------------------------------\n"); 1289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fwrite(s.working, (s.source + len - s.working), 1, stdout); 1290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru printf("\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"); 1291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return error_start_offset; 1293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass LanguageGenerator_impl{ 1296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic: 1297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LanguageGenerator_impl(const char *const bnf_definition, const char *const top_node) 1298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru :par(bnf_definition), top_node_name(top_node){ 1299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru srand((unsigned)time( NULL )); 1300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LanguageGenerator::PARSE_RESULT parseBNF(UBool debug = TRUE){ 1303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (par.parse()){ 1304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (par.symbols.find(top_node_name, &top_node_ref) == SymbolTable::HAS_REF) { 1305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (par.symbols.is_complete()) { 1306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return LanguageGenerator::OK; 1307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (debug) printf("The bnf definition is incomplete.\n"); 1309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return LanguageGenerator::INCOMPLETE; 1310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (debug) printf("No top node is found.\n"); 1313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return LanguageGenerator::NO_TOP_NODE; 1314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(debug) { 1317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru printf("The bnf definition is wrong\n"); 1318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru DumpScanner(par.s, TRUE); 1319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return LanguageGenerator::BNF_DEF_WRONG; 1321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char * next(){ 1324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return top_node_ref->next(); 1325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruprivate: 1328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Parser par; 1329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *const top_node_name; 1330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Pick * top_node_ref; 1331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 1332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLanguageGenerator::LanguageGenerator():lang_gen(NULL){ 1334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLanguageGenerator::~LanguageGenerator(){ 1337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete lang_gen; 1338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLanguageGenerator::PARSE_RESULT LanguageGenerator::parseBNF(const char *const bnf_definition /*in*/, const char *const top_node/*in*/, UBool debug){ 1341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (lang_gen){ 1342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete lang_gen; 1343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lang_gen = new LanguageGenerator_impl(bnf_definition, top_node); 1345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru PARSE_RESULT r = lang_gen->parseBNF(debug); 1346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (r != OK){ 1347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete lang_gen; 1348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lang_gen = NULL; 1349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return r; 1350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return r; 1352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst char *LanguageGenerator::next(){ // Return a null-terminated c-string. The buffer is owned by callee. 1355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (lang_gen){ 1356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return lang_gen->next(); 1357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru }else { 1358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return ""; 1359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/////////////////////////////////////////////////////////// 1363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 1364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// The test code for WBNF 1365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 1366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define CALL(fun) \ 1368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (fun()){ \ 1369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru printf("Pass: " #fun "\n");\ 1370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { \ 1371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru printf("FAILED: !!! " #fun " !!!\n"); \ 1372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define DUMP_R(fun, var, times) \ 1375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru {printf("\n========= " #fun " =============\n"); \ 1376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int i=0; i<times; i++) { \ 1377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char * t = var.next();\ 1378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fwrite(t,strlen(t),1,stdout); \ 1379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru printf("\n"); \ 1380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } \ 1381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru printf("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n");} 1382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if TEST_WBNF_TEST 1386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UBool TestQuote(){ 1387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *const str = "This ' A !,z| qq [] .new\tline"; 1388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //const char *const str_r = "This \\' A '!,'z'|' qq '[]' '.'new\tline"; 1389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //// 1390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //// :( we must quote our string to following C syntax 1391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //// cannot type the literal here, it makes our code rather human unreadable 1392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //// very very unconformable! 1393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //// 1394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ///* 1395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //*/ 1396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //const char *const s1 = "ab'c"; 1398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //const char (* s1_r1) [] = { "ab''c", // ab''c 1399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // "ab\\'c", // ab\'c 1400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // };// 1401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ///* 1402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // . '.' \. 1403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // .. \.\. '.'\. '.'\. '..' // '.''.' wrong 1404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //*/ 1405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //const char *const s2 = "a..'.b"; // a..'.b 1407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //const char (*s2_r) [] = { "a'..''.'b" // a'..''.'b 1408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // ,"a'..\\'.'b" // a'..\'.'b 1409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // ,"a'..'\\''.'b" // a'..'\''.'b 1410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // };// 1411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //const char *const s3 = "a..\\.b"; // a..\.b 1413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //const char (*s3_r) [] = { "a'..\\\\.'b" // a'..\\.'b 1414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // ,"a'..'\\\\'.'b" // a'..'\\'.'b 1415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // };// 1416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // // no catact operation, no choice, must be compact 1418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru srand((unsigned)time( NULL )); 1420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //Escaper l(Escaper::NO, Escaper::NO, Escaper::RAND_ESC); 1422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Pick *p = new Literal(str); 1423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Quote q(*p); 1424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1425ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru DUMP_R(TestQuote, (*p), 1); 1426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru DUMP_R(TestQuote, q, 20); 1427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 1428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UBool TestLiteral(){ 1430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char * s = "test string99."; 1431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Literal n(s); 1432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char * r = n.next(); 1433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return strcmp(s,r) == 0; 1434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UBool TestSequence(){ 1437ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Sequence seq; 1438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru seq.append(new Literal("abc ")); 1439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru seq.append(new Literal(", s")); 1440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return strcmp(seq.next(), "abc , s") == 0; 1442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UBool TestAlternation(){ 1444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru srand((unsigned)time( NULL )); 1445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Alternation alt; 1446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru alt.append(new Literal("aaa_10%"),10); 1447ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru alt.append(new Literal("bbb_0%"),0); 1448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru alt.append(new Literal("ccc_10%"),10); 1449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru alt.append(new Literal("ddddddd_50%"),50); 1450ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1451ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru DUMP_R(TestAlternation, alt, 50); 1452ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 1454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1455ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UBool TestBuffer(){ 1457ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Buffer_int t; 1458ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru t.append(1).append(0).append(5); 1459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int s = t.content_size(); 1460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int i=0; i<s; ++i){ 1461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru printf("%d\n", t[i]); 1462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1463ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 1464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UBool TestWeightedRand(){ 1467ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru srand((unsigned)time( NULL )); 1468ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Buffer_int t; 1469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru t.append(1).append(0).append(5); 1470ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru WeightedRand wr(&Buffer_int().append(10).append(0).append(50),4); 1471ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// WeightedRand wr(&t,3); 1472ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int i=0; i< 50; ++i){ 1473ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru printf("%d\n", wr.next()); 1474ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1475ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 1476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1477ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1478ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UBool TestRepeat(){ 1479ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru srand((unsigned)time( NULL )); 1480ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Repeat rep(new Literal("aaa1-5 "), 1, 5); 1481ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru DUMP_R(TestRepeat, rep, 50); 1482ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1483ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Repeat r2(new Literal("b{1,3}1%0%5% "), 1, 3, &Buffer_int().append(1).append(0).append(5)); 1484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru DUMP_R(TestRepeat, r2, 50); 1485ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1486ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Repeat r3(new Literal("aaa5-5 "), 5, 5); 1487ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru DUMP_R(TestRepeat, r3, 50); 1488ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1489ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 1490ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1491ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1492ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UBool TestVariable(){ 1493ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru SymbolTable tab; 1494ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Pick * value = new Literal("string1"); 1495ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Variable var1(&tab, "x", value); 1496ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1497ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Variable var2(&tab, "y"); 1498ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// tab.put(var2, value); // TOFIX: point alias/recursion problem 1499ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Pick * value2 = new Literal("string2"); 1500ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru tab.put(var2, value2); 1501ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1502ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Pick * value3 = new Literal("string3"); 1503ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Variable var3(&tab, "z"); 1504ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru tab.put("z", value3); 1505ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1506ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool pass; 1507ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = strcmp(var1.next(), value->next()) == 0; 1508ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && strcmp(var2.next(), value2->next()) == 0; 1509ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && strcmp(var3.next(), value3->next()) == 0; 1510ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return pass; 1511ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1512ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1513ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UBool TestSymbolTable(){ 1514ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Literal * n1 = new Literal("string1"); 1515ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Literal * n2 = new Literal("string2"); 1516ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru SymbolTable t; 1517ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru t.put("abc", n1); 1518ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru t.put("$aaa", n2); 1519ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// t.put("alias", n1); // TOFIX: point alias/recursion problem 1520ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru t.put("bbb"); 1521ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1522ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool pass; 1523ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = t.find(NULL) == SymbolTable::EMPTY; 1524ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && t.find("ccc") == SymbolTable::NO_VAR; 1525ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && t.find("bbb") == SymbolTable::NO_REF; 1526ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && t.find("abc") == SymbolTable::HAS_REF; 1527ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && t.find("$aaa") == SymbolTable::HAS_REF; 1528ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1529ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru t.reset(); 1530ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && t.find("abc") == SymbolTable::NO_VAR; 1531ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return pass; 1532ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1533ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1534ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1535ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UBool TestScanner(void){ 1536ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //const char str1[] = "$root = $command{0,5} $reset $mostRules{1,20};"; 1537ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //const char str1_r[][20] = {"$root", "=", "$command", "{", "0", ",", "5", "}", 1538ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // "$reset", "$mostRules", "{", "1", ",", "20", "}", ";"}; 1539ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1540ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char str2[] = "$p2 =(\\\\ $s $string $s)? 25%;"; 1541ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char str2_r[][20] = {"$p2", "=", "(", "\\", "$s", "$string", "$s", ")", "?", "25", "%", ";"}; 1542ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1543ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *str = str2; 1544ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char (*str_r)[20] = str2_r; 1545ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int tokenNum = sizeof(str2_r)/sizeof(char[20]); 1546ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1547ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Scanner t(str); 1548ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool pass = TRUE; 1549ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru t.getNextToken(); 1550ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int i = 0; 1551ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (pass){ 1552ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (t.tokenType == STREAM_END){ 1553ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass? i == tokenNum : FALSE; 1554ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break;//while 1555ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (t.tokenType == ERROR){ 1556ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = FALSE; 1557ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break;//while 1558ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1559ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = strcmp( &(t.token[0]), str_r[i++]) == 0; 1560ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru t.getNextToken(); 1561ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1562ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1563ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1564ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //const char ts[] = "$commandList = '['" 1565ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //" ( alternate ' ' $alternateOptions" 1566ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //" | backwards ' 2'" 1567ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //" | normalization ' ' $onoff " 1568ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //" | caseLevel ' ' $onoff " 1569ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //" | hiraganaQ ' ' $onoff" 1570ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //" | caseFirst ' ' $caseFirstOptions" 1571ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //" | strength ' ' $strengthOptions" 1572ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //" ) ']';" ; 1573ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1574ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //Scanner t2(ts); 1575ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //pass = TRUE; 1576ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //do { 1577ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // t2.getNextToken(); 1578ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // if (t2.tokenType == ERROR){ 1579ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // DumpScanner(t2); 1580ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // return FALSE; 1581ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // } 1582ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //}while (t.tokenType != STREAM_END); 1583ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1584ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return pass; 1585ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1586ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1587ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass TestParserT { 1588ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic: 1589ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool operator () (const char *const str, const int exp_error_offset = -1, const UBool dump = TRUE){ 1590ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Parser par(str); 1591ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (par.rules()){ 1592ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if ( exp_error_offset == -1){ 1593ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 1594ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru }else { 1595ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru DumpScanner(par.s,dump); 1596ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 1597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1598ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru }else { 1599ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return DumpScanner(par.s, dump) == exp_error_offset; 1600ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1601ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1602ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 1603ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1604ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool TestParser(){ 1605ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru TestParserT test; 1606ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1607ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool pass = TRUE; 1608ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && test ("$s = ' ' ? 50%;"); 1609ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && test("$x = ($var {1,2}) 3%;"); // legal 1610ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && test("$x = $var {1,2} 3% | b 4%;"); // legal 1611ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && test("$x = $var {1,2} 3%;"); // legal 1612ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && test("$m = $c ? 2% 4% | $r 5% | $n 25%;"); // legal 1613ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && test("$a = b ? 2% | c 5%;"); // legal 1614ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && test("$x = A B 5% C 10% | D;", 8, FALSE); // illegal 5% 1615ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && test("$x = aa 45% | bb 5% cc;", 19, FALSE);// illegal cc 1616ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && test("$x = (b 5%) (c 6%);"); // legal 1617ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && test("$x = (b 5%) c 6%;", 13, FALSE); // illegal 6% 1618ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && test("$x = b 5% (c 6%);", 9, FALSE); // illegal (c 6%) 1619ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && test("$x = b 5% c 6%;", 9, FALSE); // illegal c 6% 1620ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && test("$x = b 5%;"); // legal 1621ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && test("$x = aa 45% | bb 5% cc;", 19, FALSE);// illegal cc 1622ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && test("$x = a | b | c 4% | d 5%;"); // legal 1623ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && test("$s = ' ' ? 50% abc;"); // legal 1624ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && test("$s = a | c d | e f;"); // legal 1625ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && test( "$z = q 0% | p 1% | r 100%;"); // legal How to check parsed tree?? 1626ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1627ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && test("$s = ' ' ? 50%;"); 1628ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && test("$relationList = '<' | '<<' | ';' | '<<<' | ',' | '=';"); 1629ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && test("$p1 = ($string $s '|' $s)? 25%;"); 1630ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && test("$p2 = (\\\\ $s $string $s)? 25%;"); 1631ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && test("$rel2 = $p1 $string $s $p2;"); 1632ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && test("$relation = $relationList $s ($rel1 | $rel2) $crlf;"); 1633ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && test("$command = $commandList $crlf;"); 1634ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && test("$reset = '&' $s ($beforeList $s)? 10% ($positionList 100% | $string 10%) $crlf;"); 1635ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && test("$mostRules = $command 1% | $reset 5% | $relation 25%;"); 1636ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && test("$root = $command{0,5} $reset $mostRules{1,20};"); 1637ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1638ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char collationBNF[] = 1639ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "$s = ' '? 50%;" 1640ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "$crlf = '\r\n';" 1641ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1642ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "$alternateOptions = non'-'ignorable | shifted;" 1643ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "$onoff = on | off;" 1644ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "$caseFirstOptions = off | upper | lower;" 1645ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "$strengthOptions = '1' | '2' | '3' | '4' | 'I';" 1646ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "$commandList = '['" 1647ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru " ( alternate ' ' $alternateOptions" 1648ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru " | backwards ' 2'" 1649ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru " | normalization ' ' $onoff " 1650ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru " | caseLevel ' ' $onoff " 1651ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru " | hiraganaQ ' ' $onoff" 1652ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru " | caseFirst ' ' $caseFirstOptions" 1653ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru " | strength ' ' $strengthOptions" 1654ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru " ) ']';" 1655ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "$command = $commandList $crlf;" 1656ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1657ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "$ignorableTypes = (tertiary | secondary | primary) ' ' ignorable;" 1658ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "$allTypes = variable | regular | implicit | trailing | $ignorableTypes;" 1659ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "$positionList = '[' (first | last) ' ' $allTypes ']';" 1660ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1661ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "$beforeList = '[before ' ('1' | '2' | '3') ']';" 1662ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1663ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "$relationList = (" 1664ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru " '<'" 1665ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru " | '<<'" 1666ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru " | ';'" 1667ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru " | '<<<'" 1668ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru " | ','" 1669ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru " | '='" 1670ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ");" 1671ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "$string = $magic;" 1672ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "$rel1 = '[variable top]' $s;" 1673ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "$p1 = ($string $s '|' $s)? 25%;" 1674ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "$p2 = (\\\\ $s $string $s)? 25%;" 1675ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "$rel2 = $p1 $string $s $p2;" 1676ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "$relation = $relationList $s ($rel1 | $rel2) $crlf;" 1677ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1678ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "$reset = '&' $s ($beforeList $s)? 10% ($positionList 1% | $string 10%) $crlf;" 1679ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "$mostRules = $command 1% | $reset 5% | $relation 25%;" 1680ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "$root = $command{0,5} $reset $mostRules{1,20};" 1681ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ; 1682ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1683ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = pass && test(collationBNF); 1684ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1685ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1686ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return pass; 1687ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1688ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1689ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UBool TestMorph(){ 1690ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru srand((unsigned)time( NULL )); 1691ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1692ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Alternation * alt = new Alternation(); 1693ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1694ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (*alt) 1695ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru .append(new Literal("a")).append(new Literal("b")).append(new Literal("c")) 1696ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru .append(new Literal("d")).append(new Literal("e")).append(new Literal("f")) 1697ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru .append(new Literal("g")).append(new Literal("h")).append(new Literal("i")) 1698ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru .append(new Literal("j")).append(new Literal("k")).append(new Literal("l")) 1699ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru .append(new Literal("m")).append(new Literal("n")).append(new Literal("o")) 1700ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ; 1701ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1702ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Repeat * rep = new Repeat( alt ,5,5 ); 1703ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Morph m( *rep); 1704ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1705ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// DUMP_R(TestMorph,(*rep),20); 1706ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru DUMP_R(TestMorph,m,100); 1707ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1708ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 1709ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1710ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1711ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 1712ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1713ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UBool TestLanguageGenerator(){ 1714ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //LanguageGenerator g; 1715ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //const char *const s = "$s = p 0% | q 1%;"; 1716ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //g.parseBNF(s, "$s"); 1717ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool pass; 1718ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //= strcmp("q", g.next()) == 0; 1719ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1720ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char *const def = 1721ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //"$a = $b;" 1722ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //"$b = $c;" 1723ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //"$c = $t;" 1724ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //"$t = abc $z{1,2};" 1725ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //"$k = a | b | c | d | e | f | g ;" 1726ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //"$z = q 0% | p 1% | r 1%;" 1727ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru "$x = a ? 0%;" 1728ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ; // end of string 1729ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// const char * s = "abczz"; 1730ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 1731ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 1732ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LanguageGenerator g; 1733ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pass = g.parseBNF(def, "$x",TRUE); 1734ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//// LanguageGenerator g(collationBNF, "$root", "$magic", new MagicNode()); 1735ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 1736ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (pass != LanguageGenerator::OK) return FALSE; 1737ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1738ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru DUMP_R(TestLanguageGenerator, g, 20); 1739ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return pass; 1740ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1741ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ////UBool pass = strcmp(s,r) == 0; 1742ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1743ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //if (pass){ 1744ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // printf("TestRandomLanguageGenerator passed.\n"); 1745ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //} else { 1746ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // printf("TestRandomLanguageGenerator FAILED!!!\n"); 1747ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //} 1748ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //return pass; 1749ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1750ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1751ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid TestWbnf(void){ 1752ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru srand((unsigned)time( NULL )); 1753ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1754ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //CALL(TestLiteral); 1755ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //CALL(TestSequence); 1756ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //CALL(TestSymbolTable); 1757ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //CALL(TestVariable); 1758ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1759ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //TestRepeat(); 1760ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //TestAlternation(); 1761ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //TestMorph(); 1762ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1763ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //TestQuote(); 1764ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //TestBuffer(); 1765ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //TestWeightedRand(); 1766ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1767ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //CALL(TestScanner); 1768ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru //CALL(TestParser); 1769ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru CALL(TestLanguageGenerator); 1770ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1771ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1772