int OctStrToInt64(const char *string, uint64_t *dest){ while(*string!='\0'){ if(!IsOctDigit(*string)) return -1; dest[0]<<=3; dest[0]+=(*string)-'0'; string++; } return 1; }
static int ScanNumericLiteral() { int base = 10; if('.' == *CURSOR) { return ScanFloatLiteral(); } if('0' == *CURSOR && (CURSOR[1] == 'x'|| CURSOR[1] == 'X')) { base = 16; CURSOR += 2; while(IsHexDigit(*CURSOR)) { CURSOR++; } } else if('0' == *CURSOR) { base = 8; CURSOR++; while(IsOctDigit(*CURSOR)) { CURSOR++; } } else { CURSOR++; while(IsDigit(*CURSOR)) { CURSOR++; } } if(base == 16 || (*CURSOR == '.' && *CURSOR == 'e' && *CURSOR == 'E')) { while('u' == *CURSOR || 'U' == *CURSOR || 'l' == *CURSOR || 'L' == *CURSOR) { CURSOR++; } return TK_INTCONST; } else { return ScanFloatLiteral(); } }
TokenType ReadOctNumber(istream& is, string& str, Coordinates& xy) { State st; char c; while (!is.eof()) { st = GetState(is.peek()); if (IsSyntaxError(st)) throw Error("syntax error", pos.first, pos.second); if (IsOctDigit(is.peek())) str = str + GetSymb(is,xy); else { c = GetSymb(is,xy); if (!IsSep(c) && c != '\n' && c != EOF) throw Error("wrong oct number", pos.first, pos.second); return int_const_oct; } } return int_const_hex; }
static inline size_t EscapeC(unsigned char c, TNextChar next, TBufferChar r[ESCAPE_C_BUFFER_SIZE]) { // (1) Printable characters go as-is, except backslash and double quote. // (2) Characters \r, \n, \t and \0 ... \7 replaced by their simple escape characters (if possible). // (3) Otherwise, character is encoded using hexadecimal escape sequence (if possible), or octal. if (c == '\"') { r[0] = '\\'; r[1] = '\"'; return 2; } else if (c == '\\') { r[0] = '\\'; r[1] = '\\'; return 2; } else if (IsPrintable(c)) { r[0] = c; return 1; } else if (c == '\r') { r[0] = '\\'; r[1] = 'r'; return 2; } else if (c == '\n') { r[0] = '\\'; r[1] = 'n'; return 2; } else if (c == '\t') { r[0] = '\\'; r[1] = 't'; return 2; } else if (c < 8 && !IsOctDigit(next)) { r[0] = '\\'; r[1] = OctDigit(c); return 2; } else if (!IsHexDigit(next)) { r[0] = '\\'; r[1] = 'x'; r[2] = HexDigit((c & 0xF0) >> 4); r[3] = HexDigit((c & 0x0F) >> 0); return 4; } else {
/* 扫描常数序列 */ static int ScanNumericLiteral (void) { unsigned char *start = CURRENT; /* 表示数值是多少进制 */ unsigned char base = 10; if ('.' == *CURRENT) { return ScanFloatLiteral (start); } /* 扫描前半部分(小数点的左边) */ if ('0' == *CURRENT && ('x' == CURRENT[1] || 'X' == CURRENT[1])) { base = 16; start = (CURRENT += 2); if (!IsHexDigit (*CURRENT)) { Error (&TokenCoord, "Expect hex digit"); TokenValue.i[0] = 0; return TK_INTCONST; } while (IsHexDigit (*CURRENT)) CURRENT++; } else if ('0' == *CURRENT) { base = 8; while (IsOctDigit (*++CURRENT)); } else { while (IsDigit (*++CURRENT)); } /* 如果符合下边条件,按整形处理 */ if (16 == base || ('.' != *CURRENT && 'e' != *CURRENT && 'E' != *CURRENT)) return ScanIntLiteral (start, (int)(CURRENT - start), base); else return ScanFloatLiteral (start); }
/* 处理转移字符 */ static int ScanEscapeChar (int wide) { int i, v, overflow; /* 跳过转移字符的 \ */ CURRENT++; switch (*CURRENT++) { /* 返回转义后的ASCII 值 */ case 'a': return '\a'; case 'b': return '\b'; case 'f': return '\f'; case 'n': return '\n'; case 'r': return '\r'; case 't': return '\t'; case 'v': return '\v'; /* 返回源字符的ASCII 值即可 */ case '\'': case '"': case '\\': case '\?': return *(CURRENT-1); case 'x': /* x之后若不是十六进制的数字则错误 */ if (!IsHexDigit (*CURRENT)) { Error (&TokenCoord, "Expect hex digit"); return 'x'; } /* 如果非宽字符 * 且从0开始可处理3个字符, * 非0开始可处理2个字符 * 如果宽字符 * 且从0开始可处理9个字符, * 非0开始可处理8个字符 */ i = ('0' == *CURRENT ? 0 : 1) + (wide ? 0 : 6); for (v = 0; i < 9 && IsHexDigit (*CURRENT); CURRENT++, i++) { v = (v << 4) + (IsDigit (*CURRENT) ? (*CURRENT-'0') : (ToUpper (*CURRENT) - 'A' + 10)); } /* 如果i不到9则字符中间有非法字符 */ if (9 != i) Warning (&TokenCoord, "Hexademical espace sequence overflo"); return v; /* 处理八进制 */ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': /* 如果非宽字符 * 且从0开始可处理三个字符, * 非0开始可处理两个字符 * 若是宽字符可处理三个字符 */ v = *(CURRENT - 1) - '0'; //i = wide ? for (i = v ? 1 : 0; i < 2 && IsOctDigit (*CURRENT); i++) v = (v << 3) + *CURRENT++ - '0'; return v; default: Warning (&TokenCoord, "Unrecognized escape sequence: \\%c", *CURRENT); return *CURRENT; } }