X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=lexer.c;h=7c610825bc24344e083cf5d71f97f1379ccc3278;hb=00fad4c6c28b600fd17a6c3e8320dd6227c28e30;hp=66401d5408fac3c072431ec21a517f0f4e2e717d;hpb=6fb5b6813ea936aee285ede3b7b2b096303a3a4c;p=cparser diff --git a/lexer.c b/lexer.c index 66401d5..7c61082 100644 --- a/lexer.c +++ b/lexer.c @@ -1,5 +1,6 @@ #include +#include "diagnostic.h" #include "lexer.h" #include "token_t.h" #include "symbol_table_t.h" @@ -10,6 +11,7 @@ #include "type_t.h" #include "target_architecture.h" #include "parser.h" +#include "warning.h" #include #include @@ -61,8 +63,8 @@ static void parse_error(const char *msg) static inline void next_real_char(void) { - bufpos++; - if(bufpos >= bufend) { + assert(bufpos <= bufend); + if (bufpos >= bufend) { size_t s = fread(buf + MAX_PUTBACK, 1, sizeof(buf) - MAX_PUTBACK, input); if(s == 0) { @@ -72,20 +74,13 @@ static inline void next_real_char(void) bufpos = buf + MAX_PUTBACK; bufend = buf + MAX_PUTBACK + s; } - c = *(bufpos); + c = *bufpos++; } static inline void put_back(int pc) { - assert(bufpos >= buf); - //assert(bufpos < buf+MAX_PUTBACK || *bufpos == pc); - - char *p = buf + (bufpos - buf); - *p = (char) pc; - - /* going backwards in the buffer is legal as long as it's not more often - * than MAX_PUTBACK */ - bufpos--; + assert(bufpos > buf); + *(--bufpos - buf + buf) = (char) pc; #ifdef DEBUG_CHARS printf("putback '%c'\n", pc); @@ -101,11 +96,11 @@ static inline void next_char(void); next_char(); \ } \ lexer_token.source_position.linenr++; \ - code; \ + code \ case '\n': \ next_char(); \ lexer_token.source_position.linenr++; \ - code; + code #define eat(c_type) do { assert(c == c_type); next_char(); } while(0) @@ -156,8 +151,8 @@ static inline void next_char(void) case '>': c = '}'; break; case '-': c = '~'; break; default: - put_back('?'); put_back(c); + put_back('?'); c = '?'; break; } @@ -676,28 +671,30 @@ static int parse_escape_sequence(void) } } -const char *concat_strings(const char *s1, const char *s2) +string_t concat_strings(const string_t *const s1, const string_t *const s2) { - size_t len1 = strlen(s1); - size_t len2 = strlen(s2); + const size_t len1 = s1->size - 1; + const size_t len2 = s2->size - 1; - char *concat = obstack_alloc(&symbol_obstack, len1 + len2 + 1); - memcpy(concat, s1, len1); - memcpy(concat + len1, s2, len2 + 1); + char *const concat = obstack_alloc(&symbol_obstack, len1 + len2 + 1); + memcpy(concat, s1->begin, len1); + memcpy(concat + len1, s2->begin, len2 + 1); +#if 0 /* TODO hash */ const char *result = strset_insert(&stringset, concat); if(result != concat) { obstack_free(&symbol_obstack, concat); } return result; +#else + return (string_t){ concat, len1 + len2 + 1 }; +#endif } static void parse_string_literal(void) { - unsigned start_linenr = lexer_token.source_position.linenr; - char *string; - const char *result; + const unsigned start_linenr = lexer_token.source_position.linenr; assert(c == '"'); next_char(); @@ -734,16 +731,22 @@ end_of_string: /* add finishing 0 to the string */ obstack_1grow(&symbol_obstack, '\0'); - string = obstack_finish(&symbol_obstack); + const size_t size = (size_t)obstack_object_size(&symbol_obstack); + const char *const string = obstack_finish(&symbol_obstack); +#if 0 /* TODO hash */ /* check if there is already a copy of the string */ result = strset_insert(&stringset, string); if(result != string) { obstack_free(&symbol_obstack, string); } +#else + const char *const result = string; +#endif - lexer_token.type = T_STRING_LITERAL; - lexer_token.v.string = result; + lexer_token.type = T_STRING_LITERAL; + lexer_token.v.string.begin = result; + lexer_token.v.string.size = size; } static void parse_wide_character_constant(void) @@ -995,7 +998,7 @@ static void parse_line_directive(void) next_pp_token(); } if(pp_token.type == T_STRING_LITERAL) { - lexer_token.source_position.input_name = pp_token.v.string; + lexer_token.source_position.input_name = pp_token.v.string.begin; next_pp_token(); } @@ -1035,6 +1038,10 @@ static void parse_preprocessor_identifier(void) error_directive(); break; case TP_pragma: + if (warning.unknown_pragmas) { + warningf(lexer_token.source_position, "encountered unknown #pragma"); + } + eat_until_newline(); break; } } @@ -1122,6 +1129,21 @@ void lexer_next_preprocessing_token(void) case '.': MAYBE_PROLOG + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + put_back(c); + c = '.'; + parse_number_dec(); + return; + case '.': MAYBE_PROLOG MAYBE('.', T_DOTDOTDOT) @@ -1285,6 +1307,8 @@ void lexer_open_stream(FILE *stream, const char *input_name) lexer_token.source_position.input_name = input_name; symbol_L = symbol_table_insert("L"); + bufpos = NULL; + bufend = NULL; /* place a virtual \n at the beginning so the lexer knows that we're * at the beginning of a line */