From 698f3fe8ffdc1a29028d99f945d16b943541bbf5 Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Thu, 27 Mar 2008 05:35:36 +0000 Subject: [PATCH] Fix #136: Unbreak ..@ non-local-label mechanism. Add testcase for this. Also fix $-prefixed labels to match non-$-prefixed label behavior (this has been broken for a very long time). svn path=/trunk/yasm/; revision=2045 --- modules/parsers/nasm/nasm-parse.c | 4 ++ modules/parsers/nasm/nasm-parser.h | 1 + modules/parsers/nasm/nasm-token.re | 63 +++++++++++++---------- modules/parsers/nasm/tests/Makefile.inc | 2 + modules/parsers/nasm/tests/locallabel.asm | 21 ++++++++ modules/parsers/nasm/tests/locallabel.hex | 16 ++++++ 6 files changed, 79 insertions(+), 28 deletions(-) create mode 100644 modules/parsers/nasm/tests/locallabel.asm create mode 100644 modules/parsers/nasm/tests/locallabel.hex diff --git a/modules/parsers/nasm/nasm-parse.c b/modules/parsers/nasm/nasm-parse.c index 02a64121..cba949f8 100644 --- a/modules/parsers/nasm/nasm-parse.c +++ b/modules/parsers/nasm/nasm-parse.c @@ -98,6 +98,7 @@ destroy_curtok_(yasm_parser_nasm *parser_nasm) case ID: case LOCAL_ID: case SPECIAL_ID: + case NONLOCAL_ID: yasm_xfree(curval.str_val); break; case STRING: @@ -169,6 +170,7 @@ describe_token(int token) case ID: str = "identifier"; break; case LOCAL_ID: str = ".identifier"; break; case SPECIAL_ID: str = "..identifier"; break; + case NONLOCAL_ID: str = "..@identifier"; break; case LINE: str = "%line"; break; default: strch[1] = token; @@ -349,6 +351,7 @@ parse_line(yasm_parser_nasm *parser_nasm) return parse_times(parser_nasm); case ID: case SPECIAL_ID: + case NONLOCAL_ID: case LOCAL_ID: { char *name = ID_val; @@ -1143,6 +1146,7 @@ parse_expr6(yasm_parser_nasm *parser_nasm, expr_type type) /*@fallthrough@*/ case ID: case LOCAL_ID: + case NONLOCAL_ID: sym = yasm_symtab_use(p_symtab, ID_val, cur_line); e = p_expr_new_ident(yasm_expr_sym(sym)); yasm_xfree(ID_val); diff --git a/modules/parsers/nasm/nasm-parser.h b/modules/parsers/nasm/nasm-parser.h index 359761c3..c6148a7b 100644 --- a/modules/parsers/nasm/nasm-parser.h +++ b/modules/parsers/nasm/nasm-parser.h @@ -62,6 +62,7 @@ enum tokentype { ID, LOCAL_ID, SPECIAL_ID, + NONLOCAL_ID, LINE, NONE /* special token for lookahead */ }; diff --git a/modules/parsers/nasm/nasm-token.re b/modules/parsers/nasm/nasm-token.re index d81e0ce6..4409566c 100644 --- a/modules/parsers/nasm/nasm-token.re +++ b/modules/parsers/nasm/nasm-token.re @@ -70,6 +70,34 @@ static int linechg_numcount; quot = ["']; */ +static int +handle_dot_label(YYSTYPE *lvalp, char *tok, size_t toklen, size_t zeropos, + yasm_parser_nasm *parser_nasm) +{ + /* check for special non-local labels like ..start */ + if (tok[zeropos+1] == '.') { + lvalp->str_val = yasm__xstrndup(tok+zeropos, toklen-zeropos); + /* check for special non-local ..@label */ + if (lvalp->str_val[zeropos+2] == '@') + return NONLOCAL_ID; + return SPECIAL_ID; + } + + if (!parser_nasm->locallabel_base) { + lvalp->str_val = yasm__xstrndup(tok+zeropos, toklen-zeropos); + yasm_warn_set(YASM_WARN_GENERAL, + N_("no non-local label before `%s'"), + lvalp->str_val); + } else { + size_t len = toklen - zeropos + parser_nasm->locallabel_base_len; + lvalp->str_val = yasm_xmalloc(len + 1); + strcpy(lvalp->str_val, parser_nasm->locallabel_base); + strncat(lvalp->str_val, tok+zeropos, toklen-zeropos); + lvalp->str_val[len] = '\0'; + } + + return LOCAL_ID; +} int nasm_parser_lex(YYSTYPE *lvalp, yasm_parser_nasm *parser_nasm) @@ -77,7 +105,7 @@ nasm_parser_lex(YYSTYPE *lvalp, yasm_parser_nasm *parser_nasm) yasm_scanner *s = &parser_nasm->s; YYCTYPE *cursor = s->cur; YYCTYPE endch; - size_t count, len; + size_t count; YYCTYPE savech; /* Handle one token of lookahead */ @@ -286,38 +314,17 @@ scan: [-+|^*&/%~$():=,\[] { RETURN(s->tok[0]); } "]" { RETURN(s->tok[0]); } - /* special non-local ..@label */ - "..@" [a-zA-Z0-9_$#@~.?]+ { - lvalp->str_val = yasm__xstrndup(TOK, TOKLEN); - RETURN(ID); - } - - /* special non-local labels like ..start */ - ".." [a-zA-Z0-9_$#~.?]+ { - lvalp->str_val = yasm__xstrndup(TOK, TOKLEN); - RETURN(SPECIAL_ID); - } - /* local label (.label) */ - "." [a-zA-Z0-9_$#@~?][a-zA-Z0-9_$#@~.?]* { - if (!parser_nasm->locallabel_base) { - lvalp->str_val = yasm__xstrndup(TOK, TOKLEN); - yasm_warn_set(YASM_WARN_GENERAL, - N_("no non-local label before `%s'"), - lvalp->str_val); - } else { - len = TOKLEN + parser_nasm->locallabel_base_len; - lvalp->str_val = yasm_xmalloc(len + 1); - strcpy(lvalp->str_val, parser_nasm->locallabel_base); - strncat(lvalp->str_val, TOK, TOKLEN); - lvalp->str_val[len] = '\0'; - } - - RETURN(LOCAL_ID); + "." [a-zA-Z0-9_$#@~.?]+ { + RETURN(handle_dot_label(lvalp, TOK, TOKLEN, 0, parser_nasm)); } /* forced identifier */ "$" [a-zA-Z0-9_$#@~.?]+ { + if (TOK[1] == '.') { + /* handle like .label */ + RETURN(handle_dot_label(lvalp, TOK, TOKLEN, 1, parser_nasm)); + } lvalp->str_val = yasm__xstrndup(TOK+1, TOKLEN-1); RETURN(ID); } diff --git a/modules/parsers/nasm/tests/Makefile.inc b/modules/parsers/nasm/tests/Makefile.inc index 0e7cf1ed..ad84593c 100644 --- a/modules/parsers/nasm/tests/Makefile.inc +++ b/modules/parsers/nasm/tests/Makefile.inc @@ -19,6 +19,8 @@ EXTRA_DIST += modules/parsers/nasm/tests/hexconst.asm EXTRA_DIST += modules/parsers/nasm/tests/hexconst.hex EXTRA_DIST += modules/parsers/nasm/tests/long.asm EXTRA_DIST += modules/parsers/nasm/tests/long.hex +EXTRA_DIST += modules/parsers/nasm/tests/locallabel.asm +EXTRA_DIST += modules/parsers/nasm/tests/locallabel.hex EXTRA_DIST += modules/parsers/nasm/tests/nasm-prefix.asm EXTRA_DIST += modules/parsers/nasm/tests/nasm-prefix.hex EXTRA_DIST += modules/parsers/nasm/tests/newsect.asm diff --git a/modules/parsers/nasm/tests/locallabel.asm b/modules/parsers/nasm/tests/locallabel.asm new file mode 100644 index 00000000..013de530 --- /dev/null +++ b/modules/parsers/nasm/tests/locallabel.asm @@ -0,0 +1,21 @@ +label: +db 0 +.local: +db 0 +..@local1: +.local2: +dw label.local +dw label.local2 + +$label2: +db 0 +$.local: +db 0 +$..@local2: +$.local2: +dw label2.local +dw label2.local2 +dw $label2.local +dw $label2.local2 + + diff --git a/modules/parsers/nasm/tests/locallabel.hex b/modules/parsers/nasm/tests/locallabel.hex new file mode 100644 index 00000000..4aaba4ef --- /dev/null +++ b/modules/parsers/nasm/tests/locallabel.hex @@ -0,0 +1,16 @@ +00 +00 +01 +00 +02 +00 +00 +00 +07 +00 +08 +00 +07 +00 +08 +00