SQInteger SQLexer::AddUTF16(SQUnsignedInteger ch) { if (ch >= 0x10000) { SQUnsignedInteger code = (ch - 0x10000); APPEND_CHAR((SQChar)(0xD800 | (code >> 10))); APPEND_CHAR((SQChar)(0xDC00 | (code & 0x3FF))); return 2; }
SQInteger SQLexer::ReadID() { SQInteger res; INIT_TEMP_STRING(); do { APPEND_CHAR(CUR_CHAR); NEXT(); } while(scisalnum(CUR_CHAR) || CUR_CHAR == _SC('_')); TERMINATE_BUFFER(); res = GetIDType(&_longstr[0],_longstr.size() - 1); if(res == TK_IDENTIFIER || res == TK_CONSTRUCTOR) { _svalue = &_longstr[0]; } return res; }
// 设已经弹入一个字符,CURRENT_CHAR指向当前待分析的字符(由于可能需要向后看一个字符) // 试探下一个字符,若是自己的一部分,则读入下一个字符再返回,否则直接返回 Token* Lex_getNextToken(){ Token* tk = (Token*) malloc (sizeof(Token)); tk -> type = TK_UNDEF; tk ->value = NULL; while(isSpace(CURRENT_CHAR)){ if(CURRENT_CHAR == '\n')curLine++; MOVE_NEXT_CHAR; } if(CURRENT_CHAR == EOF ){ // 注意先跳过格式字符再看是否EOF,否则文件最后的空格会识别错误 tk -> type = TK_EOF; // 删除:curLine=0; 原因:造成最后一个错误报告行为0 return tk; } if(isAlpha(CURRENT_CHAR)){ int i = 0; tk -> value = NEW_STRING; while(isAlpha(CURRENT_CHAR)||isDigit(CURRENT_CHAR)){ APPEND_CHAR(CURRENT_CHAR); MOVE_NEXT_CHAR; } APPEND_CHAR('\0'); // 保留字和标志符的识别 for(i=0;i< KEYWORDS_NUM ;i++){ if(0==strcmp(tk -> value ,keywords[i])){ tk -> type = i; //(tk_e) free(tk -> value);// 如果是关键字,就释放存储值的空间 return tk; } } tk -> type = TK_IDENT; return tk; } else if(isDigit(CURRENT_CHAR)){ // 无符号整数识别 tk -> value = NEW_STRING; while(isDigit(CURRENT_CHAR)){ APPEND_CHAR(CURRENT_CHAR); MOVE_NEXT_CHAR; } APPEND_CHAR('\0'); tk -> type = TK_NUM; return tk; } else if(isRelop(CURRENT_CHAR)){ tk -> value = NEW_STRING; APPEND_CHAR(CURRENT_CHAR); MOVE_NEXT_CHAR; if('=' == CURRENT_CHAR){ if(CURRENT_CHAR == '!'){ tk -> type = TK_UNDEF; } else { APPEND_CHAR(CURRENT_CHAR); MOVE_NEXT_CHAR; tk -> type = TK_RELOP; } } else { tk -> type = TK_RELOP; // 2014-7-6 Fixed BUG1 } APPEND_CHAR('\0'); return tk; } else if( '=' == CURRENT_CHAR ){ tk -> value = NEW_STRING; APPEND_CHAR(CURRENT_CHAR); MOVE_NEXT_CHAR; if('=' == CURRENT_CHAR){ APPEND_CHAR(CURRENT_CHAR); MOVE_NEXT_CHAR; tk -> type = TK_RELOP; } else{ tk -> type = TK_ASSIGN; } APPEND_CHAR('\0'); return tk; } else { switch(CURRENT_CHAR){ case '+':tk -> type = TK_ADD;break; case '-':tk -> type = TK_SUB;break; case '*':tk -> type = TK_MUL;break; case '/':tk -> type = TK_DIV;break; case '{':tk -> type = TK_LBRACE;break; case '}':tk -> type = TK_RBRACE;break; case '(':tk -> type = TK_LPAREN;break; case ')':tk -> type = TK_RPAREN;break; case ';':tk -> type = TK_SEMICOLON;break; case '|':tk -> type = TK_LOG_OR;break; case '&':tk -> type = TK_LOG_AND;break; default: tk -> type = TK_UNDEF; tk -> value = NEW_STRING; APPEND_CHAR(CURRENT_CHAR); APPEND_CHAR('\0'); break; } MOVE_NEXT_CHAR; return tk; } }
String Misc_expandMacros(String string, const char *macroTemplate, const TextMacro macros[], uint macroCount ) { #define APPEND_CHAR(string,index,ch) \ do \ { \ if ((index) < sizeof(string)-1) \ { \ (string)[index] = ch; \ (index)++; \ } \ } \ while (0) #define SKIP_SPACES(string,i) \ do \ { \ while ( ((string)[i] != '\0') \ && isspace((string)[i]) \ ) \ { \ (i)++; \ } \ } \ while (0) bool macroFlag; ulong i; uint j; char name[128]; char format[128]; assert(macroTemplate != NULL); assert((macroCount == 0) || (macros != NULL)); String_clear(string); i = 0; do { // add prefix string macroFlag = FALSE; while ((macroTemplate[i] != '\0') && !macroFlag) { if (macroTemplate[i] == '%') { if ((macroTemplate[i+1] == '%')) { String_appendChar(string,'%'); i+=2; } else { macroFlag = TRUE; i++; } } else { String_appendChar(string,macroTemplate[i]); i++; } } if (macroFlag) { // skip spaces SKIP_SPACES(macroTemplate,i); // get macro name j = 0; if ( (macroTemplate[i] != '\0') && isalpha(macroTemplate[i]) ) { APPEND_CHAR(name,j,'%'); do { APPEND_CHAR(name,j,macroTemplate[i]); i++; } while ( (macroTemplate[i] != '\0') && isalnum(macroTemplate[i]) ); } name[j] = '\0'; // get format data (if any) j = 0; if (macroTemplate[i] == ':') { // skip ':' i++; // skip spaces SKIP_SPACES(macroTemplate,i); // get format string APPEND_CHAR(format,j,'%'); while ( (macroTemplate[i] != '\0') && ( isdigit(macroTemplate[i]) || (macroTemplate[i] == '-') || (macroTemplate[i] == '.') ) ) { APPEND_CHAR(format,j,macroTemplate[i]); i++; } while ( (macroTemplate[i] != '\0') && (strchr("l",macroTemplate[i]) != NULL) ) { APPEND_CHAR(format,j,macroTemplate[i]); i++; } if ( (macroTemplate[i] != '\0') && (strchr("duxfsS",macroTemplate[i]) != NULL) ) { APPEND_CHAR(format,j,macroTemplate[i]); i++; } } format[j] = '\0'; // find macro if (strlen(name) > 0) { // find macro j = 0; while ( (j < macroCount) && (strcmp(name,macros[j].name) != 0) ) { j++; } if (j < macroCount) { // get default format if no format given if (strlen(format) == 0) { switch (macros[j].type) { case TEXT_MACRO_TYPE_INTEGER: strcpy(format,"%d"); break; case TEXT_MACRO_TYPE_INTEGER64: strcpy(format,"%lld"); break; case TEXT_MACRO_TYPE_DOUBLE: strcpy(format,"%lf"); break; case TEXT_MACRO_TYPE_CSTRING: strcpy(format,"%s"); break; case TEXT_MACRO_TYPE_STRING: strcpy(format,"%S"); break; #ifndef NDEBUG default: HALT_INTERNAL_ERROR_UNHANDLED_SWITCH_CASE(); break; /* not reached */ #endif /* NDEBUG */ } } // expand macro switch (macros[j].type) { case TEXT_MACRO_TYPE_INTEGER: String_format(string,format,macros[j].value.i); break; case TEXT_MACRO_TYPE_INTEGER64: String_format(string,format,macros[j].value.l); break; case TEXT_MACRO_TYPE_DOUBLE: String_format(string,format,macros[j].value.d); break; case TEXT_MACRO_TYPE_CSTRING: String_format(string,format,macros[j].value.s); break; case TEXT_MACRO_TYPE_STRING: String_format(string,format,macros[j].value.string); break; #ifndef NDEBUG default: HALT_INTERNAL_ERROR_UNHANDLED_SWITCH_CASE(); break; /* not reached */ #endif /* NDEBUG */ } } else { // keep unknown macro String_appendCString(string,name); } } else { // empty macro: add empty string String_format(string,format,""); } } } while (macroFlag); return string; #undef SKIP_SPACES #undef APPEND_CHAR }
SQInteger SQLexer::ReadNumber() { #define TINT 1 #define TFLOAT 2 #define THEX 3 #define TSCIENTIFIC 4 #define TOCTAL 5 SQInteger type = TINT, firstchar = CUR_CHAR; SQChar *sTemp; INIT_TEMP_STRING(); NEXT(); if(firstchar == _SC('0') && (toupper(CUR_CHAR) == _SC('X') || scisodigit(CUR_CHAR)) ) { if(scisodigit(CUR_CHAR)) { type = TOCTAL; while(scisodigit(CUR_CHAR)) { APPEND_CHAR(CUR_CHAR); NEXT(); } if(scisdigit(CUR_CHAR)) Error(_SC("invalid octal number")); } else { NEXT(); type = THEX; while(isxdigit(CUR_CHAR)) { APPEND_CHAR(CUR_CHAR); NEXT(); } if(_longstr.size() > MAX_HEX_DIGITS) Error(_SC("too many digits for an Hex number")); } } else { APPEND_CHAR((int)firstchar); while (CUR_CHAR == _SC('.') || scisdigit(CUR_CHAR) || isexponent(CUR_CHAR)) { if(CUR_CHAR == _SC('.') || isexponent(CUR_CHAR)) type = TFLOAT; if(isexponent(CUR_CHAR)) { if(type != TFLOAT) Error(_SC("invalid numeric format")); type = TSCIENTIFIC; APPEND_CHAR(CUR_CHAR); NEXT(); if(CUR_CHAR == '+' || CUR_CHAR == '-'){ APPEND_CHAR(CUR_CHAR); NEXT(); } if(!scisdigit(CUR_CHAR)) Error(_SC("exponent expected")); } APPEND_CHAR(CUR_CHAR); NEXT(); } } TERMINATE_BUFFER(); switch(type) { case TSCIENTIFIC: case TFLOAT: _fvalue = (SQFloat)scstrtod(&_longstr[0],&sTemp); return TK_FLOAT; case TINT: LexInteger(&_longstr[0],(SQUnsignedInteger *)&_nvalue); return TK_INTEGER; case THEX: LexHexadecimal(&_longstr[0],(SQUnsignedInteger *)&_nvalue); return TK_INTEGER; case TOCTAL: LexOctal(&_longstr[0],(SQUnsignedInteger *)&_nvalue); return TK_INTEGER; } return 0; }
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; }
/* * Convert IPv6 binary address into presentation (printable) format. */ const char * addrtostr6 (const void *src, char *dst, size_t size) { /* * Note that int32_t and int16_t need only be "at least" large enough * to contain a value of the specified size. On some systems, like * Crays, there is no such thing as an integer variable with 16 bits. * Keep this in mind if you think this function should have been coded * to use pointer overlays. All the world's not a VAX. */ const u_char *srcaddr = (const u_char *)src; char *dp; size_t space_left, added_space; int snprintfed; struct { int base; int len; } best, cur; uint16_t words [IN6ADDRSZ / INT16SZ]; int i; /* Preprocess: * Copy the input (bytewise) array into a wordwise array. * Find the longest run of 0x00's in src[] for :: shorthanding. */ for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) words[i] = (srcaddr[2*i] << 8) | srcaddr[2*i + 1]; best.len = 0; best.base = -1; cur.len = 0; cur.base = -1; for (i = 0; i < (int)(IN6ADDRSZ / INT16SZ); i++) { if (words[i] == 0) { if (cur.base == -1) cur.base = i, cur.len = 1; else cur.len++; } else if (cur.base != -1) { if (best.base == -1 || cur.len > best.len) best = cur; cur.base = -1; } } if ((cur.base != -1) && (best.base == -1 || cur.len > best.len)) best = cur; if (best.base != -1 && best.len < 2) best.base = -1; /* Format the result. */ dp = dst; space_left = size; #define APPEND_CHAR(c) \ { \ if (space_left == 0) { \ errno = ENOSPC; \ return (NULL); \ } \ *dp++ = c; \ space_left--; \ } for (i = 0; i < (int)(IN6ADDRSZ / INT16SZ); i++) { /* Are we inside the best run of 0x00's? */ if (best.base != -1 && i >= best.base && i < (best.base + best.len)) { if (i == best.base) APPEND_CHAR(':'); continue; } /* Are we following an initial run of 0x00s or any real hex? */ if (i != 0) APPEND_CHAR(':'); /* Is this address an encapsulated IPv4? */ if (i == 6 && best.base == 0 && (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { if (!addrtostr(srcaddr+12, dp, space_left)) { errno = ENOSPC; return (NULL); } added_space = strlen(dp); dp += added_space; space_left -= added_space; break; } snprintfed = snprintf (dp, space_left, "%x", words[i]); if (snprintfed < 0) return (NULL); if ((size_t) snprintfed >= space_left) { errno = ENOSPC; return (NULL); } dp += snprintfed; space_left -= snprintfed; } /* Was it a trailing run of 0x00's? */ if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) APPEND_CHAR(':'); APPEND_CHAR('\0'); return (dst); }