00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #if !defined(MARSYAS_EX_SCANNER_H)
00020 #define MARSYAS_EX_SCANNER_H
00021
00022 #include <limits.h>
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <string.h>
00026 #include <cstring>
00027 #include "common_header.h"
00028
00029 #if _MSC_VER >= 1400
00030 #define coco_sprintf sprintf_s
00031 #elif _MSC_VER >= 1300
00032 #define coco_sprintf _snprintf
00033 #elif defined __GNUC__
00034 #define coco_sprintf snprintf
00035 #else
00036 #error unknown compiler!
00037 #endif
00038
00039 #define COCO_WCHAR_MAX 65535
00040 #define MAX_BUFFER_LENGTH (64*1024)
00041 #define HEAP_BLOCK_SIZE (64*1024)
00042
00043
00044 char* coco_string_create(const char* value);
00045 char* coco_string_create(const char* value , int startIndex, int length);
00046 char* coco_string_create_upper(char* data);
00047 char* coco_string_create_lower(char* data);
00048 char* coco_string_create_append(const char* data1, const char* data2);
00049 char* coco_string_create_append(const char* data, const char value);
00050 void coco_string_delete(char* &data);
00051 int coco_string_length(const char* data);
00052 bool coco_string_endswith(char* data, char* value);
00053 int coco_string_indexof(char* data, char value);
00054 int coco_string_lastindexof(char* data, char value);
00055 void coco_string_merge(char* &data, char* value);
00056 bool coco_string_equal(char* data1, char* data2);
00057 int coco_string_compareto(char* data1, char* data2);
00058 int coco_string_hash(char* data);
00059
00060
00061 namespace Marsyas {
00062
00063 class Token
00064 {
00065 public:
00066 int kind;
00067 int pos;
00068 int col;
00069 int line;
00070 char* val;
00071 Token *next;
00072
00073 Token();
00074 ~Token();
00075
00076 };
00077
00078 class Buffer {
00079 private:
00080 char *buf;
00081 int bufStart;
00082 int bufLen;
00083 int fileLen;
00084 int pos;
00085 FILE* stream;
00086 bool isUserStream;
00087
00088 public:
00089 static const int EoF = COCO_WCHAR_MAX + 1;
00090
00091 Buffer(FILE* s, bool isUserStream);
00092 Buffer(const char* s);
00093 Buffer(Buffer *b);
00094 virtual ~Buffer();
00095
00096 virtual void Close();
00097 virtual int Read();
00098 virtual int Peek();
00099 virtual char* GetString(int beg, int end);
00100 virtual int GetPos();
00101 virtual void SetPos(int value);
00102 };
00103
00104 class UTF8Buffer : public Buffer {
00105 public:
00106 UTF8Buffer(Buffer *b) : Buffer(b) {};
00107 virtual int Read();
00108 };
00109
00110
00111
00112
00113 class StartStates {
00114 private:
00115 class Elem {
00116 public:
00117 int key, val;
00118 Elem *next;
00119 Elem(int key, int val) { this->key = key; this->val = val; next = NULL; }
00120 };
00121
00122 Elem **tab;
00123
00124 public:
00125 StartStates() { tab = new Elem*[128]; memset(tab, 0, 128 * sizeof(Elem*)); }
00126 virtual ~StartStates() {
00127 for (int i = 0; i < 128; ++i) {
00128 Elem *e = tab[i];
00129 while (e != NULL) {
00130 Elem *next = e->next;
00131 delete e;
00132 e = next;
00133 }
00134 }
00135 delete [] tab;
00136 }
00137
00138 void set(int key, int val) {
00139 Elem *e = new Elem(key, val);
00140 int k = key % 128;
00141 e->next = tab[k]; tab[k] = e;
00142 }
00143
00144 int state(int key) {
00145 Elem *e = tab[key % 128];
00146 while (e != NULL && e->key != key) e = e->next;
00147 return e == NULL ? 0 : e->val;
00148 }
00149 };
00150
00151
00152
00153
00154
00155 class KeywordMap {
00156 private:
00157 class Elem {
00158 public:
00159 char* key;
00160 int val;
00161 Elem *next;
00162 Elem(char* key, int val) { this->key = coco_string_create(key); this->val = val; next = NULL; }
00163 virtual ~Elem() { coco_string_delete(key); }
00164 };
00165
00166 Elem **tab;
00167
00168 public:
00169 KeywordMap() { tab = new Elem*[128]; memset(tab, 0, 128 * sizeof(Elem*)); }
00170 virtual ~KeywordMap() {
00171 for (int i = 0; i < 128; ++i) {
00172 Elem *e = tab[i];
00173 while (e != NULL) {
00174 Elem *next = e->next;
00175 delete e;
00176 e = next;
00177 }
00178 }
00179 delete [] tab;
00180 }
00181
00182 void set(char* key, int val) {
00183 Elem *e = new Elem(key, val);
00184 int k = coco_string_hash(key) % 128;
00185 e->next = tab[k]; tab[k] = e;
00186 }
00187
00188 int get(char* key, int defaultVal) {
00189 Elem *e = tab[coco_string_hash(key) % 128];
00190 while (e != NULL && !coco_string_equal(e->key, key)) e = e->next;
00191 return e == NULL ? defaultVal : e->val;
00192 }
00193 };
00194
00195 class ExScanner {
00196 private:
00197 char EOL;
00198 int eofSym;
00199 int noSym;
00200 int maxT;
00201 int charSetSize;
00202 StartStates start;
00203 KeywordMap keywords;
00204
00205 Token *t;
00206 char* tval;
00207 int tvalLength;
00208 int tlen;
00209
00210 Token *tokens;
00211 Token *pt;
00212 Token* tail;
00213 int ch;
00214
00215 int pos;
00216 int line;
00217 int col;
00218 int oldEols;
00219
00220 Token* CreateToken();
00221
00222 void Init();
00223 void NextCh();
00224 void AddCh();
00225 bool Comment0();
00226 bool Comment1();
00227
00228 Token* NextToken();
00229
00230
00231 public:
00232 Buffer *buffer;
00233 ExScanner(char* data, int i);
00234 ExScanner(char* fileName);
00235 ExScanner(FILE* s);
00236 ExScanner();
00237 ~ExScanner();
00238 Token* Scan();
00239 Token* Peek();
00240 void ResetPeek();
00241 void setString(const char* s);
00242
00243 };
00244
00245 };
00246
00247 #endif // !defined(MARSYAS_EX_SCANNER_H)
00248