aicasm_scan.l revision 66270
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 * $Id: //depot/src/aic7xxx/aicasm/aicasm_scan.l#3 $ 33 * 34 * $FreeBSD: head/sys/dev/aic7xxx/aicasm/aicasm_scan.l 66270 2000-09-22 22:19:55Z gibbs $ 35 */ 36 37#include <sys/types.h> 38 39#include <limits.h> 40#include <stdio.h> 41#include <string.h> 42#include <sysexits.h> 43#ifdef __linux__ 44#include "../queue.h" 45#else 46#include <sys/queue.h> 47#endif 48 49#include "aicasm.h" 50#include "aicasm_symbol.h" 51#include "y.tab.h" 52 53#define MAX_STR_CONST 256 54char string_buf[MAX_STR_CONST]; 55char *string_buf_ptr; 56int parren_count; 57%} 58 59PATH [-/A-Za-z0-9_.]*[./][-/A-Za-z0-9_.]* 60WORD [A-Za-z_][-A-Za-z_0-9]* 61SPACE [ \t]+ 62 63%x COMMENT 64%x CEXPR 65%x INCLUDE 66 67%% 68\n { ++yylineno; } 69"/*" { BEGIN COMMENT; /* Enter comment eating state */ } 70<COMMENT>"/*" { fprintf(stderr, "Warning! Comment within comment."); } 71<COMMENT>\n { ++yylineno; } 72<COMMENT>[^*/\n]* ; 73<COMMENT>"*"+[^*/\n]* ; 74<COMMENT>"/"+[^*/\n]* ; 75<COMMENT>"*"+"/" { BEGIN INITIAL; } 76if[ \t]*\( { 77 string_buf_ptr = string_buf; 78 parren_count = 1; 79 BEGIN CEXPR; 80 return T_IF; 81 } 82<CEXPR>\( { *string_buf_ptr++ = '('; parren_count++; } 83<CEXPR>\) { 84 parren_count--; 85 if (parren_count == 0) { 86 /* All done */ 87 BEGIN INITIAL; 88 *string_buf_ptr = '\0'; 89 yylval.sym = symtable_get(string_buf); 90 return T_CEXPR; 91 } else { 92 *string_buf_ptr++ = ')'; 93 } 94 } 95<CEXPR>\n { ++yylineno; } 96<CEXPR>[^()\n]+ { 97 char *yptr = yytext; 98 99 while (*yptr != '\0') { 100 /* Remove duplicate spaces */ 101 if (*yptr == '\t') 102 *yptr = ' '; 103 if (*yptr == ' ' 104 && string_buf_ptr != string_buf 105 && string_buf_ptr[-1] == ' ') 106 yptr++; 107 else 108 *string_buf_ptr++ = *yptr++; 109 } 110 } 111 112{SPACE} ; 113 114 /* Register/SCB/SRAM definition keywords */ 115register { return T_REGISTER; } 116const { yylval.value = FALSE; return T_CONST; } 117download { return T_DOWNLOAD; } 118address { return T_ADDRESS; } 119access_mode { return T_ACCESS_MODE; } 120RW|RO|WO { 121 if (strcmp(yytext, "RW") == 0) 122 yylval.value = RW; 123 else if (strcmp(yytext, "RO") == 0) 124 yylval.value = RO; 125 else 126 yylval.value = WO; 127 return T_MODE; 128 } 129BEGIN_CRITICAL { return T_BEGIN_CS; } 130END_CRITICAL { return T_END_CS; } 131bit { return T_BIT; } 132mask { return T_MASK; } 133alias { return T_ALIAS; } 134size { return T_SIZE; } 135scb { return T_SCB; } 136scratch_ram { return T_SRAM; } 137accumulator { return T_ACCUM; } 138allones { return T_ALLONES; } 139allzeros { return T_ALLZEROS; } 140none { return T_NONE; } 141sindex { return T_SINDEX; } 142A { return T_A; } 143 144 /* Opcodes */ 145shl { return T_SHL; } 146shr { return T_SHR; } 147ror { return T_ROR; } 148rol { return T_ROL; } 149mvi { return T_MVI; } 150mov { return T_MOV; } 151clr { return T_CLR; } 152jmp { return T_JMP; } 153jc { return T_JC; } 154jnc { return T_JNC; } 155je { return T_JE; } 156jne { return T_JNE; } 157jz { return T_JZ; } 158jnz { return T_JNZ; } 159call { return T_CALL; } 160add { return T_ADD; } 161adc { return T_ADC; } 162bmov { return T_BMOV; } 163inc { return T_INC; } 164dec { return T_DEC; } 165stc { return T_STC; } 166clc { return T_CLC; } 167cmp { return T_CMP; } 168not { return T_NOT; } 169xor { return T_XOR; } 170test { return T_TEST;} 171and { return T_AND; } 172or { return T_OR; } 173ret { return T_RET; } 174nop { return T_NOP; } 175else { return T_ELSE; } 176 177 /* Allowed Symbols */ 178[-+,:()~|&."{};<>[\]!] { return yytext[0]; } 179 180 /* Number processing */ 1810[0-7]* { 182 yylval.value = strtol(yytext, NULL, 8); 183 return T_NUMBER; 184 } 185 1860[xX][0-9a-fA-F]+ { 187 yylval.value = strtoul(yytext + 2, NULL, 16); 188 return T_NUMBER; 189 } 190 191[1-9][0-9]* { 192 yylval.value = strtol(yytext, NULL, 10); 193 return T_NUMBER; 194 } 195 196 /* Include Files */ 197#include { return T_INCLUDE; BEGIN INCLUDE;} 198<INCLUDE>[<>\"] { return yytext[0]; } 199<INCLUDE>{PATH} { yylval.str = strdup(yytext); return T_PATH; } 200<INCLUDE>; { BEGIN INITIAL; return yytext[0]; } 201<INCLUDE>. { stop("Invalid include line", EX_DATAERR); } 202 203 /* For parsing C include files with #define foo */ 204#define { yylval.value = TRUE; return T_CONST; } 205 /* Throw away macros */ 206#define[^\n]*[()]+[^\n]* ; 207{PATH} { yylval.str = strdup(yytext); return T_PATH; } 208 209{WORD} { yylval.sym = symtable_get(yytext); return T_SYMBOL; } 210 211. { 212 char buf[255]; 213 214 snprintf(buf, sizeof(buf), "Invalid character " 215 "'%c'", yytext[0]); 216 stop(buf, EX_DATAERR); 217 } 218%% 219 220typedef struct include { 221 YY_BUFFER_STATE buffer; 222 int lineno; 223 char *filename; 224 SLIST_ENTRY(include) links; 225}include_t; 226 227SLIST_HEAD(, include) include_stack; 228 229void 230include_file(char *file_name, include_type type) 231{ 232 FILE *newfile; 233 include_t *include; 234 235 newfile = NULL; 236 /* Try the current directory first */ 237 if (includes_search_curdir != 0 || type == SOURCE_FILE) 238 newfile = fopen(file_name, "r"); 239 240 if (newfile == NULL && type != SOURCE_FILE) { 241 path_entry_t include_dir; 242 for (include_dir = search_path.slh_first; 243 include_dir != NULL; 244 include_dir = include_dir->links.sle_next) { 245 char fullname[PATH_MAX]; 246 247 if ((include_dir->quoted_includes_only == TRUE) 248 && (type != QUOTED_INCLUDE)) 249 continue; 250 251 snprintf(fullname, sizeof(fullname), 252 "%s/%s", include_dir->directory, file_name); 253 254 if ((newfile = fopen(fullname, "r")) != NULL) 255 break; 256 } 257 } 258 259 if (newfile == NULL) { 260 perror(file_name); 261 stop("Unable to open input file", EX_SOFTWARE); 262 /* NOTREACHED */ 263 } 264 265 if (type != SOURCE_FILE) { 266 include = (include_t *)malloc(sizeof(include_t)); 267 if (include == NULL) { 268 stop("Unable to allocate include stack entry", 269 EX_SOFTWARE); 270 /* NOTREACHED */ 271 } 272 include->buffer = YY_CURRENT_BUFFER; 273 include->lineno = yylineno; 274 include->filename = yyfilename; 275 SLIST_INSERT_HEAD(&include_stack, include, links); 276 } 277 yy_switch_to_buffer(yy_create_buffer(newfile, YY_BUF_SIZE)); 278 yylineno = 1; 279 yyfilename = strdup(file_name); 280} 281 282int 283yywrap() 284{ 285 include_t *include; 286 287 yy_delete_buffer(YY_CURRENT_BUFFER); 288 (void)fclose(yyin); 289 if (yyfilename != NULL) 290 free(yyfilename); 291 yyfilename = NULL; 292 include = include_stack.slh_first; 293 if (include != NULL) { 294 yy_switch_to_buffer(include->buffer); 295 yylineno = include->lineno; 296 yyfilename = include->filename; 297 SLIST_REMOVE_HEAD(&include_stack, links); 298 free(include); 299 return (0); 300 } 301 return (1); 302} 303