X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=lexer.c;h=5ca734a9256a171d0ac75c1898de04d0b8dc96c2;hb=43f6b44f389409af5b6162d831fe7c5c79f2ccb3;hp=635c3ca4d17ddc01b32822ca3284ed6f7f5cf301;hpb=f68cb5c533bd0e04c2607b8610c15ac9901ebf8e;p=cparser diff --git a/lexer.c b/lexer.c index 635c3ca..5ca734a 100644 --- a/lexer.c +++ b/lexer.c @@ -56,6 +56,7 @@ static char buf[1024 + MAX_PUTBACK]; static const char *bufend; static const char *bufpos; static strset_t stringset; +bool allow_dollar_in_symbol = true; /** * Prints a parse error message at the current token. @@ -194,6 +195,7 @@ end_of_next_char:; } #define SYMBOL_CHARS \ + case '$': if (!allow_dollar_in_symbol) goto dollar_sign; \ case 'a': \ case 'b': \ case 'c': \ @@ -281,6 +283,7 @@ static void parse_symbol(void) break; default: +dollar_sign: goto end_symbol; } } @@ -484,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); } /** @@ -566,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 == '+') { @@ -749,7 +792,7 @@ static int parse_escape_sequence(void) int ec = c; next_char(); - switch(ec) { + switch (ec) { case '"': return '"'; case '\'': return '\''; case '\\': return '\\'; @@ -775,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; @@ -1103,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 '*': @@ -1145,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; @@ -1564,6 +1623,7 @@ void lexer_next_preprocessing_token(void) return; default: +dollar_sign: errorf(&lexer_token.source_position, "unknown character '%c' found", c); next_char(); lexer_token.type = T_ERROR;