1 %{ 2 /* $NetBSD: aicasm_scan.l,v 1.1 2000/03/15 02:09:14 fvdl Exp $ */ 3 4 /* 5 * Lexical Analyzer for the Aic7xxx SCSI Host adapter sequencer assembler. 6 * 7 * Copyright (c) 1997-1998 Justin T. Gibbs. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions, and the following disclaimer, 15 * without modification. 16 * 2. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 * 31 * $FreeBSD: src/sys/dev/aic7xxx/aicasm_scan.l,v 1.8 1999/12/06 18:23:30 gibbs Exp $ 32 */ 33 34 #include <sys/types.h> 35 36 #include <limits.h> 37 #include <stdio.h> 38 #include <string.h> 39 #include <sysexits.h> 40 #include <sys/queue.h> 41 42 #include "aicasm.h" 43 #include "aicasm_symbol.h" 44 #ifdef __NetBSD__ 45 #include "aicasm_gram.h" 46 #else 47 #include "y.tab.h" 48 #endif 49 50 #define MAX_STR_CONST 256 51 char string_buf[MAX_STR_CONST]; 52 char *string_buf_ptr; 53 int parren_count; 54 %} 55 56 PATH [-/A-Za-z0-9_.]*[./][-/A-Za-z0-9_.]* 57 WORD [A-Za-z_][-A-Za-z_0-9]* 58 SPACE [ \t]+ 59 60 %x COMMENT 61 %x CEXPR 62 %x INCLUDE 63 64 %% 65 \n { ++yylineno; } 66 "/*" { BEGIN COMMENT; /* Enter comment eating state */ } 67 <COMMENT>"/*" { fprintf(stderr, "Warning! Comment within comment."); } 68 <COMMENT>\n { ++yylineno; } 69 <COMMENT>[^*/\n]* ; 70 <COMMENT>"*"+[^*/\n]* ; 71 <COMMENT>"/"+[^*/\n]* ; 72 <COMMENT>"*"+"/" { BEGIN INITIAL; } 73 if[ \t]*\( { 74 string_buf_ptr = string_buf; 75 parren_count = 1; 76 BEGIN CEXPR; 77 return T_IF; 78 } 79 <CEXPR>\( { *string_buf_ptr++ = '('; parren_count++; } 80 <CEXPR>\) { 81 parren_count--; 82 if (parren_count == 0) { 83 /* All done */ 84 BEGIN INITIAL; 85 *string_buf_ptr = '\0'; 86 yylval.sym = symtable_get(string_buf); 87 return T_CEXPR; 88 } else { 89 *string_buf_ptr++ = ')'; 90 } 91 } 92 <CEXPR>\n { ++yylineno; } 93 <CEXPR>[^()\n]+ { 94 char *yptr = yytext; 95 96 while (*yptr != '\0') 97 *string_buf_ptr++ = *yptr++; 98 } 99 100 {SPACE} ; 101 102 /* Register/SCB/SRAM definition keywords */ 103 register { return T_REGISTER; } 104 const { yylval.value = FALSE; return T_CONST; } 105 download { return T_DOWNLOAD; } 106 address { return T_ADDRESS; } 107 access_mode { return T_ACCESS_MODE; } 108 RW|RO|WO { 109 if (strcmp(yytext, "RW") == 0) 110 yylval.value = RW; 111 else if (strcmp(yytext, "RO") == 0) 112 yylval.value = RO; 113 else 114 yylval.value = WO; 115 return T_MODE; 116 } 117 bit { return T_BIT; } 118 mask { return T_MASK; } 119 alias { return T_ALIAS; } 120 size { return T_SIZE; } 121 scb { return T_SCB; } 122 scratch_ram { return T_SRAM; } 123 accumulator { return T_ACCUM; } 124 allones { return T_ALLONES; } 125 allzeros { return T_ALLZEROS; } 126 none { return T_NONE; } 127 sindex { return T_SINDEX; } 128 A { return T_A; } 129 130 /* Opcodes */ 131 shl { return T_SHL; } 132 shr { return T_SHR; } 133 ror { return T_ROR; } 134 rol { return T_ROL; } 135 mvi { return T_MVI; } 136 mov { return T_MOV; } 137 clr { return T_CLR; } 138 jmp { return T_JMP; } 139 jc { return T_JC; } 140 jnc { return T_JNC; } 141 je { return T_JE; } 142 jne { return T_JNE; } 143 jz { return T_JZ; } 144 jnz { return T_JNZ; } 145 call { return T_CALL; } 146 add { return T_ADD; } 147 adc { return T_ADC; } 148 bmov { return T_BMOV; } 149 inc { return T_INC; } 150 dec { return T_DEC; } 151 stc { return T_STC; } 152 clc { return T_CLC; } 153 cmp { return T_CMP; } 154 xor { return T_XOR; } 155 test { return T_TEST;} 156 and { return T_AND; } 157 or { return T_OR; } 158 ret { return T_RET; } 159 nop { return T_NOP; } 160 else { return T_ELSE; } 161 162 /* Allowed Symbols */ 163 [-+,:()~|&."{};<>[\]!] { return yytext[0]; } 164 165 /* Number processing */ 166 0[0-7]* { 167 yylval.value = strtol(yytext, NULL, 8); 168 return T_NUMBER; 169 } 170 171 0[xX][0-9a-fA-F]+ { 172 yylval.value = strtoul(yytext + 2, NULL, 16); 173 return T_NUMBER; 174 } 175 176 [1-9][0-9]* { 177 yylval.value = strtol(yytext, NULL, 10); 178 return T_NUMBER; 179 } 180 181 /* Include Files */ 182 #include { return T_INCLUDE; BEGIN INCLUDE;} 183 <INCLUDE>[<>\"] { return yytext[0]; } 184 <INCLUDE>{PATH} { yylval.str = strdup(yytext); return T_PATH; } 185 <INCLUDE>; { BEGIN INITIAL; return yytext[0]; } 186 <INCLUDE>. { stop("Invalid include line", EX_DATAERR); } 187 188 /* For parsing C include files with #define foo */ 189 #define { yylval.value = TRUE; return T_CONST; } 190 /* Throw away macros */ 191 #define[^\n]*[()]+[^\n]* ; 192 {PATH} { yylval.str = strdup(yytext); return T_PATH; } 193 194 {WORD} { yylval.sym = symtable_get(yytext); return T_SYMBOL; } 195 196 . { 197 char buf[255]; 198 199 snprintf(buf, sizeof(buf), "Invalid character " 200 "'%c'", yytext[0]); 201 stop(buf, EX_DATAERR); 202 } 203 %% 204 205 typedef struct include { 206 YY_BUFFER_STATE buffer; 207 int lineno; 208 char *filename; 209 SLIST_ENTRY(include) links; 210 }include_t; 211 212 SLIST_HEAD(, include) include_stack; 213 214 void 215 include_file(file_name, type) 216 char *file_name; 217 include_type type; 218 { 219 FILE *newfile; 220 include_t *include; 221 222 newfile = NULL; 223 /* Try the current directory first */ 224 if (includes_search_curdir != 0 || type == SOURCE_FILE) 225 newfile = fopen(file_name, "r"); 226 227 if (newfile == NULL && type != SOURCE_FILE) { 228 path_entry_t include_dir; 229 for (include_dir = search_path.slh_first; 230 include_dir != NULL; 231 include_dir = include_dir->links.sle_next) { 232 char fullname[PATH_MAX]; 233 234 if ((include_dir->quoted_includes_only == TRUE) 235 && (type != QUOTED_INCLUDE)) 236 continue; 237 238 snprintf(fullname, sizeof(fullname), 239 "%s/%s", include_dir->directory, file_name); 240 241 if ((newfile = fopen(fullname, "r")) != NULL) 242 break; 243 } 244 } 245 246 if (newfile == NULL) { 247 perror(file_name); 248 stop("Unable to open input file", EX_SOFTWARE); 249 /* NOTREACHED */ 250 } 251 252 if (type != SOURCE_FILE) { 253 include = (include_t *)malloc(sizeof(include_t)); 254 if (include == NULL) { 255 stop("Unable to allocate include stack entry", 256 EX_SOFTWARE); 257 /* NOTREACHED */ 258 } 259 include->buffer = YY_CURRENT_BUFFER; 260 include->lineno = yylineno; 261 include->filename = yyfilename; 262 SLIST_INSERT_HEAD(&include_stack, include, links); 263 } 264 yy_switch_to_buffer(yy_create_buffer(newfile, YY_BUF_SIZE)); 265 yylineno = 1; 266 yyfilename = strdup(file_name); 267 } 268 269 int 270 yywrap() 271 { 272 include_t *include; 273 274 yy_delete_buffer(YY_CURRENT_BUFFER); 275 (void)fclose(yyin); 276 if (yyfilename != NULL) 277 free(yyfilename); 278 yyfilename = NULL; 279 include = include_stack.slh_first; 280 if (include != NULL) { 281 yy_switch_to_buffer(include->buffer); 282 yylineno = include->lineno; 283 yyfilename = include->filename; 284 SLIST_REMOVE_HEAD(&include_stack, links); 285 free(include); 286 return (0); 287 } 288 return (1); 289 } 290