]> granicus.if.org Git - yasm/commitdiff
Handle instruction and prefix identifiers properly when used in other
authorPeter Johnson <peter@tortall.net>
Thu, 3 Nov 2005 05:29:42 +0000 (05:29 -0000)
committerPeter Johnson <peter@tortall.net>
Thu, 3 Nov 2005 05:29:42 +0000 (05:29 -0000)
places in GAS input.  Do this by adding a tokenizer state that turns off
insn and prefix generation when inside an instruction or directive, AND
adding a special case for labels.

* gas-parser.h (state): Add INSTDIR.
* gas-token.re: Switch state back to INITIAL on ';' or newline; set state
when entering instruction or directive, add special case for labels.
* gas-bison.y: Remove non-working attempt at translating INSN and PREFIX
into string token; add special case for LABEL identifiers (generated from
special case for labels in tokenizer).

svn path=/trunk/yasm/; revision=1309

modules/parsers/gas/gas-bison.y
modules/parsers/gas/gas-parser.h
modules/parsers/gas/gas-token.re
modules/parsers/gas/tests/Makefile.inc
modules/parsers/gas/tests/gas-instlabel.asm [new file with mode: 0644]
modules/parsers/gas/tests/gas-instlabel.errwarn [new file with mode: 0644]
modules/parsers/gas/tests/gas-instlabel.hex [new file with mode: 0644]

index 81cec4ee9882246e42ae3e592e341d3ea626b320..442983c60f339148c2bea782bb593bb5a9873dc2 100644 (file)
@@ -102,7 +102,7 @@ static void gas_parser_directive
 %token <int_info> RESERVE_SPACE
 %token <arch_data> INSN PREFIX REG REGGROUP SEGREG TARGETMOD
 %token LEFT_OP RIGHT_OP
-%token <str_val> ID DIR_ID
+%token <str_val> ID DIR_ID LABEL
 %token LINE
 %token DIR_2BYTE DIR_4BYTE DIR_ALIGN DIR_ASCII DIR_ASCIZ DIR_BALIGN
 %token DIR_BSS DIR_BYTE DIR_COMM DIR_DATA DIR_DOUBLE DIR_ENDR DIR_EXTERN
@@ -169,6 +169,14 @@ lineexp: instr
        $$ = $3;
        define_label(parser_gas, $1, 0);
     }
+    | LABEL            {
+       $$ = (yasm_bytecode *)NULL;
+       define_label(parser_gas, $1, 0);
+    }
+    | LABEL instr      {
+       $$ = $2;
+       define_label(parser_gas, $1, 0);
+    }
     /* Line directive */
     | DIR_LINE INTNUM {
        $$ = (yasm_bytecode *)NULL;
@@ -716,16 +724,6 @@ expr_id: label_id
     | DIR_DATA { $$ = yasm__xstrdup(".data"); }
     | DIR_TEXT { $$ = yasm__xstrdup(".text"); }
     | DIR_BSS  { $$ = yasm__xstrdup(".bss"); }
-    | INSN     {
-       /* Used as an identifier, grab token to make it one! */
-       $$ = yasm__xstrndup(parser_gas->s.tok,
-                           (size_t)(parser_gas->s.cur - parser_gas->s.tok));
-    }
-    | PREFIX   {
-       /* Used as an identifier, grab token to make it one! */
-       $$ = yasm__xstrndup(parser_gas->s.tok,
-                           (size_t)(parser_gas->s.cur - parser_gas->s.tok));
-    }
 ;
 
 label_id: ID | DIR_ID;
index d17ee34aa2a35d7db34245aac87f95bf2df49afc..df9421f260feef1553ea8a6e08c3b4948cc7a001 100644 (file)
@@ -88,7 +88,8 @@ typedef struct yasm_parser_gas {
     Scanner s;
     enum {
        INITIAL,
-       SECTION_DIRECTIVE
+       SECTION_DIRECTIVE,
+       INSTDIR
     } state;
 
     int code_section;
index e284232f34379478f7c07ce3573bac929d12a102..67bcb6bff6485026ca4e160343607fc5812e6cd0 100644 (file)
@@ -334,60 +334,64 @@ scan:
        ">>"                    { RETURN(RIGHT_OP); }
        "<"                     { RETURN(LEFT_OP); }
        ">"                     { RETURN(RIGHT_OP); }
-       [-+|^!*&/~$():;@=,]     { RETURN(s->tok[0]); }
+       [-+|^!*&/~$():@=,]      { RETURN(s->tok[0]); }
+       ";"     {
+           parser_gas->state = INITIAL;
+           RETURN(s->tok[0]);
+       }
 
        /* arch-independent directives */
-       '.2byte'        { RETURN(DIR_2BYTE); }
-       '.4byte'        { RETURN(DIR_4BYTE); }
-       '.8byte'        { RETURN(DIR_QUAD); }
-       '.align'        { RETURN(DIR_ALIGN); }
-       '.ascii'        { RETURN(DIR_ASCII); }
-       '.asciz'        { RETURN(DIR_ASCIZ); }
-       '.balign'       { RETURN(DIR_BALIGN); }
-       '.bss'          { RETURN(DIR_BSS); }
-       '.byte'         { RETURN(DIR_BYTE); }
-       '.comm'         { RETURN(DIR_COMM); }
-       '.data'         { RETURN(DIR_DATA); }
-       '.double'       { RETURN(DIR_DOUBLE); }
-       '.endr'         { RETURN(DIR_ENDR); }
-       '.equ'          { RETURN(DIR_EQU); }
-       '.extern'       { RETURN(DIR_EXTERN); }
-       '.file'         { RETURN(DIR_FILE); }
-       '.float'        { RETURN(DIR_FLOAT); }
-       '.global'       { RETURN(DIR_GLOBAL); }
-       '.globl'        { RETURN(DIR_GLOBAL); }
-       '.hword'        { RETURN(DIR_SHORT); }
-       '.ident'        { RETURN(DIR_IDENT); }
-       '.int'          { RETURN(DIR_INT); }
-       '.lcomm'        { RETURN(DIR_LCOMM); }
-       '.line'         { RETURN(DIR_LINE); }
-       '.loc'          { RETURN(DIR_LOC); }
-       '.long'         { RETURN(DIR_INT); }
-       '.octa'         { RETURN(DIR_OCTA); }
-       '.org'          { RETURN(DIR_ORG); }
-       '.p2align'      { RETURN(DIR_P2ALIGN); }
-       '.rept'         { RETURN(DIR_REPT); }
+       '.2byte'        { parser_gas->state = INSTDIR; RETURN(DIR_2BYTE); }
+       '.4byte'        { parser_gas->state = INSTDIR; RETURN(DIR_4BYTE); }
+       '.8byte'        { parser_gas->state = INSTDIR; RETURN(DIR_QUAD); }
+       '.align'        { parser_gas->state = INSTDIR; RETURN(DIR_ALIGN); }
+       '.ascii'        { parser_gas->state = INSTDIR; RETURN(DIR_ASCII); }
+       '.asciz'        { parser_gas->state = INSTDIR; RETURN(DIR_ASCIZ); }
+       '.balign'       { parser_gas->state = INSTDIR; RETURN(DIR_BALIGN); }
+       '.bss'          { parser_gas->state = INSTDIR; RETURN(DIR_BSS); }
+       '.byte'         { parser_gas->state = INSTDIR; RETURN(DIR_BYTE); }
+       '.comm'         { parser_gas->state = INSTDIR; RETURN(DIR_COMM); }
+       '.data'         { parser_gas->state = INSTDIR; RETURN(DIR_DATA); }
+       '.double'       { parser_gas->state = INSTDIR; RETURN(DIR_DOUBLE); }
+       '.endr'         { parser_gas->state = INSTDIR; RETURN(DIR_ENDR); }
+       '.equ'          { parser_gas->state = INSTDIR; RETURN(DIR_EQU); }
+       '.extern'       { parser_gas->state = INSTDIR; RETURN(DIR_EXTERN); }
+       '.file'         { parser_gas->state = INSTDIR; RETURN(DIR_FILE); }
+       '.float'        { parser_gas->state = INSTDIR; RETURN(DIR_FLOAT); }
+       '.global'       { parser_gas->state = INSTDIR; RETURN(DIR_GLOBAL); }
+       '.globl'        { parser_gas->state = INSTDIR; RETURN(DIR_GLOBAL); }
+       '.hword'        { parser_gas->state = INSTDIR; RETURN(DIR_SHORT); }
+       '.ident'        { parser_gas->state = INSTDIR; RETURN(DIR_IDENT); }
+       '.int'          { parser_gas->state = INSTDIR; RETURN(DIR_INT); }
+       '.lcomm'        { parser_gas->state = INSTDIR; RETURN(DIR_LCOMM); }
+       '.line'         { parser_gas->state = INSTDIR; RETURN(DIR_LINE); }
+       '.loc'          { parser_gas->state = INSTDIR; RETURN(DIR_LOC); }
+       '.long'         { parser_gas->state = INSTDIR; RETURN(DIR_INT); }
+       '.octa'         { parser_gas->state = INSTDIR; RETURN(DIR_OCTA); }
+       '.org'          { parser_gas->state = INSTDIR; RETURN(DIR_ORG); }
+       '.p2align'      { parser_gas->state = INSTDIR; RETURN(DIR_P2ALIGN); }
+       '.rept'         { parser_gas->state = INSTDIR; RETURN(DIR_REPT); }
        '.section'      {
            parser_gas->state = SECTION_DIRECTIVE;
            RETURN(DIR_SECTION);
        }
-       '.set'          { RETURN(DIR_EQU); }
-       '.short'        { RETURN(DIR_SHORT); }
-       '.single'       { RETURN(DIR_FLOAT); }
-       '.size'         { RETURN(DIR_SIZE); }
-       '.skip'         { RETURN(DIR_SKIP); }
-       '.sleb128'      { RETURN(DIR_SLEB128); }
-       '.space'        { RETURN(DIR_SKIP); }
-       '.string'       { RETURN(DIR_ASCIZ); }
-       '.text'         { RETURN(DIR_TEXT); }
-       '.tfloat'       { RETURN(DIR_TFLOAT); }
-       '.type'         { RETURN(DIR_TYPE); }
-       '.quad'         { RETURN(DIR_QUAD); }
-       '.uleb128'      { RETURN(DIR_ULEB128); }
-       '.value'        { RETURN(DIR_VALUE); }
-       '.weak'         { RETURN(DIR_WEAK); }
-       '.word'         { RETURN(DIR_WORD); }
-       '.zero'         { RETURN(DIR_ZERO); }
+       '.set'          { parser_gas->state = INSTDIR; RETURN(DIR_EQU); }
+       '.short'        { parser_gas->state = INSTDIR; RETURN(DIR_SHORT); }
+       '.single'       { parser_gas->state = INSTDIR; RETURN(DIR_FLOAT); }
+       '.size'         { parser_gas->state = INSTDIR; RETURN(DIR_SIZE); }
+       '.skip'         { parser_gas->state = INSTDIR; RETURN(DIR_SKIP); }
+       '.sleb128'      { parser_gas->state = INSTDIR; RETURN(DIR_SLEB128); }
+       '.space'        { parser_gas->state = INSTDIR; RETURN(DIR_SKIP); }
+       '.string'       { parser_gas->state = INSTDIR; RETURN(DIR_ASCIZ); }
+       '.text'         { parser_gas->state = INSTDIR; RETURN(DIR_TEXT); }
+       '.tfloat'       { parser_gas->state = INSTDIR; RETURN(DIR_TFLOAT); }
+       '.type'         { parser_gas->state = INSTDIR; RETURN(DIR_TYPE); }
+       '.quad'         { parser_gas->state = INSTDIR; RETURN(DIR_QUAD); }
+       '.uleb128'      { parser_gas->state = INSTDIR; RETURN(DIR_ULEB128); }
+       '.value'        { parser_gas->state = INSTDIR; RETURN(DIR_VALUE); }
+       '.weak'         { parser_gas->state = INSTDIR; RETURN(DIR_WEAK); }
+       '.word'         { parser_gas->state = INSTDIR; RETURN(DIR_WORD); }
+       '.zero'         { parser_gas->state = INSTDIR; RETURN(DIR_ZERO); }
 
        /* label or maybe directive */
        [.][a-zA-Z0-9_$.]* {
@@ -432,22 +436,41 @@ scan:
            RETURN(REG);
        }
 
+       /* label */
+       [a-zA-Z][a-zA-Z0-9_$.]* ws* ':' {
+           /* strip off colon and any whitespace */
+           count = TOKLEN-1;
+           while (s->tok[count] == ' ' || s->tok[count] == '\t'
+                  || s->tok[count] == '\r')
+               count--;
+           /* Just an identifier, return as such. */
+           lvalp->str_val = yasm__xstrndup(s->tok, count);
+           RETURN(LABEL);
+       }
+
        /* identifier that may be an instruction, etc. */
        [a-zA-Z][a-zA-Z0-9_$.]* {
-           savech = s->tok[TOKLEN];
-           s->tok[TOKLEN] = '\0';
-           if (yasm_arch_parse_check_insn(parser_gas->arch, lvalp->arch_data,
-                                          s->tok, cur_line)) {
-               s->tok[TOKLEN] = savech;
-               RETURN(INSN);
-           }
-           if (yasm_arch_parse_check_prefix(parser_gas->arch,
-                                            lvalp->arch_data, s->tok,
-                                            cur_line)) {
+           /* Can only be an instruction/prefix when not inside an
+            * instruction or directive.
+            */
+           if (parser_gas->state != INSTDIR) {
+               savech = s->tok[TOKLEN];
+               s->tok[TOKLEN] = '\0';
+               if (yasm_arch_parse_check_insn(parser_gas->arch,
+                                              lvalp->arch_data, s->tok,
+                                              cur_line)) {
+                   s->tok[TOKLEN] = savech;
+                   parser_gas->state = INSTDIR;
+                   RETURN(INSN);
+               }
+               if (yasm_arch_parse_check_prefix(parser_gas->arch,
+                                                lvalp->arch_data, s->tok,
+                                                cur_line)) {
+                   s->tok[TOKLEN] = savech;
+                   RETURN(PREFIX);
+               }
                s->tok[TOKLEN] = savech;
-               RETURN(PREFIX);
            }
-           s->tok[TOKLEN] = savech;
            /* Just an identifier, return as such. */
            lvalp->str_val = yasm__xstrndup(s->tok, TOKLEN);
            RETURN(ID);
index 7134b34a5cd0f414bac67836356c61c58657efdd..e357c98b90fc498af176bd4178b363e3043476a8 100644 (file)
@@ -12,6 +12,9 @@ EXTRA_DIST += modules/parsers/gas/tests/datavis.hex
 EXTRA_DIST += modules/parsers/gas/tests/datavis2.asm
 EXTRA_DIST += modules/parsers/gas/tests/datavis2.errwarn
 EXTRA_DIST += modules/parsers/gas/tests/datavis2.hex
+EXTRA_DIST += modules/parsers/gas/tests/gas-instlabel.asm
+EXTRA_DIST += modules/parsers/gas/tests/gas-instlabel.errwarn
+EXTRA_DIST += modules/parsers/gas/tests/gas-instlabel.hex
 EXTRA_DIST += modules/parsers/gas/tests/gas-semi.asm
 EXTRA_DIST += modules/parsers/gas/tests/gas-semi.errwarn
 EXTRA_DIST += modules/parsers/gas/tests/gas-semi.hex
diff --git a/modules/parsers/gas/tests/gas-instlabel.asm b/modules/parsers/gas/tests/gas-instlabel.asm
new file mode 100644 (file)
index 0000000..44c4748
--- /dev/null
@@ -0,0 +1,3 @@
+       .globl  SUB
+       .type   SUB, @function
+SUB:
diff --git a/modules/parsers/gas/tests/gas-instlabel.errwarn b/modules/parsers/gas/tests/gas-instlabel.errwarn
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/modules/parsers/gas/tests/gas-instlabel.hex b/modules/parsers/gas/tests/gas-instlabel.hex
new file mode 100644 (file)
index 0000000..cba2591
--- /dev/null
@@ -0,0 +1,376 @@
+7f 
+45 
+4c 
+46 
+01 
+01 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+03 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+b0 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+34 
+00 
+00 
+00 
+00 
+00 
+28 
+00 
+05 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+2e 
+74 
+65 
+78 
+74 
+00 
+2e 
+73 
+74 
+72 
+74 
+61 
+62 
+00 
+2e 
+73 
+79 
+6d 
+74 
+61 
+62 
+00 
+2e 
+73 
+68 
+73 
+74 
+72 
+74 
+61 
+62 
+00 
+00 
+00 
+00 
+00 
+2d 
+00 
+53 
+55 
+42 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+04 
+00 
+f1 
+ff 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+03 
+00 
+04 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+12 
+00 
+04 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+17 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+40 
+00 
+00 
+00 
+21 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+07 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+64 
+00 
+00 
+00 
+07 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+0f 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+6c 
+00 
+00 
+00 
+40 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+10 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+06 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+40 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+10 
+00 
+00 
+00 
+00 
+00 
+00 
+00