static double str2float( const char* str, char** endptr ) { double sign = is_sign(*str) && *str++ == '-' ? -1 : 1; double result = 0; while( is_dec(*str) ) result = (result * 10) + (*str++ - '0'); if( *str == '.' ) { ++str; double fraction = 1; while( is_dec(*str) ) fraction *= 0.1, result += (*str++ - '0') * fraction; } if( *str == 'e' || *str == 'E' ) { ++str; double base = is_sign(*str) && *str++ == '-' ? 0.1 : 10; int exponent = 0; while( is_dec(*str) ) exponent = (exponent * 10) + (*str++ - '0'); double power = 1; for( ; exponent; exponent >>= 1, base *= base ) if( exponent & 1 ) power *= base; result *= power; }
int Scanner::GetToken(int *sub) { *sub = 0; skip_non_token(); // char c = cur_char(); if (is_dec(c)) { return read_num(); } // struct OperatorTableEntry *op = lookup_op(); if (op) { int r; r = read_op(op); *sub = op->sub_op; return r; } // if (c == '\"') { return read_str(); } if (is_symhead(c)) { return read_sym(); } return -1; }
int Scanner::read_num() { clear_token(); bool hex_dec_mode = false; if (cur_char() == '0' && next_char() == 'x') { push_char(cur_char()); go_ahead(); push_char(cur_char()); go_ahead(); hex_dec_mode = true; } while (true) { char c = cur_char(); if (hex_dec_mode) { if (!is_hex_dec(c)) { break; } } else { if (!is_dec(c)) { break; } } push_char(cur_char()); go_ahead(); } return s_info->num_token; }
static int is_number(const char * n) { if (n[0] == '0' && n[1] == 'x') return is_hex(n + 2); else return is_dec(n); }
bool Scanner::is_symbody(char c) { if (is_symhead(c)) { return true; } if (is_dec(c)) { return true; } return false; }
bool Scanner::is_hex_dec(char c) { if (is_dec(c)) { return true; } if ((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) { return true; } return false; }
/** * Count the number of characters in the number. * The next bit of text starts with a number (0-9 or '.'), so it is a number. * Count the number of characters in the number. * * This should cover all number formats for all languages. * Note that this is not a strict parser. It will happily parse numbers in * an invalid format. * * For example, only D allows underscores in the numbers, but they are * allowed in all formats. * * @param pc The structure to update, str is an input. * @return Whether a number was parsed */ static bool parse_number(tok_ctx& ctx, chunk_t& pc) { int tmp; bool is_float; bool did_hex = false; /* A number must start with a digit or a dot, followed by a digit */ if (!is_dec(ctx.peek()) && ((ctx.peek() != '.') || !is_dec(ctx.peek(1)))) { return(false); } is_float = (ctx.peek() == '.'); if (is_float && (ctx.peek(1) == '.')) { return(false); } /* Check for Hex, Octal, or Binary * Note that only D and Pawn support binary, but who cares? */ if (ctx.peek() == '0') { pc.str.append(ctx.get()); /* store the '0' */ switch (unc_toupper(ctx.peek())) { case 'X': /* hex */ did_hex = true; do { pc.str.append(ctx.get()); /* store the 'x' and then the rest */ } while (is_hex_(ctx.peek())); break; case 'B': /* binary */ do { pc.str.append(ctx.get()); /* store the 'b' and then the rest */ } while (is_bin_(ctx.peek())); break; case '0': /* octal or decimal */ case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': do { pc.str.append(ctx.get()); } while (is_oct_(ctx.peek())); break; default: /* either just 0 or 0.1 or 0UL, etc */ break; } } else { /* Regular int or float */ while (is_dec_(ctx.peek())) { pc.str.append(ctx.get()); } } /* Check if we stopped on a decimal point & make sure it isn't '..' */ if ((ctx.peek() == '.') && (ctx.peek(1) != '.')) { pc.str.append(ctx.get()); is_float = true; if (did_hex) { while (is_hex_(ctx.peek())) { pc.str.append(ctx.get()); } } else { while (is_dec_(ctx.peek())) { pc.str.append(ctx.get()); } } } /* Check exponent * Valid exponents per language (not that it matters): * C/C++/D/Java: eEpP * C#/Pawn: eE */ tmp = unc_toupper(ctx.peek()); if ((tmp == 'E') || (tmp == 'P')) { is_float = true; pc.str.append(ctx.get()); if ((ctx.peek() == '+') || (ctx.peek() == '-')) { pc.str.append(ctx.get()); } while (is_dec_(ctx.peek())) { pc.str.append(ctx.get()); } } /* Check the suffixes * Valid suffixes per language (not that it matters): * Integer Float * C/C++: uUlL64 lLfF * C#: uUlL fFdDMm * D: uUL ifFL * Java: lL fFdD * Pawn: (none) (none) * * Note that i, f, d, and m only appear in floats. */ while (1) { tmp = unc_toupper(ctx.peek()); if ((tmp == 'I') || (tmp == 'F') || (tmp == 'D') || (tmp == 'M')) { is_float = true; } else if ((tmp != 'L') && (tmp != 'U')) { break; } pc.str.append(ctx.get()); } /* skip the Microsoft-specific '64' suffix */ if ((ctx.peek() == '6') && (ctx.peek(1) == '4')) { pc.str.append(ctx.get()); pc.str.append(ctx.get()); } pc.type = is_float ? CT_NUMBER_FP : CT_NUMBER; /* If there is anything left, then we are probably dealing with garbage or * some sick macro junk. Eat it. */ parse_suffix(ctx, pc); return(true); } // parse_number
static bool is_dec_(int ch) { return(is_dec(ch) || (ch == '_')); }