1 %top{ 2 /* 3 * Copyright (c) 2002, 2004, 2010 Tama Communications Corporation 4 * 5 * This file is part of GNU GLOBAL. 6 * 7 * This program is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 #ifdef HAVE_CONFIG_H 22 #include <config.h> 23 #endif 24 #ifdef HAVE_STRING_H 25 #include <string.h> 26 #else 27 #include <strings.h> 28 #endif 29 30 #define YYLTYPE int 31 32 #include "internal.h" 33 #include "asm_parse.h" 34 #include "asm_res.h" 35 #include "die.h" 36 #include "linetable.h" 37 #include "strbuf.h" 38 39 #define lex_symbol_generation_rule(x) asm_ ## x 40 #define LEXLEX lex_symbol_generation_rule(lex) 41 #define LEXTEXT lex_symbol_generation_rule(text) 42 #define LEXLENG lex_symbol_generation_rule(leng) 43 #define LEXLINENO lex_symbol_generation_rule(lineno) 44 #define LEXRESTART lex_symbol_generation_rule(restart) 45 #define LEXLVAL lex_symbol_generation_rule(lval) 46 #define LEXLLOC lex_symbol_generation_rule(lloc) 47 48 #define YY_DECL int LEXLEX(const struct parser_param *param) 49 50 #define YY_INPUT(buf, result, max_size) do { \ 51 if ((result = linetable_read(buf, max_size)) == -1) \ 52 result = YY_NULL; \ 53 } while (0) 54 55 #define ADD_SYM(tag, lno) do { \ 56 LEXLVAL = strbuf_getlen(asm_symtable); \ 57 LEXLLOC = (lno); \ 58 strbuf_puts0(asm_symtable, tag); \ 59 } while (0) 60 61 #undef PUT 62 #define PUT(type, tag, lno) do { \ 63 const char *line_image = linetable_get(lno, NULL); \ 64 char *nl = strchr(line_image, '\n'); \ 65 if (nl != NULL) \ 66 *nl = '\0'; \ 67 param->put(type, tag, lno, param->file, line_image, param->arg);\ 68 if (nl != NULL) \ 69 *nl = '\n'; \ 70 } while (0) 71 72 static int last_directive; 73 74 } 75 76 H 0[Xx][0-9A-Fa-f]+ 77 N [0-9]+ 78 L {N}L? 79 D1 {N}\.{N}([Ee][+-]?{N})? 80 D2 \.{N}([Ee][+-]?{N})? 81 NUMBER -?({L}|{D1}|{D2}) 82 ALPHA [a-zA-Z_\x80-\xff] 83 ALPHANUM [a-zA-Z_\x80-\xff0-9] 84 WORD {ALPHA}{ALPHANUM}* 85 86 %x C_COMMENT CPP_COMMENT STRING LITERAL 87 %s PREPROCESSOR_LINE 88 89 %option 8bit yylineno stack noyywrap noyy_top_state never-interactive prefix="asm_" 90 91 %% 92 93 /* Ignore spaces */ 94 [ \f\t\v]+ 95 96 /* C style comment */ 97 "/*" { yy_push_state(C_COMMENT); } 98 <C_COMMENT>{ 99 [^*\n]* 100 [^*\n]*\n 101 "*"+[^*/\n]* 102 "*"+[^*/\n]*\n 103 "*"+"/" { yy_pop_state(); } 104 <<EOF>> { 105 if (param->flags & PARSER_WARNING) 106 warning("unexpected eof. [+%d %s]", LEXLINENO, param->file); 107 yyterminate(); 108 } 109 } 110 111 /* C++ style line comment */ 112 "//" { yy_push_state(CPP_COMMENT); } 113 <CPP_COMMENT>{ 114 (\\.|[^\\\n])+ 115 \\\n 116 \n { yy_pop_state(); unput('\n'); } 117 } 118 119 /* String */ 120 \" { yy_push_state(STRING); } 121 <STRING>{ 122 (\\.|[^\"\\\n])+ 123 \\\n 124 \n { yy_pop_state(); unput('\n'); return ASM_CONST; } 125 \" { yy_pop_state(); return ASM_CONST; } 126 } 127 128 /* Character */ 129 \' { yy_push_state(LITERAL); } 130 <LITERAL>{ 131 (\\.|[^\'\\\n])+ 132 \\\n 133 \n { yy_pop_state(); unput('\n'); return ASM_CONST; } 134 \' { yy_pop_state(); return ASM_CONST; } 135 } 136 137 /* Number */ 138 {NUMBER} { return ASM_CONST; } 139 140 <INITIAL>{ 141 ^[ \t]*\#[ \t]*{WORD} { 142 last_directive = asm_reserved_sharp(LEXTEXT, LEXLENG); 143 switch (last_directive) { 144 case 0: 145 yy_push_state(CPP_COMMENT); 146 break; 147 case SHARP_DEFINE: 148 yy_push_state(PREPROCESSOR_LINE); 149 return ASM_DEFINE; 150 case SHARP_UNDEF: 151 yy_push_state(PREPROCESSOR_LINE); 152 return ASM_UNDEF; 153 default: 154 yy_push_state(PREPROCESSOR_LINE); 155 return ASM_DIRECTIVE; 156 } 157 } 158 ^[ \t]*\# { 159 last_directive = 0; 160 yy_push_state(PREPROCESSOR_LINE); 161 return ASM_DIRECTIVE; 162 } 163 call|jsr { return ASM_CALL; } 164 \.macro|macro { return ASM_MACRO; } 165 \.equ|equ { return ASM_EQU; } 166 ^(ENTRY|ALTENTRY|NENTRY|GLOBAL_ENTRY|JSBENTRY|C_SYMBOL_NAME|C_ENTRY) { 167 ADD_SYM(LEXTEXT, LEXLINENO); 168 return ASM_ENTRY; 169 } 170 EXT|SYMBOL_NAME|C_LABEL { 171 ADD_SYM(LEXTEXT, LEXLINENO); 172 return ASM_EXT; 173 } 174 ^{WORD} { ADD_SYM(LEXTEXT, LEXLINENO); return ASM_LABEL; } 175 } 176 177 <PREPROCESSOR_LINE>{ 178 {WORD} { 179 switch (last_directive) { 180 case SHARP_IF: 181 case SHARP_ELIF: 182 if (strcmp(LEXTEXT, "defined") == 0) 183 break; 184 /* FALLTHROUGH */ 185 case SHARP_IFDEF: 186 case SHARP_IFNDEF: 187 PUT(PARSER_REF_SYM, LEXTEXT, LEXLINENO); 188 break; 189 default: 190 ADD_SYM(LEXTEXT, LEXLINENO); 191 return ASM_SYMBOL; 192 } 193 } 194 \n { yy_pop_state(); return '\n'; } 195 } 196 197 {WORD} { ADD_SYM(LEXTEXT, LEXLINENO); return ASM_SYMBOL; } 198 199 \\\n 200 \n { return '\n'; } 201 . { return LEXTEXT[0]; } 202 203 %% 204 205 void 206 asm_initscan(void) 207 { 208 BEGIN(INITIAL); 209 LEXRESTART(NULL); 210 LEXLINENO = 1; 211 } 212