diff options
Diffstat (limited to 'lexer.c')
-rw-r--r-- | lexer.c | 69 |
1 files changed, 52 insertions, 17 deletions
@@ -8,6 +8,7 @@ token *last_tok = NULL; symbol *locals = NULL; symbol *last_loc = NULL; symbol *cur_sym = NULL; +symbol *struct_sym = NULL; line *tmp_line = NULL; @@ -228,6 +229,7 @@ line *find_line(uint32_t ln, uint8_t dbg) { } uint8_t is_struct = 0; +uint8_t is_anon = 0; uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) { char sym[0x100]; @@ -270,6 +272,7 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) { token *t = NULL; token *lt = NULL; symbol *tmp_sym = NULL; + symbol *tsym = NULL; while (isdigit(str[i]) && isdelm(str[i], dbg) != 16) { lnum[j++] = str[i++]; @@ -319,8 +322,6 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) { offset++; if ((ptok == PTOK_S && toupper(str[i+1]) == 'P') || (ptok == PTOK_P && toupper(str[i+1]) == 'C')) { offset++; - } else if (ptok == PTOK_S || ptok == PTOK_P) { - } switch (get_ptok(str[i+offset], dbg)) { case PTOK_B : @@ -331,6 +332,9 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) { case PTOK_ALPHA : case PTOK_NUMBER: ptok = PTOK_ALPHA; break; } + if ((ptok == PTOK_S && toupper(str[i+1]) != 'P') || (ptok == PTOK_P && toupper(str[i+1]) != 'C')) { + ptok = PTOK_ALPHA; + } } switch (ptok) { case PTOK_DOT: @@ -343,28 +347,49 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) { for (k = 0; k < 11; k++) { if (tolower(lexeme[0]) == dir_t[k][0] && !strcasecmp(lexeme, dir_t[k])) { lex_type = TOK_DIR; + uint16_t tmp = j; + for (j = 0; isdelm(str[i+j], dbg) & 16; j++); + uint8_t ret = get_ptok(str[i+j], dbg); + j = tmp; + if ((k == DIR_STRUCT || k == DIR_UNION) && (ret != PTOK_ALPHA || (is_anon && ret == PTOK_ALPHA))) { + is_anon++; + } is_struct += (k == DIR_STRUCT || k == DIR_UNION); is_struct -= (k == DIR_ENDSTRUCT || k == DIR_ENDUNION); if ((k == DIR_ENDSTRUCT || k == DIR_ENDUNION)) { - if (is_struct) { + int skip = 0; + if ((int)is_anon > 0) { + if ((cur_sym->up && !cur_sym->up->isanon) || (struct_sym && struct_sym->isanon)) { + is_anon--; + } + skip = (!is_anon); + } + if ((int)(is_struct-is_anon) > 0 && !skip && cur_sym->up) { symbol *s = cur_sym; for (; s->prev; s = s->prev) { - if (s->up == NULL) { + if (s->up == NULL && cur_sym->up) { s->up = cur_sym->up; } - printf("s: %p, last_loc: %p\n", s, last_loc); + if (dbg) { + printf("s: %p, s->up: %p, cur_sym->up: %p, last_loc: %p\n", s, s->up, cur_sym->up, last_loc); + } } for (s = locals; s; s = s->next) { if (s->up == NULL) { s->up = cur_sym; } + if (dbg) { + printf("s: %p, s->up: %p, cur_sym: %p, last_loc: %p\n", s, s->up, cur_sym, last_loc); + } } if (cur_sym->down == NULL) { cur_sym->down = locals; } cur_sym = cur_sym->up; - for (locals = cur_sym->down; locals->prev; locals = locals->prev); + for (struct_sym = locals->up; struct_sym->prev && !struct_sym->isanon; struct_sym = struct_sym->prev); + for (locals = locals->up; locals->prev; locals = locals->prev); for (last_loc = locals; last_loc->next; last_loc = last_loc->next); + } else if (!is_struct) { } } break; @@ -440,14 +465,14 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) { i += j; value = strtoull(lexeme, NULL, base); if (lt->id == TOK_SYM) { - mksymbol(sym, value, 1, islocal, 0, 0, dbg); + tsym = mksymbol(sym, value, 1, islocal, 0, 0, dbg); if (lt) { lt->sym = get_sym(sym, address, lt, islocal, dbg); } if (!islocal) { cur_sym = last_sym; - /*last_loc = NULL;*/ } + tsym = NULL; islocal = 0; isfixup += (lt->sym == NULL); if (dbg) { @@ -595,7 +620,7 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) { lexeme[j] = ':'; lexeme[j+1] = '\0'; lex_type = TOK_LABEL; - mksymbol(sym, address, 1, islocal, 0, 0, dbg); + tsym = mksymbol(sym, address, 1, islocal, 0, 0, dbg); if (isfixup) { isfixup = reslv_fixups(dbg); } @@ -605,14 +630,15 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) { lt->sym = get_sym(sym, address, t, islocal, dbg); isfixup += (lt->sym == NULL); } - if (!islocal) { - cur_sym = last_sym; + if (!islocal) { + cur_sym = last_sym; locals = NULL; - last_loc = NULL; + last_loc = NULL; } else if (cur_sym->down == NULL && cur_sym == last_sym) { - cur_sym->down = locals; - cur_sym->down->up = cur_sym; + cur_sym->down = locals; + cur_sym->down->up = cur_sym; } + tsym = NULL; islocal = 0; if (dbg) { printf("lex(): isfixup: %u\n", isfixup); @@ -678,7 +704,8 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) { if (!isop) { uint8_t spaces = 0; for (; isdelm(str[i+spaces], dbg) == 16; spaces++); - if (get_ptok(str[i+spaces], dbg) == PTOK_COLON) { + uint8_t ret = get_ptok(str[i+spaces], dbg); + if (ret == PTOK_COLON || ret == PTOK_EQU) { islocal = (lex_type == TOK_LOCAL); } lex_type = TOK_SYM; @@ -694,18 +721,26 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) { if (isfixup) { isfixup = reslv_fixups(dbg); } - t->sym = get_sym(sym, 0, t, islocal, dbg); + t->sym = get_sym(sym, 0, t, islocal, dbg); if (lt && lt->id == TOK_DIR) { t->sym->isstruct = 1; t->id = (lt->type == DIR_STRUCT) ? TOK_STRUCT : TOK_UNION; tmp_line = l; } else { t->id = TOK_MEMBER; + t->sym->isanon = (is_anon > 0); } isfixup += (t->sym == NULL); + int is_top = (cur_sym == NULL); cur_sym = (!islocal && !cur_sym) ? last_sym : cur_sym; if (!islocal) { - cur_sym->down = locals; + if (!is_top) { + cur_sym = t->sym; + locals = NULL; + last_loc = NULL; + } else { + cur_sym->down = locals; + } } else { if (lt && lt->id == TOK_DIR) { if (lt->type == DIR_UNION || lt->type == DIR_STRUCT) { |