// integer ::= digit+ inline Token Lexer::integer() { assert(is_decimal_digit(peek())); digit(); while (is_decimal_digit(peek())) digit(); return on_integer(); }
/*----------------------------------------------------------------------*/ static void read_number(lex_state_t *l, token_t *token) { int i; double d; int digit; int after_dot; int after_dot_divisor; /* read the left part up to the dot */ i = 0; while (is_decimal_digit(*l->ptr)) { digit = (*l->ptr - '0'); i *= 10; i += digit; ++l->ptr; } if (*l->ptr == '.') { /* read the right part after the dot */ d = i; ++l->ptr; after_dot = 0; after_dot_divisor = 1; while (is_decimal_digit(*l->ptr)) { digit = (*l->ptr - '0'); after_dot *= 10; after_dot += digit; after_dot_divisor *= 10; ++l->ptr; } /* read suffix */ if (*l->ptr == 'f') { ++l->ptr; token->type = TK_FLOAT_LITERAL; token->u.f = (float)i + (float)after_dot / (float)after_dot_divisor; } else { token->type = TK_DOUBLE_LITERAL; token->u.d = (double)i + (double)after_dot / (double)after_dot_divisor; } } else { token->type = TK_INT_LITERAL; token->u.i = i; } }
// digit ::= [0-9] inline void Lexer::digit() { assert(is_decimal_digit(peek())); get(); }
/*----------------------------------------------------------------------*/ static int is_hexadecimal_digit(char c) { return is_decimal_digit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); }
/*----------------------------------------------------------------------*/ static int next_token(lex_state_t *l) { token_t *token; char c; char cn; token = &l->out->tokens[l->out->token_count]; skip_comments_and_whitespace(l); token->source_pos = l->ptr - l->in->source; c = *(l->ptr + 0); cn = *(l->ptr + 1); if (c == '\0') { return 0; } else if (c == '\"') { read_string(l, token); } else if (is_decimal_digit(c)) { read_number(l, token); } else if (is_identifier_char(c)) { read_identifier(l, token); match_keyword(token); } else if (c == '<' && cn == '=') { token->type = TK_LESS_EQUAL; l->ptr += 2; } else if (c == '=' && cn == '=') { token->type = TK_EQUALS_EQUALS; l->ptr += 2; } else if (c == '>' && cn == '=') { token->type = TK_GREATER_EQUAL; l->ptr += 2; } else if (c == '+') { token->type = TK_PLUS; ++l->ptr; } else if (c == '-') { token->type = TK_MINUS; ++l->ptr; } else if (c == '*') { token->type = TK_STAR; ++l->ptr; } else if (c == '/') { token->type = TK_SLASH; ++l->ptr; } else if (c == '=') { token->type = TK_EQUALS; ++l->ptr; } else if (c == '<') { token->type = TK_LESS; ++l->ptr; } else if (c == '>') { token->type = TK_GREATER; ++l->ptr; } else if (c == '(') { token->type = TK_LBRACKET; ++l->ptr; } else if (c == ')') { token->type = TK_RBRACKET; ++l->ptr; } else if (c == ',') { token->type = TK_COMMA; ++l->ptr; } else if (c == ':') { token->type = TK_COLON; ++l->ptr; } else if (c == ';') { token->type = TK_SEMICOLON; ++l->ptr; } else { error(l); } return 1; }
// Returns true if c can appear in the rest of an identifier. inline bool is_identifier_rest(char c) { return is_identifier_start(c) || is_decimal_digit(c); }