X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=lexer.c;h=5ca734a9256a171d0ac75c1898de04d0b8dc96c2;hb=43f6b44f389409af5b6162d831fe7c5c79f2ccb3;hp=9b6d36930f17ef254da96fb1c6a318da63f42596;hpb=8fb3da11c9e16fc66b74138035c121f4f8de5477;p=cparser diff --git a/lexer.c b/lexer.c index 9b6d369..5ca734a 100644 --- a/lexer.c +++ b/lexer.c @@ -487,34 +487,74 @@ end: */ static void parse_number_hex(void) { + bool is_float = false; assert(c == 'x' || c == 'X'); next_char(); + obstack_1grow(&symbol_obstack, '0'); + obstack_1grow(&symbol_obstack, 'x'); + while(isxdigit(c)) { obstack_1grow(&symbol_obstack, (char) c); next_char(); } - obstack_1grow(&symbol_obstack, '\0'); - char *string = obstack_finish(&symbol_obstack); - if(c == '.' || c == 'p' || c == 'P') { + if (c == '.') { + obstack_1grow(&symbol_obstack, (char) c); next_char(); - internal_error("Hex floating point numbers not implemented yet"); + + while (isxdigit(c)) { + obstack_1grow(&symbol_obstack, (char) c); + next_char(); + } + is_float = true; } + if (c == 'p' || c == 'P') { + obstack_1grow(&symbol_obstack, (char) c); + next_char(); + + if (c == '-' || c == '+') { + obstack_1grow(&symbol_obstack, (char) c); + next_char(); + } + + while (isxdigit(c)) { + obstack_1grow(&symbol_obstack, (char) c); + next_char(); + } + is_float = true; + } + + obstack_1grow(&symbol_obstack, '\0'); + char *string = obstack_finish(&symbol_obstack); if(*string == '\0') { parse_error("invalid hex number"); lexer_token.type = T_ERROR; + obstack_free(&symbol_obstack, string); + return; } - const char *endptr; - lexer_token.type = T_INTEGER; - lexer_token.v.intvalue = parse_int_string(string, &endptr, 16); - if(*endptr != '\0') { - parse_error("hex number literal too long"); + if (is_float) { + char *endptr; + lexer_token.type = T_FLOATINGPOINT; + lexer_token.v.floatvalue = strtold(string, &endptr); + + if(*endptr != '\0') { + parse_error("invalid hex float literal"); + } + + parse_floating_suffix(); + } else { + const char *endptr; + lexer_token.type = T_INTEGER; + lexer_token.v.intvalue = parse_int_string(string + 2, &endptr, 16); + if(*endptr != '\0') { + parse_error("hex number literal too long"); + } + parse_integer_suffix(true); } obstack_free(&symbol_obstack, string); - parse_integer_suffix(true); } /** @@ -569,23 +609,23 @@ static void parse_number_oct(void) static void parse_number_dec(void) { bool is_float = false; - while(isdigit(c)) { + while (isdigit(c)) { obstack_1grow(&symbol_obstack, (char) c); next_char(); } - if(c == '.') { + if (c == '.') { obstack_1grow(&symbol_obstack, '.'); next_char(); - while(isdigit(c)) { + while (isdigit(c)) { obstack_1grow(&symbol_obstack, (char) c); next_char(); } is_float = true; } if(c == 'e' || c == 'E') { - obstack_1grow(&symbol_obstack, 'e'); + obstack_1grow(&symbol_obstack, (char) c); next_char(); if(c == '-' || c == '+') { @@ -752,7 +792,7 @@ static int parse_escape_sequence(void) int ec = c; next_char(); - switch(ec) { + switch (ec) { case '"': return '"'; case '\'': return '\''; case '\\': return '\\'; @@ -778,6 +818,10 @@ static int parse_escape_sequence(void) case EOF: parse_error("reached end of file while parsing escape sequence"); return EOF; + case 'e': + if (c_mode & _GNUC) + return 27; /* hopefully 27 is ALWAYS the code for ESACAPE */ + /*fallthrough*/ default: parse_error("unknown escape sequence"); return EOF; @@ -1106,7 +1150,10 @@ static void skip_multiline_comment(void) case '/': next_char(); if (c == '*') { - /* TODO: nested comment, warn here */ + /* nested comment, warn here */ + if (warning.comment) { + warningf(&lexer_token.source_position, "'/*' within comment"); + } } break; case '*': @@ -1148,6 +1195,15 @@ static void skip_line_comment(void) case '\r': return; + case '\\': + next_char(); + if (c == '\n' || c == '\r') { + if (warning.comment) + warningf(&lexer_token.source_position, "multi-line comment"); + return; + } + break; + default: next_char(); break;