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