SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim) { INIT_TEMP_STRING(); NEXT(); if(IS_EOB()) return -1; for(;;) { while(CUR_CHAR != ndelim) { switch(CUR_CHAR) { case SQUIRREL_EOB: Error(_SC("unfinished string")); return -1; case _SC('\n'): if(!verbatim) Error(_SC("newline in a constant")); APPEND_CHAR(CUR_CHAR); NEXT(); _currentline++; break; case _SC('\\'): if(verbatim) { APPEND_CHAR('\\'); NEXT(); } else { NEXT(); switch(CUR_CHAR) { case _SC('x'): NEXT(); { if(!isxdigit(CUR_CHAR)) Error(_SC("hexadecimal number expected")); const SQInteger maxdigits = 4; SQChar temp[maxdigits+1]; SQInteger n = 0; while(isxdigit(CUR_CHAR) && n < maxdigits) { temp[n] = CUR_CHAR; n++; NEXT(); } temp[n] = 0; SQChar *sTemp; APPEND_CHAR((SQChar)scstrtoul(temp,&sTemp,16)); } break; case _SC('t'): APPEND_CHAR(_SC('\t')); NEXT(); break; case _SC('a'): APPEND_CHAR(_SC('\a')); NEXT(); break; case _SC('b'): APPEND_CHAR(_SC('\b')); NEXT(); break; case _SC('n'): APPEND_CHAR(_SC('\n')); NEXT(); break; case _SC('r'): APPEND_CHAR(_SC('\r')); NEXT(); break; case _SC('v'): APPEND_CHAR(_SC('\v')); NEXT(); break; case _SC('f'): APPEND_CHAR(_SC('\f')); NEXT(); break; case _SC('0'): APPEND_CHAR(_SC('\0')); NEXT(); break; case _SC('\\'): APPEND_CHAR(_SC('\\')); NEXT(); break; case _SC('"'): APPEND_CHAR(_SC('"')); NEXT(); break; case _SC('\''): APPEND_CHAR(_SC('\'')); NEXT(); break; default: Error(_SC("unrecognised escaper char")); break; } } break; default: APPEND_CHAR(CUR_CHAR); NEXT(); } } NEXT(); if(verbatim && CUR_CHAR == '"') { //double quotation APPEND_CHAR(CUR_CHAR); NEXT(); } else { break; } } TERMINATE_BUFFER(); SQInteger len = _longstr.size()-1; if(ndelim == _SC('\'')) { if(len == 0) Error(_SC("empty constant")); if(len > 1) Error(_SC("constant too long")); _nvalue = _longstr[0]; return TK_INTEGER; } _svalue = &_longstr[0]; return TK_STRING_LITERAL; }
void SQLexer::LexLineComment() { do { NEXT(); } while (CUR_CHAR != _SC('\n') && (!IS_EOB())); }
SQInteger SQLexer::Lex() { _lasttokenline = _currentline; while(CUR_CHAR != SQUIRREL_EOB) { #if !defined(_UNICODE) && defined(USESJIS) if (iskanji) { SQInteger c = CUR_CHAR; NEXT(); RETURN_TOKEN(c); } iskanji = false; #endif switch(CUR_CHAR){ case _SC('\t'): case _SC('\r'): case _SC(' '): NEXT(); continue; case _SC('\n'): _currentline++; _prevtoken=_curtoken; _curtoken=_SC('\n'); NEXT(); _currentcolumn=1; continue; case _SC('/'): NEXT(); switch(CUR_CHAR){ case _SC('*'): NEXT(); LexBlockComment(); continue; case _SC('/'): do { NEXT(); } while (CUR_CHAR != _SC('\n') && (!IS_EOB())); continue; case _SC('='): NEXT(); RETURN_TOKEN(TK_DIVEQ); continue; case _SC('>'): NEXT(); RETURN_TOKEN(TK_ATTR_CLOSE); continue; default: RETURN_TOKEN('/'); } case _SC('='): NEXT(); if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('=') } else { NEXT(); RETURN_TOKEN(TK_EQ); } case _SC('<'): NEXT(); if ( CUR_CHAR == _SC('=') ) { NEXT(); RETURN_TOKEN(TK_LE) } else if ( CUR_CHAR == _SC('-') ) { NEXT(); RETURN_TOKEN(TK_NEWSLOT); } else if ( CUR_CHAR == _SC('<') ) { NEXT(); RETURN_TOKEN(TK_SHIFTL); } else if ( CUR_CHAR == _SC('/') ) { NEXT(); RETURN_TOKEN(TK_ATTR_OPEN); } //else if ( CUR_CHAR == _SC('[') ) { NEXT(); ReadMultilineString(); RETURN_TOKEN(TK_STRING_LITERAL); } else { RETURN_TOKEN('<') } case _SC('>'): NEXT(); if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_GE);} else if(CUR_CHAR == _SC('>')){ NEXT(); if(CUR_CHAR == _SC('>')){ NEXT(); RETURN_TOKEN(TK_USHIFTR); } RETURN_TOKEN(TK_SHIFTR); } else { RETURN_TOKEN('>') } case _SC('!'): NEXT(); if (CUR_CHAR != _SC('=')){ RETURN_TOKEN('!')} else { NEXT(); RETURN_TOKEN(TK_NE); } case _SC('@'): { SQInteger stype; NEXT(); if(CUR_CHAR != _SC('"')) Error(_SC("string expected")); if((stype=ReadString('"',true))!=-1) { RETURN_TOKEN(stype); } Error(_SC("error parsing the string")); } case _SC('"'): case _SC('\''): { SQInteger stype; if((stype=ReadString(CUR_CHAR,false))!=-1){ RETURN_TOKEN(stype); } Error(_SC("error parsing the string")); } case _SC('{'): case _SC('}'): case _SC('('): case _SC(')'): case _SC('['): case _SC(']'): case _SC(';'): case _SC(','): case _SC('?'): case _SC('^'): case _SC('~'): {SQInteger ret = CUR_CHAR; NEXT(); RETURN_TOKEN(ret); } case _SC('.'): NEXT(); if (CUR_CHAR != _SC('.')){ RETURN_TOKEN('.') } NEXT(); if (CUR_CHAR != _SC('.')){ Error(_SC("invalid token '..'")); } NEXT(); RETURN_TOKEN(TK_VARPARAMS); case _SC('&'): NEXT(); if (CUR_CHAR != _SC('&')){ RETURN_TOKEN('&') } else { NEXT(); RETURN_TOKEN(TK_AND); } case _SC('|'): NEXT(); if (CUR_CHAR != _SC('|')){ RETURN_TOKEN('|') } else { NEXT(); RETURN_TOKEN(TK_OR); } case _SC(':'): NEXT(); if (CUR_CHAR != _SC(':')){ RETURN_TOKEN(':') } else { NEXT(); RETURN_TOKEN(TK_DOUBLE_COLON); } case _SC('*'): NEXT(); if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MULEQ);} else RETURN_TOKEN('*'); case _SC('%'): NEXT(); if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MODEQ);} else RETURN_TOKEN('%'); case _SC('-'): NEXT(); if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_MINUSEQ);} else if (CUR_CHAR == _SC('-')){ NEXT(); RETURN_TOKEN(TK_MINUSMINUS);} else RETURN_TOKEN('-'); case _SC('+'): NEXT(); if (CUR_CHAR == _SC('=')){ NEXT(); RETURN_TOKEN(TK_PLUSEQ);} else if (CUR_CHAR == _SC('+')){ NEXT(); RETURN_TOKEN(TK_PLUSPLUS);} else RETURN_TOKEN('+'); case SQUIRREL_EOB: return 0; default:{ if (scisdigit(CUR_CHAR)) { SQInteger ret = ReadNumber(); RETURN_TOKEN(ret); } else if (scisalpha(CUR_CHAR) || CUR_CHAR == _SC('_')) { SQInteger t = ReadID(); RETURN_TOKEN(t); } else { SQInteger c = CUR_CHAR; if (sciscntrl((int)c)) Error(_SC("unexpected character(control)")); #if !defined(_UNICODE) && defined(USESJIS) iskanji = iskanji1(c); #endif NEXT(); RETURN_TOKEN(c); } RETURN_TOKEN(0); } }