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