1 %{ 2 /* 3 * Lexical Analyzer for the Aic7xxx SCSI Host adapter sequencer assembler. 4 * 5 * Copyright (c) 1997 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 immediately at the beginning of the file, without modification, 13 * this list of conditions, and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. The name of the author may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 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 * $Id: scan.l,v 1.1 1997/03/16 07:08:17 gibbs Exp $ 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 "aic7xxx_asm.h" 44 #include "symbol.h" 45 #include "y.tab.h" 46 %} 47 48 PATH [-/A-Za-z0-9_.]*[./][-/A-Za-z0-9_.]* 49 WORD [A-Za-z_][-A-Za-z_0-9]* 50 SPACE [ \t]+ 51 52 %x COMMENT 53 54 %% 55 \n { ++yylineno; } 56 "/*" { BEGIN COMMENT; /* Enter comment eating state */ } 57 <COMMENT>"/*" { fprintf(stderr, "Warning! Comment within comment."); } 58 <COMMENT>\n { ++yylineno; } 59 <COMMENT>[^*/\n]* ; 60 <COMMENT>"*"+[^*/\n]* ; 61 <COMMENT>"/"+[^*/\n]* ; 62 <COMMENT>"*"+"/" { BEGIN INITIAL; } 63 64 {SPACE} ; 65 66 /* Register/SCB/SRAM definition keywords */ 67 register { return T_REGISTER; } 68 const { yylval.value = FALSE; return T_CONST; } 69 address { return T_ADDRESS; } 70 access_mode { return T_ACCESS_MODE; } 71 RW|RO|WO { 72 if (strcmp(yytext, "RW") == 0) 73 yylval.value = RW; 74 else if (strcmp(yytext, "RO") == 0) 75 yylval.value = RO; 76 else 77 yylval.value = WO; 78 return T_MODE; 79 } 80 bit { return T_BIT; } 81 mask { return T_MASK; } 82 alias { return T_ALIAS; } 83 size { return T_SIZE; } 84 scb { return T_SCB; } 85 scratch_ram { return T_SRAM; } 86 accumulator { return T_ACCUM; } 87 allones { return T_ALLONES; } 88 allzeros { return T_ALLZEROS; } 89 none { return T_NONE; } 90 sindex { return T_SINDEX; } 91 A { return T_A; } 92 93 /* Opcodes */ 94 shl { return T_SHL; } 95 shr { return T_SHR; } 96 ror { return T_ROR; } 97 rol { return T_ROL; } 98 mvi { return T_MVI; } 99 mov { return T_MOV; } 100 clr { return T_CLR; } 101 jmp { return T_JMP; } 102 jc { return T_JC; } 103 jnc { return T_JNC; } 104 je { return T_JE; } 105 jne { return T_JNE; } 106 jz { return T_JZ; } 107 jnz { return T_JNZ; } 108 call { return T_CALL; } 109 add { return T_ADD; } 110 adc { return T_ADC; } 111 inc { return T_INC; } 112 dec { return T_DEC; } 113 stc { return T_STC; } 114 clc { return T_CLC; } 115 cmp { return T_CMP; } 116 xor { return T_XOR; } 117 test { return T_TEST;} 118 and { return T_AND; } 119 or { return T_OR; } 120 ret { return T_RET; } 121 nop { return T_NOP; } 122 .if { return T_IF; } 123 .else { return T_ELSE; } 124 .endif { return T_ENDIF; } 125 126 /* Allowed Symbols */ 127 [-+,:()~|&."{};<>[\]!] { return yytext[0]; } 128 129 /* Number processing */ 130 0[0-7]* { 131 yylval.value = strtol(yytext, NULL, 8); 132 return T_NUMBER; 133 } 134 135 0[xX][0-9a-fA-F]+ { 136 yylval.value = strtoul(yytext + 2, NULL, 16); 137 return T_NUMBER; 138 } 139 140 [1-9][0-9]* { 141 yylval.value = strtol(yytext, NULL, 10); 142 return T_NUMBER; 143 } 144 145 /* Include Files */ 146 #include { return T_INCLUDE; } 147 148 /* For parsing C include files with #define foo */ 149 #define { yylval.value = TRUE; return T_CONST; } 150 /* Throw away macros */ 151 #define[^\n]*[()]+[^\n]* ; 152 {PATH} { yylval.str = strdup(yytext); return T_PATH; } 153 154 {WORD} { yylval.sym = symtable_get(yytext); return T_SYMBOL; } 155 156 . { 157 char buf[255]; 158 159 snprintf(buf, sizeof(buf), "Invalid character " 160 "'%c'", yytext[0]); 161 stop(buf, EX_DATAERR); 162 } 163 %% 164 165 typedef struct include { 166 YY_BUFFER_STATE buffer; 167 int lineno; 168 char *filename; 169 SLIST_ENTRY(include) links; 170 }include_t; 171 172 SLIST_HEAD(, include) include_stack; 173 174 void 175 include_file(file_name, type) 176 char *file_name; 177 include_type type; 178 { 179 FILE *newfile; 180 include_t *include; 181 182 newfile = NULL; 183 /* Try the current directory first */ 184 if (includes_search_curdir != 0 || type == SOURCE_FILE) 185 newfile = fopen(file_name, "r"); 186 187 if (newfile == NULL && type != SOURCE_FILE) { 188 path_entry_t include_dir; 189 for (include_dir = search_path.slh_first; 190 include_dir != NULL; 191 include_dir = include_dir->links.sle_next) { 192 char fullname[PATH_MAX]; 193 194 if ((include_dir->quoted_includes_only == TRUE) 195 && (type != QUOTED_INCLUDE)) 196 continue; 197 198 snprintf(fullname, sizeof(fullname), 199 "%s/%s", include_dir->directory, file_name); 200 201 if ((newfile = fopen(fullname, "r")) != NULL) 202 break; 203 } 204 } 205 206 if (newfile == NULL) { 207 perror(file_name); 208 stop("Unable to open input file", EX_SOFTWARE); 209 /* NOTREACHED */ 210 } 211 include = (include_t *)malloc(sizeof(include_t)); 212 if (include == NULL) { 213 stop("Unable to allocate include stack entry", EX_SOFTWARE); 214 /* NOTREACHED */ 215 } 216 include->buffer = YY_CURRENT_BUFFER; 217 include->lineno = yylineno; 218 include->filename = yyfilename; 219 SLIST_INSERT_HEAD(&include_stack, include, links); 220 yy_switch_to_buffer(yy_create_buffer(newfile, YY_BUF_SIZE)); 221 yylineno = 1; 222 yyfilename = strdup(file_name); 223 } 224 225 int 226 yywrap() 227 { 228 include_t *include; 229 230 yy_delete_buffer(YY_CURRENT_BUFFER); 231 (void)fclose(yyin); 232 if (yyfilename != NULL) 233 free(yyfilename); 234 include = include_stack.slh_first; 235 if (include != NULL) { 236 yy_switch_to_buffer(include->buffer); 237 yylineno = include->lineno; 238 yyfilename = include->filename; 239 SLIST_REMOVE_HEAD(&include_stack, links); 240 free(include); 241 return (0); 242 } 243 return (1); 244 } 245