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