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