00001
00002
00003 #include <memory.h>
00004 #include <string.h>
00005 #include "ExScanner.h"
00006
00007
00008
00009 char* coco_string_create(const char* value) {
00010 char* data;
00011 int len = 0;
00012 if (value) { len =(int)strlen(value); }
00013 data = new char[len + 1];
00014 strncpy(data, value, len);
00015 data[len] = 0;
00016 return data;
00017 }
00018
00019 char* coco_string_create(const char* value , int startIndex, int length) {
00020 int len = 0;
00021 char* data;
00022
00023 if (value) { len = length; }
00024 data = new char[len + 1];
00025 strncpy(data, &(value[startIndex]), len);
00026 data[len] = 0;
00027
00028 return data;
00029 }
00030
00031 char* coco_string_create_upper(char* data) {
00032 if (!data) { return NULL; }
00033
00034 int dataLen = 0;
00035 if (data) { dataLen =(int)strlen(data); }
00036
00037 char* newData = new char[dataLen + 1];
00038
00039 for (int i = 0; i <= dataLen; ++i) {
00040 if (('a' <= data[i]) && (data[i] <= 'z')) {
00041 newData[i] = data[i] + ('A' - 'a');
00042 }
00043 else { newData[i] = data[i]; }
00044 }
00045
00046 newData[dataLen] = '\0';
00047 return newData;
00048 }
00049
00050 char* coco_string_create_lower(char* data) {
00051 if (!data) { return NULL; }
00052
00053 int dataLen = 0;
00054 if (data) { dataLen =(int)strlen(data); }
00055
00056 char* newData = new char[dataLen + 1];
00057
00058 for (int i = 0; i <= dataLen; ++i) {
00059 if (('A' <= data[i]) && (data[i] <= 'Z')) {
00060 newData[i] = data[i] - ('A'- 'a');
00061 }
00062 else { newData[i] = data[i]; }
00063 }
00064 newData[dataLen] = '\0';
00065 return newData;
00066 }
00067
00068 char* coco_string_create_append(const char* data1, const char* data2) {
00069 char* data;
00070 int data1Len = 0;
00071 int data2Len = 0;
00072
00073 if (data1) { data1Len =(int)strlen(data1); }
00074 if (data2) {data2Len =(int)strlen(data2); }
00075
00076 data = new char[data1Len + data2Len + 1];
00077
00078 if (data1) { strcpy(data, data1); }
00079 if (data2) { strcpy(data + data1Len, data2); }
00080
00081 data[data1Len + data2Len] = 0;
00082
00083 return data;
00084 }
00085
00086 char* coco_string_create_append(const char* target, const char appendix) {
00087 int targetLen = coco_string_length(target);
00088 char* data = new char[targetLen + 2];
00089 strncpy(data, target, targetLen);
00090 data[targetLen] = appendix;
00091 data[targetLen + 1] = 0;
00092 return data;
00093 }
00094
00095 void coco_string_delete(char* &data) {
00096 delete [] data;
00097 data = NULL;
00098 }
00099
00100 int coco_string_length(const char* data) {
00101 if (data) { return (int)strlen(data); }
00102 return 0;
00103 }
00104
00105 bool coco_string_endswith(char* data, char* end) {
00106 int dataLen =(int)strlen(data);
00107 int endLen =(int)strlen(end);
00108 return (endLen <= dataLen) && (strcmp(data + dataLen - endLen, end) == 0);
00109 }
00110
00111 int coco_string_indexof(char* data, char value) {
00112 char* chr = strchr(data, value);
00113
00114 if (chr) { return (int)(chr-data); }
00115 return -1;
00116 }
00117
00118 int coco_string_lastindexof(char* data, char value) {
00119 char* chr = strrchr(data, value);
00120
00121 if (chr) { return (int)(chr-data); }
00122 return -1;
00123 }
00124
00125 void coco_string_merge(char* &target, char* appendix) {
00126 if (!appendix) { return; }
00127 char* data = coco_string_create_append(target, appendix);
00128 delete [] target;
00129 target = data;
00130 }
00131
00132 bool coco_string_equal(char* data1, char* data2) {
00133 return strcmp( data1, data2 ) == 0;
00134 }
00135
00136 int coco_string_compareto(char* data1, char* data2) {
00137 return strcmp(data1, data2);
00138 }
00139
00140 int coco_string_hash(char* data) {
00141 int h = 0;
00142 if (!data) { return 0; }
00143 while (*data != 0) {
00144 h = (h * 7) ^ *data;
00145 ++data;
00146 }
00147 if (h < 0) { h = -h; }
00148 return h;
00149 }
00150
00151 using namespace Marsyas;
00152
00153 Token::Token() {
00154 kind = 0;
00155 pos = 0;
00156 col = 0;
00157 line = 0;
00158 val = NULL;
00159 next = NULL;
00160 }
00161
00162 Token::~Token() {
00163 coco_string_delete(val);
00164 }
00165
00166 #include <iostream>
00167 Buffer::Buffer(const char* s) {
00168 stream = NULL;
00169 this->isUserStream = true;
00170 int l; for (l=0;s[l]!='\0';l++);
00171 fileLen = bufLen = l;
00172
00173 if (bufLen>MAX_BUFFER_LENGTH) { bufLen=MAX_BUFFER_LENGTH; }
00174 buf = new char[bufLen];
00175 for (int i=0;i<fileLen;++i) { buf[i]=s[i]; }
00176 bufStart = 0;
00177 SetPos(0);
00178 if (bufLen == fileLen) Close();
00179 }
00180
00181 Buffer::Buffer(FILE* s, bool isUserStream) {
00182 stream = s; this->isUserStream = isUserStream;
00183 fseek(s, 0, SEEK_END);
00184 fileLen = bufLen = ftell(s);
00185 fseek(s, 0, SEEK_SET);
00186 buf = new char[MAX_BUFFER_LENGTH];
00187 bufStart = INT_MAX;
00188 SetPos(0);
00189 if (bufLen == fileLen) Close();
00190 }
00191
00192 Buffer::Buffer(Buffer *b) {
00193 buf = b->buf;
00194 b->buf = NULL;
00195 bufStart = b->bufStart;
00196 bufLen = b->bufLen;
00197 fileLen = b->fileLen;
00198 pos = b->pos;
00199 stream = b->stream;
00200 b->stream = NULL;
00201 isUserStream = b->isUserStream;
00202 }
00203
00204 Buffer::~Buffer() {
00205 Close();
00206 if (buf != NULL) {
00207 delete [] buf;
00208 buf = NULL;
00209 }
00210 }
00211
00212 void Buffer::Close() {
00213 if (!isUserStream && stream != NULL) {
00214 fclose(stream);
00215 stream = NULL;
00216 }
00217 }
00218
00219 int Buffer::Read() {
00220 if (pos < bufLen) {
00221 return buf[pos++];
00222 } else if (GetPos() < fileLen) {
00223 SetPos(GetPos());
00224 return buf[pos++];
00225 } else {
00226 return EoF;
00227 }
00228 }
00229
00230 int Buffer::Peek() {
00231 int curPos = GetPos();
00232 int ch = Read();
00233 SetPos(curPos);
00234 return ch;
00235 }
00236
00237 char* Buffer::GetString(int beg, int end) {
00238 int len = end - beg;
00239 char *buf = new char[len];
00240 int oldPos = GetPos();
00241 SetPos(beg);
00242 for (int i = 0; i < len; ++i) buf[i] = (char) Read();
00243 SetPos(oldPos);
00244 return buf;
00245 }
00246
00247 int Buffer::GetPos() {
00248 return pos + bufStart;
00249 }
00250
00251 void Buffer::SetPos(int value) {
00252 if (value < 0) value = 0;
00253 else if (value > fileLen) value = fileLen;
00254 if (value >= bufStart && value < bufStart + bufLen) {
00255 pos = value - bufStart;
00256 } else if (stream != NULL) {
00257 fseek(stream, value, SEEK_SET);
00258 bufLen = (int)fread(buf, sizeof(char), MAX_BUFFER_LENGTH, stream);
00259 bufStart = value; pos = 0;
00260 } else {
00261 pos = fileLen - bufStart;
00262 }
00263 }
00264
00265 int UTF8Buffer::Read() {
00266 int ch;
00267 do {
00268 ch = Buffer::Read();
00269
00270 } while ((ch >= 128) && ((ch & 0xC0) != 0xC0) && (ch != EOF));
00271 if (ch < 128 || ch == EOF) {
00272
00273
00274 } else if ((ch & 0xF0) == 0xF0) {
00275
00276 int c1 = ch & 0x07; ch = Buffer::Read();
00277 int c2 = ch & 0x3F; ch = Buffer::Read();
00278 int c3 = ch & 0x3F; ch = Buffer::Read();
00279 int c4 = ch & 0x3F;
00280 ch = (((((c1 << 6) | c2) << 6) | c3) << 6) | c4;
00281 } else if ((ch & 0xE0) == 0xE0) {
00282
00283 int c1 = ch & 0x0F; ch = Buffer::Read();
00284 int c2 = ch & 0x3F; ch = Buffer::Read();
00285 int c3 = ch & 0x3F;
00286 ch = (((c1 << 6) | c2) << 6) | c3;
00287 } else if ((ch & 0xC0) == 0xC0) {
00288
00289 int c1 = ch & 0x1F; ch = Buffer::Read();
00290 int c2 = ch & 0x3F;
00291 ch = (c1 << 6) | c2;
00292 }
00293 return ch;
00294 }
00295
00296 ExScanner::ExScanner(char* fileName) {
00297 FILE* stream;
00298 char *chFileName = coco_string_create(fileName);
00299 if ((stream = fopen(chFileName, "rb")) == NULL) {
00300 MRSWARN((std::string)"ExScanner: Cannot open file %s"+fileName);
00301 exit(1);
00302 }
00303 coco_string_delete(chFileName);
00304 buffer = new Buffer(stream, false);
00305 Init();
00306 }
00307
00308 ExScanner::ExScanner(FILE* s) {
00309 buffer = new Buffer(s, true);
00310 Init();
00311 }
00312
00313 ExScanner::ExScanner(char* s, int i) {
00314 (void) i;
00315 buffer = new Buffer(s);
00316 Init();
00317 }
00318 ExScanner::ExScanner() { tval=NULL; buffer=NULL; tail=NULL; }
00319 void ExScanner::setString(const char* s)
00320 {
00321 delete [] tval;
00322 delete buffer;
00323 while (tail!=NULL) { Token* y=tail->next; delete tail; tail=y; }
00324 buffer = new Buffer(s);
00325 Init();
00326 }
00327
00328 ExScanner::~ExScanner() {
00329 delete [] tval;
00330 delete buffer;
00331 while (tail!=NULL) { Token* y=tail->next; delete tail; tail=y; }
00332 }
00333
00334 void ExScanner::Init() {
00335 EOL = '\n';
00336 eofSym = 0;
00337 maxT = 61;
00338 noSym = 61;
00339 for (int i = 48; i <= 57; ++i) start.set(i, 52);
00340 for (int i = 46; i <= 46; ++i) start.set(i, 3);
00341 for (int i = 39; i <= 39; ++i) start.set(i, 4);
00342 for (int i = 65; i <= 90; ++i) start.set(i, 53);
00343 for (int i = 97; i <= 122; ++i) start.set(i, 53);
00344 for (int i = 47; i <= 47; ++i) start.set(i, 54);
00345 start.set(36, 55);
00346 start.set(62, 56);
00347 start.set(60, 57);
00348 start.set(43, 58);
00349 start.set(45, 59);
00350 start.set(42, 60);
00351 start.set(37, 61);
00352 start.set(38, 62);
00353 start.set(124, 63);
00354 start.set(94, 37);
00355 start.set(40, 38);
00356 start.set(41, 39);
00357 start.set(33, 64);
00358 start.set(61, 41);
00359 start.set(44, 45);
00360 start.set(123, 65);
00361 start.set(125, 46);
00362 start.set(64, 48);
00363 start.set(91, 49);
00364 start.set(93, 50);
00365 start.set(58, 51);
00366 start.set(Buffer::EoF, -1);
00367 keywords.set((char *)"/", 26);
00368 keywords.set((char *)".", 47);
00369 keywords.set((char *)"Stream", 51);
00370 keywords.set((char *)"true", 52);
00371 keywords.set((char *)"false", 53);
00372 keywords.set((char *)"map", 54);
00373 keywords.set((char *)"iter", 55);
00374 keywords.set((char *)"for", 56);
00375 keywords.set((char *)"rfor", 57);
00376 keywords.set((char *)"in", 58);
00377 keywords.set((char *)"use", 59);
00378 keywords.set((char *)"load", 60);
00379
00380
00381 tvalLength = 128;
00382 tval = new char[tvalLength];
00383
00384 pos = -1; line = 1; col = 0;
00385 oldEols = 0;
00386 NextCh();
00387 if (ch == 0xEF) {
00388 NextCh(); int ch1 = ch;
00389 NextCh(); int ch2 = ch;
00390 if (ch1 != 0xBB || ch2 != 0xBF) {
00391 MRSWARN("ExScanner: Illegal byte order mark at start of file.");
00392
00393 }
00394 Buffer *oldBuf = buffer;
00395 buffer = new UTF8Buffer(buffer); col = 0;
00396 delete oldBuf; oldBuf = NULL;
00397 NextCh();
00398 }
00399
00400
00401 tail = pt = tokens = CreateToken();
00402 pt->val=new char[1]; pt->val[0]='\0';
00403 }
00404
00405 void ExScanner::NextCh() {
00406 if (oldEols > 0) { ch = EOL; oldEols--; }
00407 else {
00408 pos = buffer->GetPos();
00409 ch = buffer->Read(); col++;
00410
00411
00412 if (ch == '\r' && buffer->Peek() != '\n') ch = EOL;
00413 if (ch == EOL) { line++; col = 0; }
00414 }
00415
00416 }
00417
00418 void ExScanner::AddCh() {
00419 if (tlen >= tvalLength) {
00420 tvalLength *= 2;
00421 char* newBuf = new char[tvalLength];
00422 memcpy(newBuf, tval, tlen*sizeof(char));
00423 delete tval;
00424 tval = newBuf;
00425 }
00426 tval[tlen++] = ch;
00427 NextCh();
00428 }
00429
00430
00431 bool ExScanner::Comment0() {
00432 int level = 1, pos0 = pos, line0 = line, col0 = col;
00433 (void) pos0; (void) col0;
00434 NextCh();
00435 for(;;) {
00436 if (ch == 10) {
00437 level--;
00438 if (level == 0) { oldEols = line - line0; NextCh(); return true; }
00439 NextCh();
00440 } else if (ch == buffer->EoF) return false;
00441 else NextCh();
00442 }
00443 }
00444
00445 bool ExScanner::Comment1() {
00446 int level = 1, pos0 = pos, line0 = line, col0 = col;
00447 NextCh();
00448 if (ch == '*') {
00449 NextCh();
00450 for(;;) {
00451 if (ch == '*') {
00452 NextCh();
00453 if (ch == ')') {
00454 level--;
00455 if (level == 0) { oldEols = line - line0; NextCh(); return true; }
00456 NextCh();
00457 }
00458 } else if (ch == '(') {
00459 NextCh();
00460 if (ch == '*') {
00461 level++; NextCh();
00462 }
00463 } else if (ch == buffer->EoF) return false;
00464 else NextCh();
00465 }
00466 } else {
00467 buffer->SetPos(pos0); NextCh(); line = line0; col = col0;
00468 }
00469 return false;
00470 }
00471
00472
00473 Token* ExScanner::CreateToken() { return new Token(); }
00474
00475 Token* ExScanner::NextToken() {
00476 while ((ch == L' ') || (ch >= 9) && (ch <= 10) || (ch == 13)) NextCh();
00477 if ((ch == '#') && (Comment0()) || (ch == '(') && Comment1()) return NextToken();
00478 int apx = 0;
00479 t = CreateToken();
00480 t->pos = pos; t->col = col; t->line = line;
00481 int state = start.state(ch);
00482 tlen = 0; AddCh();
00483
00484 switch (state) {
00485 case -1: { t->kind = eofSym; break; }
00486 case 0: { t->kind = noSym; break; }
00487 case 1:
00488 case_1:
00489 {
00490 tlen -= apx;
00491 buffer->SetPos(t->pos); NextCh(); line = t->line; col = t->col;
00492 for (int i = 0; i < tlen; ++i) NextCh();
00493 t->kind = 1; break;}
00494 case 2:
00495 case_2:
00496 if (ch >= '0' && ch <= '9') {AddCh(); goto case_2;}
00497 else {t->kind = 2; t->val = coco_string_create(tval, 0, tlen); t->kind = keywords.get(t->val, t->kind); return t;}
00498 case 3:
00499 case_3:
00500 if (ch >= '0' && ch <= '9') {AddCh(); goto case_3;}
00501 else {t->kind = 2; t->val = coco_string_create(tval, 0, tlen); t->kind = keywords.get(t->val, t->kind); return t;}
00502 case 4:
00503 case_4:
00504 if (ch == 39) {AddCh(); goto case_5;}
00505 else if ((ch <= '&') || (ch >= '(') && (ch <= 65535)) {AddCh(); goto case_4;}
00506 else {t->kind = noSym; break;}
00507 case 5:
00508 case_5:
00509 {t->kind = 3; break;}
00510 case 6:
00511 case_6:
00512 {t->kind = 4; break;}
00513 case 7:
00514 case_7:
00515 if (ch == '/') {AddCh(); goto case_8;}
00516 else if ((ch >= '0') && (ch <= '9') || (ch >= 'A') && (ch <= 'Z') || (ch == '_') || (ch >= 'a') && (ch <= 'z')) {AddCh(); goto case_7;}
00517 else {t->kind = noSym; break;}
00518 case 8:
00519 case_8:
00520 if ((ch >= 'A') && (ch <= 'Z') || (ch >= 'a') && (ch <= 'z')) {AddCh(); goto case_9;}
00521 else {t->kind = noSym; break;}
00522 case 9:
00523 case_9:
00524 if ((ch >= '0') && (ch <= '9') || (ch >= 'A') && (ch <= 'Z') || (ch == '_') || (ch >= 'a') && (ch <= 'z')) {AddCh(); goto case_10;}
00525 else {t->kind = 6; t->val = coco_string_create(tval, 0, tlen); t->kind = keywords.get(t->val, t->kind); return t;}
00526 case 10:
00527 case_10:
00528 if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch == '_' || ch >= 'a' && ch <= 'z') {AddCh(); goto case_10;}
00529 else if (ch == '/') {AddCh(); goto case_11;}
00530 else {t->kind = 6; t->val = coco_string_create(tval, 0, tlen); t->kind = keywords.get(t->val, t->kind); return t;}
00531 case 11:
00532 case_11:
00533 if (ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z') {AddCh(); goto case_12;}
00534 else {t->kind = noSym; break;}
00535 case 12:
00536 case_12:
00537 if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch == '_' || ch >= 'a' && ch <= 'z') {AddCh(); goto case_66;}
00538 else if (ch == '/') {AddCh(); goto case_11;}
00539 else {t->kind = 6; t->val = coco_string_create(tval, 0, tlen); t->kind = keywords.get(t->val, t->kind); return t;}
00540 case 13:
00541 case_13:
00542 if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch == '_' || ch >= 'a' && ch <= 'z') {AddCh(); goto case_13;}
00543 else if (ch == '/') {AddCh(); goto case_14;}
00544 else {t->kind = 6; t->val = coco_string_create(tval, 0, tlen); t->kind = keywords.get(t->val, t->kind); return t;}
00545 case 14:
00546 case_14:
00547 if (ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z') {AddCh(); goto case_15;}
00548 else {t->kind = noSym; break;}
00549 case 15:
00550 case_15:
00551 if (ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z') {AddCh(); goto case_67;}
00552 else if (ch == '/') {AddCh(); goto case_14;}
00553 else if (ch >= '0' && ch <= '9' || ch == '_') {AddCh(); goto case_15;}
00554 else {t->kind = 6; t->val = coco_string_create(tval, 0, tlen); t->kind = keywords.get(t->val, t->kind); return t;}
00555 case 16:
00556 case_16:
00557 {t->kind = 7; break;}
00558 case 17:
00559 case_17:
00560 if (ch == '>') {AddCh(); goto case_18;}
00561 else {t->kind = noSym; break;}
00562 case 18:
00563 case_18:
00564 {t->kind = 9; break;}
00565 case 19:
00566 case_19:
00567 {t->kind = 10; break;}
00568 case 20:
00569 case_20:
00570 if (ch == '>') {AddCh(); goto case_21;}
00571 else {t->kind = noSym; break;}
00572 case 21:
00573 case_21:
00574 {t->kind = 11; break;}
00575 case 22:
00576 case_22:
00577 if (ch == '>') {AddCh(); goto case_23;}
00578 else {t->kind = noSym; break;}
00579 case 23:
00580 case_23:
00581 {t->kind = 12; break;}
00582 case 24:
00583 case_24:
00584 if (ch == '>') {AddCh(); goto case_25;}
00585 else {t->kind = noSym; break;}
00586 case 25:
00587 case_25:
00588 {t->kind = 13; break;}
00589 case 26:
00590 case_26:
00591 {t->kind = 14; break;}
00592 case 27:
00593 case_27:
00594 {t->kind = 15; break;}
00595 case 28:
00596 case_28:
00597 {t->kind = 16; break;}
00598 case 29:
00599 case_29:
00600 {t->kind = 17; break;}
00601 case 30:
00602 case_30:
00603 {t->kind = 18; break;}
00604 case 31:
00605 case_31:
00606 if (ch == '>') {AddCh(); goto case_32;}
00607 else {t->kind = noSym; break;}
00608 case 32:
00609 case_32:
00610 {t->kind = 19; break;}
00611 case 33:
00612 case_33:
00613 if (ch == '>') {AddCh(); goto case_34;}
00614 else {t->kind = noSym; break;}
00615 case 34:
00616 case_34:
00617 {t->kind = 20; break;}
00618 case 35:
00619 case_35:
00620 {t->kind = 21; break;}
00621 case 36:
00622 case_36:
00623 {t->kind = 22; break;}
00624 case 37:
00625 {t->kind = 28; break;}
00626 case 38:
00627 {t->kind = 29; break;}
00628 case 39:
00629 {t->kind = 30; break;}
00630 case 40:
00631 case_40:
00632 {t->kind = 32; break;}
00633 case 41:
00634 {t->kind = 34; break;}
00635 case 42:
00636 case_42:
00637 {t->kind = 35; break;}
00638 case 43:
00639 case_43:
00640 {t->kind = 37; break;}
00641 case 44:
00642 case_44:
00643 {t->kind = 39; break;}
00644 case 45:
00645 {t->kind = 42; break;}
00646 case 46:
00647 {t->kind = 44; break;}
00648 case 47:
00649 case_47:
00650 {t->kind = 45; break;}
00651 case 48:
00652 {t->kind = 46; break;}
00653 case 49:
00654 {t->kind = 48; break;}
00655 case 50:
00656 {t->kind = 49; break;}
00657 case 51:
00658 {t->kind = 50; break;}
00659 case 52:
00660 case_52:
00661 if (ch >= '0' && ch <= '9') {AddCh(); goto case_52;}
00662 else if (ch == '.') {apx++; AddCh(); goto case_68;}
00663 else {t->kind = 1; break;}
00664 case 53:
00665 case_53:
00666 if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z') {AddCh(); goto case_53;}
00667 else if (ch == '/') {AddCh(); goto case_8;}
00668 else if (ch == '_') {AddCh(); goto case_7;}
00669 else {t->kind = 5; t->val = coco_string_create(tval, 0, tlen); t->kind = keywords.get(t->val, t->kind); return t;}
00670 case 54:
00671 if (ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z') {AddCh(); goto case_13;}
00672 else if (ch == '>') {AddCh(); goto case_22;}
00673 else {t->kind = 6; t->val = coco_string_create(tval, 0, tlen); t->kind = keywords.get(t->val, t->kind); return t;}
00674 case 55:
00675 if (ch == 'f' || ch == 't') {AddCh(); goto case_6;}
00676 else {t->kind = noSym; break;}
00677 case 56:
00678 if (ch == '>') {AddCh(); goto case_16;}
00679 else if (ch == '=') {AddCh(); goto case_43;}
00680 else {t->kind = 36; break;}
00681 case 57:
00682 if (ch == '<') {AddCh(); goto case_69;}
00683 else if (ch == '-') {AddCh(); goto case_40;}
00684 else if (ch == '=') {AddCh(); goto case_44;}
00685 else {t->kind = 38; break;}
00686 case 58:
00687 if (ch == '>') {AddCh(); goto case_17;}
00688 else {t->kind = 23; break;}
00689 case 59:
00690 if (ch == '>') {AddCh(); goto case_70;}
00691 else {t->kind = 24; break;}
00692 case 60:
00693 if (ch == '>') {AddCh(); goto case_20;}
00694 else {t->kind = 25; break;}
00695 case 61:
00696 if (ch == '>') {AddCh(); goto case_24;}
00697 else {t->kind = 27; break;}
00698 case 62:
00699 if (ch == '>') {AddCh(); goto case_31;}
00700 else {t->kind = 40; break;}
00701 case 63:
00702 if (ch == '>') {AddCh(); goto case_33;}
00703 else {t->kind = 41; break;}
00704 case 64:
00705 if (ch == '=') {AddCh(); goto case_42;}
00706 else {t->kind = 33; break;}
00707 case 65:
00708 if (ch == '?') {AddCh(); goto case_47;}
00709 else {t->kind = 43; break;}
00710 case 66:
00711 case_66:
00712 if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch == '_' || ch >= 'a' && ch <= 'z') {AddCh(); goto case_66;}
00713 else if (ch == '/') {AddCh(); goto case_11;}
00714 else {t->kind = 6; t->val = coco_string_create(tval, 0, tlen); t->kind = keywords.get(t->val, t->kind); return t;}
00715 case 67:
00716 case_67:
00717 if (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'Z' || ch == '_' || ch >= 'a' && ch <= 'z') {AddCh(); goto case_67;}
00718 else if (ch == '/') {AddCh(); goto case_14;}
00719 else {t->kind = 6; t->val = coco_string_create(tval, 0, tlen); t->kind = keywords.get(t->val, t->kind); return t;}
00720 case 68:
00721 case_68:
00722 if (ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z') {apx++; AddCh(); goto case_1;}
00723 else if (ch >= '0' && ch <= '9') {apx = 0; AddCh(); goto case_2;}
00724 else {t->kind = 2; t->val = coco_string_create(tval, 0, tlen); t->kind = keywords.get(t->val, t->kind); return t;}
00725 case 69:
00726 case_69:
00727 if (ch == '+') {AddCh(); goto case_26;}
00728 else if (ch == '-') {AddCh(); goto case_27;}
00729 else if (ch == '*') {AddCh(); goto case_28;}
00730 else if (ch == '/') {AddCh(); goto case_29;}
00731 else if (ch == '%') {AddCh(); goto case_30;}
00732 else if (ch == '&') {AddCh(); goto case_35;}
00733 else if (ch == '|') {AddCh(); goto case_36;}
00734 else {t->kind = 8; break;}
00735 case 70:
00736 case_70:
00737 if (ch == '>') {AddCh(); goto case_19;}
00738 else {t->kind = 31; break;}
00739
00740 }
00741 t->val=coco_string_create(tval, 0, tlen);
00742 return t;
00743 }
00744
00745
00746 Token* ExScanner::Scan() {
00747 if (tokens->next == NULL) { tokens->next=NextToken(); }
00748 tokens=tokens->next; pt=tokens;
00749 return tokens;
00750 }
00751
00752
00753 Token* ExScanner::Peek() {
00754 if (pt->next == NULL) {
00755 do {
00756 pt = pt->next = NextToken();
00757 } while (pt->kind > maxT);
00758 } else {
00759 do {
00760 pt = pt->next;
00761 } while (pt->kind > maxT);
00762 }
00763 return pt;
00764 }
00765
00766
00767 void ExScanner::ResetPeek() {
00768 pt = tokens;
00769 }