sqlexer.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  1. /*
  2. see copyright notice in squirrel.h
  3. */
  4. #include "sqpcheader.h"
  5. #include <ctype.h>
  6. #include <stdlib.h>
  7. #include <limits.h>
  8. #include "sqtable.h"
  9. #include "sqstring.h"
  10. #include "sqcompiler.h"
  11. #include "sqlexer.h"
  12. #define CUR_CHAR (_currdata)
  13. #define RETURN_TOKEN(t) { _prevtoken = _curtoken; _curtoken = t; return t;}
  14. #define IS_EOB() (CUR_CHAR <= SQUIRREL_EOB)
  15. #define NEXT() {Next();_currentcolumn++;}
  16. #define INIT_TEMP_STRING() { _longstr.resize(0);}
  17. #define APPEND_CHAR(c) { _longstr.push_back(c);}
  18. #define TERMINATE_BUFFER() {_longstr.push_back(_SC('\0'));}
  19. #define ADD_KEYWORD(key,id) tbl->NewSlot( SQString::Create(_sharedstate, _SC(#key)) ,SQInteger(id))
  20. SQLexer::SQLexer(){_keywords=0;}
  21. SQLexer::~SQLexer()
  22. {
  23. _keywords->Release();
  24. }
  25. void SQLexer::Init(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up,CompilerErrorFunc efunc,void *ed)
  26. {
  27. _errfunc = efunc;
  28. _errtarget = ed;
  29. _sharedstate = ss;
  30. if(_keywords) _keywords->Release();
  31. _keywords = GetKeywords();
  32. _readf = rg;
  33. _up = up;
  34. _lasttokenline = _currentline = 1;
  35. _currentcolumn = 0;
  36. _prevtoken = -1;
  37. _reached_eof = SQFalse;
  38. Next();
  39. }
  40. SQTable * SQLexer::GetKeywords()
  41. {
  42. SQTable *tbl = SQTable::Create(_sharedstate, 58 /*26*/);
  43. ADD_KEYWORD(while, TK_WHILE);
  44. ADD_KEYWORD(do, TK_DO);
  45. ADD_KEYWORD(if, TK_IF);
  46. ADD_KEYWORD(else, TK_ELSE);
  47. ADD_KEYWORD(break, TK_BREAK);
  48. ADD_KEYWORD(continue, TK_CONTINUE);
  49. ADD_KEYWORD(return, TK_RETURN);
  50. ADD_KEYWORD(null, TK_NULL);
  51. ADD_KEYWORD(NULL, TK_NULL);
  52. ADD_KEYWORD(function, TK_FUNCTION);
  53. ADD_KEYWORD(local, TK_LOCAL);
  54. ADD_KEYWORD(var, TK_LOCAL);
  55. ADD_KEYWORD(char_t, TK_LOCAL_CHAR_T);
  56. ADD_KEYWORD(wchar_t, TK_LOCAL_WCHAR_T);
  57. ADD_KEYWORD(bool_t, TK_LOCAL_BOOL_T);
  58. ADD_KEYWORD(table_t, TK_LOCAL_TABLE_T);
  59. ADD_KEYWORD(array_t, TK_LOCAL_ARRAY_T);
  60. ADD_KEYWORD(int8_t, TK_LOCAL_INT8_T);
  61. ADD_KEYWORD(int16_t, TK_LOCAL_INT16_T);
  62. ADD_KEYWORD(int32_t, TK_LOCAL_INT32_T);
  63. ADD_KEYWORD(int64_t, TK_LOCAL_INT64_T);
  64. ADD_KEYWORD(int_t, TK_LOCAL_INT_T);
  65. ADD_KEYWORD(uint8_t, TK_LOCAL_UINT8_T);
  66. ADD_KEYWORD(uint16_t, TK_LOCAL_UINT16_T);
  67. ADD_KEYWORD(uint32_t, TK_LOCAL_UINT32_T);
  68. ADD_KEYWORD(uint64_t, TK_LOCAL_UINT64_T);
  69. ADD_KEYWORD(uint_t, TK_LOCAL_UINT_T);
  70. ADD_KEYWORD(float_t, TK_LOCAL_FLOAT_T);
  71. ADD_KEYWORD(double_t, TK_LOCAL_DOUBLE_T);
  72. ADD_KEYWORD(long_double_t, TK_LOCAL_LONG_DOUBLE_T);
  73. ADD_KEYWORD(for, TK_FOR);
  74. ADD_KEYWORD(foreach, TK_FOREACH);
  75. ADD_KEYWORD(in, TK_IN);
  76. ADD_KEYWORD(typeof, TK_TYPEOF);
  77. ADD_KEYWORD(base, TK_BASE);
  78. ADD_KEYWORD(delete, TK_DELETE);
  79. ADD_KEYWORD(try, TK_TRY);
  80. ADD_KEYWORD(catch, TK_CATCH);
  81. ADD_KEYWORD(throw, TK_THROW);
  82. ADD_KEYWORD(clone, TK_CLONE);
  83. ADD_KEYWORD(yield, TK_YIELD);
  84. ADD_KEYWORD(resume, TK_RESUME);
  85. ADD_KEYWORD(switch, TK_SWITCH);
  86. ADD_KEYWORD(case, TK_CASE);
  87. ADD_KEYWORD(default, TK_DEFAULT);
  88. ADD_KEYWORD(this, TK_THIS);
  89. ADD_KEYWORD(class,TK_CLASS);
  90. ADD_KEYWORD(extends,TK_EXTENDS);
  91. ADD_KEYWORD(constructor,TK_CONSTRUCTOR);
  92. ADD_KEYWORD(instanceof,TK_INSTANCEOF);
  93. ADD_KEYWORD(true,TK_TRUE);
  94. ADD_KEYWORD(false,TK_FALSE);
  95. ADD_KEYWORD(static,TK_STATIC);
  96. ADD_KEYWORD(enum,TK_ENUM);
  97. ADD_KEYWORD(const,TK_CONST);
  98. ADD_KEYWORD(__LINE__,TK___LINE__);
  99. ADD_KEYWORD(__FUNCTION__,TK___FUNCTION__);
  100. ADD_KEYWORD(__FILE__,TK___FILE__);
  101. ADD_KEYWORD(new,TK_IGNORE);
  102. return tbl;
  103. }
  104. void SQLexer::Error(const SQChar *err)
  105. {
  106. _errfunc(_errtarget,err);
  107. }
  108. void SQLexer::Next()
  109. {
  110. SQInteger t = _readf(_up);
  111. if(t > MAX_CHAR) Error(_SC("Invalid character"));
  112. if(t != 0) {
  113. _currdata = (LexChar)t;
  114. return;
  115. }
  116. _currdata = SQUIRREL_EOB;
  117. _reached_eof = SQTrue;
  118. }
  119. const SQChar *SQLexer::Tok2Str(SQInteger tok)
  120. {
  121. SQObjectPtr itr, key, val;
  122. SQInteger nitr;
  123. while((nitr = _keywords->Next(false,itr, key, val)) != -1) {
  124. itr = (SQInteger)nitr;
  125. if(((SQInteger)_integer(val)) == tok)
  126. return _stringval(key);
  127. }
  128. return NULL;
  129. }
  130. void SQLexer::LexBlockComment()
  131. {
  132. bool done = false;
  133. while(!done) {
  134. switch(CUR_CHAR) {
  135. case _SC('*'): { NEXT(); if(CUR_CHAR == _SC('/')) { done = true; NEXT(); }}; continue;
  136. case _SC('\n'): _currentline++; NEXT(); continue;
  137. case SQUIRREL_EOB: Error(_SC("missing \"*/\" in comment"));
  138. default: NEXT();
  139. }
  140. }
  141. }
  142. void SQLexer::LexLineComment()
  143. {
  144. do { NEXT(); } while (CUR_CHAR != _SC('\n') && (!IS_EOB()));
  145. }
  146. SQInteger SQLexer::Lex()
  147. {
  148. _lasttokenline = _currentline;
  149. while(CUR_CHAR != SQUIRREL_EOB) {
  150. switch(CUR_CHAR){
  151. case _SC('\t'): case _SC('\r'): case _SC(' '): NEXT(); continue;
  152. case _SC('\n'):
  153. _currentline++;
  154. _prevtoken=_curtoken;
  155. _curtoken=_SC('\n');
  156. NEXT();
  157. _currentcolumn=1;
  158. continue;
  159. case _SC('#'): LexLineComment(); continue;
  160. case _SC('/'):
  161. NEXT();
  162. switch(CUR_CHAR){
  163. case _SC('*'):
  164. NEXT();
  165. LexBlockComment();
  166. continue;
  167. case _SC('/'):
  168. LexLineComment();
  169. continue;
  170. case _SC('='):
  171. NEXT();
  172. RETURN_TOKEN(TK_DIVEQ);
  173. continue;
  174. case _SC('>'):
  175. NEXT();
  176. RETURN_TOKEN(TK_ATTR_CLOSE);
  177. continue;
  178. default:
  179. RETURN_TOKEN('/');
  180. }
  181. case _SC('='):
  182. NEXT();
  183. if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('=') }
  184. else { NEXT(); RETURN_TOKEN(TK_EQ); }
  185. case _SC('<'):
  186. NEXT();
  187. switch(CUR_CHAR) {
  188. case _SC('='):
  189. NEXT();
  190. if(CUR_CHAR == _SC('>')) {
  191. NEXT();
  192. RETURN_TOKEN(TK_3WAYSCMP);
  193. }
  194. RETURN_TOKEN(TK_LE)
  195. break;
  196. case _SC('-'): NEXT(); RETURN_TOKEN(TK_NEWSLOT); break;
  197. case _SC('<'): NEXT(); RETURN_TOKEN(TK_SHIFTL); break;
  198. case _SC('/'): NEXT(); RETURN_TOKEN(TK_ATTR_OPEN); break;
  199. }
  200. RETURN_TOKEN('<');
  201. case _SC('>'):
  202. NEXT();
  203. if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_GE);}
  204. else if(CUR_CHAR == _SC('>')){
  205. NEXT();
  206. if(CUR_CHAR == _SC('>')){
  207. NEXT();
  208. RETURN_TOKEN(TK_USHIFTR);
  209. }
  210. RETURN_TOKEN(TK_SHIFTR);
  211. }
  212. else { RETURN_TOKEN('>') }
  213. case _SC('!'):
  214. NEXT();
  215. if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('!')}
  216. else { NEXT(); RETURN_TOKEN(TK_NE); }
  217. case _SC('@'): {
  218. SQInteger stype;
  219. NEXT();
  220. if(CUR_CHAR != _SC('"')) {
  221. RETURN_TOKEN('@');
  222. }
  223. if((stype=ReadString('"',true))!=-1) {
  224. RETURN_TOKEN(stype);
  225. }
  226. Error(_SC("error parsing the string"));
  227. }
  228. case _SC('"'):
  229. case _SC('\''): {
  230. SQInteger stype;
  231. if((stype=ReadString(CUR_CHAR,false))!=-1){
  232. RETURN_TOKEN(stype);
  233. }
  234. Error(_SC("error parsing the string"));
  235. }
  236. case _SC('{'): case _SC('}'): case _SC('('): case _SC(')'): case _SC('['): case _SC(']'):
  237. case _SC(';'): case _SC(','): case _SC('?'): case _SC('~'):
  238. {
  239. SQInteger ret = CUR_CHAR;
  240. NEXT();
  241. if(ret == _SC('[') && CUR_CHAR == _SC('=')){
  242. //lets try lua literal delimiters
  243. SQInteger stype;
  244. if((stype=ReadString(CUR_CHAR,true))!=-1){
  245. RETURN_TOKEN(stype);
  246. }
  247. Error(_SC("error parsing the string"));
  248. }
  249. else RETURN_TOKEN(ret);
  250. }
  251. case _SC('.'):
  252. NEXT();
  253. if (CUR_CHAR != _SC('.')){ RETURN_TOKEN('.') }
  254. NEXT();
  255. if (CUR_CHAR != _SC('.')){ Error(_SC("invalid token '..'")); }
  256. NEXT();
  257. RETURN_TOKEN(TK_VARPARAMS);
  258. case _SC('^'):
  259. NEXT();
  260. //if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_BIT_XOR_EQ);}
  261. RETURN_TOKEN('^');
  262. case _SC('&'):
  263. NEXT();
  264. //if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_BIT_AND_EQ);}
  265. if (CUR_CHAR != _SC('&')){ RETURN_TOKEN('&') }
  266. else { NEXT(); RETURN_TOKEN(TK_AND); }
  267. case _SC('|'):
  268. NEXT();
  269. //if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_BIT_OR_EQ);}
  270. if (CUR_CHAR != _SC('|')){ RETURN_TOKEN('|') }
  271. else { NEXT(); RETURN_TOKEN(TK_OR); }
  272. case _SC(':'):
  273. NEXT();
  274. if (CUR_CHAR != _SC(':')){ RETURN_TOKEN(':') }
  275. else { NEXT(); RETURN_TOKEN(TK_DOUBLE_COLON); }
  276. case _SC('*'):
  277. NEXT();
  278. if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MULEQ);}
  279. else RETURN_TOKEN('*');
  280. case _SC('%'):
  281. NEXT();
  282. if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MODEQ);}
  283. else RETURN_TOKEN('%');
  284. case _SC('-'):
  285. NEXT();
  286. if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MINUSEQ);}
  287. else if (CUR_CHAR == _SC('-')){ NEXT(); RETURN_TOKEN(TK_MINUSMINUS);}
  288. else if (CUR_CHAR == _SC('>')){ NEXT(); RETURN_TOKEN('.');} //accept C/C++ like pointers
  289. else RETURN_TOKEN('-');
  290. case _SC('+'):
  291. NEXT();
  292. if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_PLUSEQ);}
  293. else if (CUR_CHAR == _SC('+')){ NEXT(); RETURN_TOKEN(TK_PLUSPLUS);}
  294. else RETURN_TOKEN('+');
  295. case SQUIRREL_EOB:
  296. return 0;
  297. default:{
  298. if (scisdigit(CUR_CHAR)) {
  299. SQInteger ret = ReadNumber();
  300. RETURN_TOKEN(ret);
  301. }
  302. else if (scisalpha(CUR_CHAR) || CUR_CHAR == _SC('_')) {
  303. SQInteger t = ReadID();
  304. RETURN_TOKEN(t);
  305. }
  306. else {
  307. SQInteger c = CUR_CHAR;
  308. if (sciscntrl((int)c)) Error(_SC("unexpected character(control)"));
  309. NEXT();
  310. RETURN_TOKEN(c);
  311. }
  312. RETURN_TOKEN(0);
  313. }
  314. }
  315. }
  316. return 0;
  317. }
  318. SQInteger SQLexer::GetIDType(SQChar *s)
  319. {
  320. SQObjectPtr t;
  321. if(_keywords->Get(SQString::Create(_sharedstate, s), t)) {
  322. return SQInteger(_integer(t));
  323. }
  324. return TK_IDENTIFIER;
  325. }
  326. SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim)
  327. {
  328. INIT_TEMP_STRING();
  329. SQInteger start_equals = 0;
  330. if(ndelim == _SC('=')){
  331. //lua like literal
  332. while(!IS_EOB() && CUR_CHAR == _SC('=')) {
  333. ++start_equals;
  334. NEXT();
  335. }
  336. if(CUR_CHAR != _SC('[')){
  337. //it's not a lua literal delimiter
  338. Error(_SC("expect '[' on literal delimiter"));
  339. return -1;
  340. }
  341. ndelim = _SC(']');
  342. }
  343. NEXT();
  344. if(IS_EOB()) return -1;
  345. if(start_equals && CUR_CHAR == _SC('\n')) {
  346. ++_currentline;
  347. NEXT(); //if a new line follows the start of delimiter drop it
  348. if(IS_EOB()) return -1;
  349. }
  350. for(;;) {
  351. while(CUR_CHAR != ndelim) {
  352. switch(CUR_CHAR) {
  353. case SQUIRREL_EOB:
  354. Error(_SC("unfinished string"));
  355. return -1;
  356. case _SC('\n'):
  357. if(!verbatim) Error(_SC("newline in a constant"));
  358. APPEND_CHAR(CUR_CHAR); NEXT();
  359. _currentline++;
  360. break;
  361. case _SC('\\'):
  362. if(verbatim) {
  363. APPEND_CHAR('\\'); NEXT();
  364. }
  365. else {
  366. NEXT();
  367. switch(CUR_CHAR) {
  368. case _SC('x'): NEXT(); {
  369. if(!isxdigit(CUR_CHAR)) Error(_SC("hexadecimal number expected"));
  370. const SQInteger maxdigits = 4;
  371. SQChar temp[maxdigits+1];
  372. SQInteger n = 0;
  373. while(isxdigit(CUR_CHAR) && n < maxdigits) {
  374. temp[n] = CUR_CHAR;
  375. n++;
  376. NEXT();
  377. }
  378. temp[n] = 0;
  379. SQChar *sTemp;
  380. APPEND_CHAR((SQChar)scstrtoul(temp,&sTemp,16));
  381. }
  382. break;
  383. case _SC('t'): APPEND_CHAR(_SC('\t')); NEXT(); break;
  384. case _SC('a'): APPEND_CHAR(_SC('\a')); NEXT(); break;
  385. case _SC('b'): APPEND_CHAR(_SC('\b')); NEXT(); break;
  386. case _SC('n'): APPEND_CHAR(_SC('\n')); NEXT(); break;
  387. case _SC('r'): APPEND_CHAR(_SC('\r')); NEXT(); break;
  388. case _SC('v'): APPEND_CHAR(_SC('\v')); NEXT(); break;
  389. case _SC('f'): APPEND_CHAR(_SC('\f')); NEXT(); break;
  390. case _SC('0'): APPEND_CHAR(_SC('\0')); NEXT(); break;
  391. case _SC('\\'): APPEND_CHAR(_SC('\\')); NEXT(); break;
  392. case _SC('"'): APPEND_CHAR(_SC('"')); NEXT(); break;
  393. case _SC('\''): APPEND_CHAR(_SC('\'')); NEXT(); break;
  394. default:
  395. Error(_SC("unrecognised escaper char"));
  396. break;
  397. }
  398. }
  399. break;
  400. default:
  401. APPEND_CHAR(CUR_CHAR);
  402. NEXT();
  403. }
  404. }
  405. NEXT();
  406. if(start_equals){
  407. bool lastBraceAdded = false;
  408. if(CUR_CHAR == _SC('=')){
  409. SQInteger end_equals = start_equals;
  410. NEXT();
  411. if(CUR_CHAR == _SC('=') || CUR_CHAR == _SC(']')){
  412. --end_equals;
  413. while(!IS_EOB() && CUR_CHAR == _SC('=')) {
  414. --end_equals;
  415. NEXT();
  416. }
  417. if(end_equals) Error(_SC("expect same number of '=' on literal delimiter"));
  418. if(CUR_CHAR != _SC(']')) Error(_SC("expect ']' to close literal delimiter"));
  419. NEXT();
  420. break;
  421. }
  422. APPEND_CHAR(_SC(']')); //the first NEXT() after break the while loop
  423. APPEND_CHAR(_SC('='));
  424. lastBraceAdded = true;
  425. }
  426. if(!lastBraceAdded) APPEND_CHAR(_SC(']')); //the first NEXT() after break the while loop
  427. APPEND_CHAR(CUR_CHAR);
  428. NEXT();
  429. }
  430. else if(verbatim && CUR_CHAR == '"') { //double quotation
  431. APPEND_CHAR(CUR_CHAR);
  432. NEXT();
  433. }
  434. else {
  435. break;
  436. }
  437. }
  438. TERMINATE_BUFFER();
  439. SQInteger len = _longstr.size()-1;
  440. if(ndelim == _SC('\'')) {
  441. if(len == 0) Error(_SC("empty constant"));
  442. if(len > 1) Error(_SC("constant too long"));
  443. _nvalue = _longstr[0];
  444. return TK_INTEGER;
  445. }
  446. _svalue = &_longstr[0];
  447. return TK_STRING_LITERAL;
  448. }
  449. void LexHexadecimal(const SQChar *s,SQUnsignedInteger *res)
  450. {
  451. *res = 0;
  452. while(*s != 0)
  453. {
  454. if(scisdigit(*s)) *res = (*res)*16+((*s++)-'0');
  455. else if(scisxdigit(*s)) *res = (*res)*16+(toupper(*s++)-'A'+10);
  456. else { assert(0); }
  457. }
  458. }
  459. void LexInteger(const SQChar *s,SQUnsignedInteger *res)
  460. {
  461. *res = 0;
  462. while(*s != 0)
  463. {
  464. *res = (*res)*10+((*s++)-'0');
  465. }
  466. }
  467. SQInteger scisodigit(SQInteger c) { return c >= _SC('0') && c <= _SC('7'); }
  468. void LexOctal(const SQChar *s,SQUnsignedInteger *res)
  469. {
  470. *res = 0;
  471. while(*s != 0)
  472. {
  473. if(scisodigit(*s)) *res = (*res)*8+((*s++)-'0');
  474. else { assert(0); }
  475. }
  476. }
  477. SQInteger isexponent(SQInteger c) { return c == 'e' || c=='E'; }
  478. #define MAX_HEX_DIGITS (sizeof(SQInteger)*2)
  479. SQInteger SQLexer::ReadNumber()
  480. {
  481. #define TINT 1
  482. #define TFLOAT 2
  483. #define THEX 3
  484. #define TSCIENTIFIC 4
  485. #define TOCTAL 5
  486. SQInteger type = TINT, firstchar = CUR_CHAR;
  487. SQUnsignedInteger itmp;
  488. SQChar *sTemp;
  489. INIT_TEMP_STRING();
  490. NEXT();
  491. if(firstchar == _SC('0') && (toupper(CUR_CHAR) == _SC('X') || scisodigit(CUR_CHAR)) ) {
  492. if(scisodigit(CUR_CHAR)) {
  493. type = TOCTAL;
  494. while(scisodigit(CUR_CHAR)) {
  495. APPEND_CHAR(CUR_CHAR);
  496. NEXT();
  497. }
  498. if(scisdigit(CUR_CHAR)) Error(_SC("invalid octal number"));
  499. }
  500. else {
  501. NEXT();
  502. type = THEX;
  503. while(isxdigit(CUR_CHAR)) {
  504. APPEND_CHAR(CUR_CHAR);
  505. NEXT();
  506. }
  507. if(_longstr.size() > MAX_HEX_DIGITS) Error(_SC("too many digits for an Hex number"));
  508. }
  509. }
  510. else {
  511. APPEND_CHAR((int)firstchar);
  512. while (CUR_CHAR == _SC('.') || scisdigit(CUR_CHAR) || isexponent(CUR_CHAR)) {
  513. if(CUR_CHAR == _SC('.') || isexponent(CUR_CHAR)) type = TFLOAT;
  514. if(isexponent(CUR_CHAR)) {
  515. if(type != TFLOAT) Error(_SC("invalid numeric format"));
  516. type = TSCIENTIFIC;
  517. APPEND_CHAR(CUR_CHAR);
  518. NEXT();
  519. if(CUR_CHAR == '+' || CUR_CHAR == '-'){
  520. APPEND_CHAR(CUR_CHAR);
  521. NEXT();
  522. }
  523. if(!scisdigit(CUR_CHAR)) Error(_SC("exponent expected"));
  524. }
  525. APPEND_CHAR(CUR_CHAR);
  526. NEXT();
  527. }
  528. }
  529. TERMINATE_BUFFER();
  530. switch(type) {
  531. case TSCIENTIFIC:
  532. case TFLOAT:
  533. _fvalue = (SQFloat)scstrtod(&_longstr[0],&sTemp);
  534. return TK_FLOAT;
  535. case TINT:
  536. LexInteger(&_longstr[0],&itmp);
  537. break;
  538. case THEX:
  539. LexHexadecimal(&_longstr[0],&itmp);
  540. break;
  541. case TOCTAL:
  542. LexOctal(&_longstr[0],&itmp);
  543. break;
  544. }
  545. switch(type) {
  546. case TINT:
  547. case THEX:
  548. case TOCTAL:
  549. if(itmp > INT_MAX) Error(_SC("integer overflow"));
  550. _nvalue = (SQInteger) itmp;
  551. return TK_INTEGER;
  552. }
  553. return 0;
  554. }
  555. SQInteger SQLexer::ReadID()
  556. {
  557. SQInteger res;
  558. INIT_TEMP_STRING();
  559. do {
  560. APPEND_CHAR(CUR_CHAR);
  561. NEXT();
  562. } while(scisalnum(CUR_CHAR) || CUR_CHAR == _SC('_'));
  563. TERMINATE_BUFFER();
  564. res = GetIDType(&_longstr[0]);
  565. if(res == TK_IDENTIFIER || res == TK_CONSTRUCTOR) {
  566. _svalue = &_longstr[0];
  567. }
  568. return res;
  569. }