aicasm_scan.l revision 66270
189051Sjake%{ 289051Sjake/* 3182916Smarius * Lexical Analyzer for the Aic7xxx SCSI Host adapter sequencer assembler. 489051Sjake * 589051Sjake * Copyright (c) 1997, 1998 Justin T. Gibbs. 689051Sjake * All rights reserved. 789051Sjake * 889051Sjake * Redistribution and use in source and binary forms, with or without 989051Sjake * modification, are permitted provided that the following conditions 1089051Sjake * are met: 1189051Sjake * 1. Redistributions of source code must retain the above copyright 1289051Sjake * notice, this list of conditions, and the following disclaimer, 1389051Sjake * without modification. 1489051Sjake * 2. The name of the author may not be used to endorse or promote products 1589051Sjake * derived from this software without specific prior written permission. 1689051Sjake * 1789051Sjake * Alternatively, this software may be distributed under the terms of the 1889051Sjake * GNU Public License ("GPL"). 1989051Sjake * 2089051Sjake * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 2189051Sjake * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2289051Sjake * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2389051Sjake * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 2489051Sjake * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2589051Sjake * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2689051Sjake * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2789051Sjake * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28114188Sjake * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29114188Sjake * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30114188Sjake * SUCH DAMAGE. 3189051Sjake * 3289051Sjake * $Id: //depot/src/aic7xxx/aicasm/aicasm_scan.l#3 $ 33207248Smarius * 3489051Sjake * $FreeBSD: head/sys/dev/aic7xxx/aicasm/aicasm_scan.l 66270 2000-09-22 22:19:55Z gibbs $ 3589051Sjake */ 36166105Smarius 37182730Smarius#include <sys/types.h> 3889051Sjake 3989051Sjake#include <limits.h> 4089051Sjake#include <stdio.h> 4189051Sjake#include <string.h> 4289051Sjake#include <sysexits.h> 4389051Sjake#ifdef __linux__ 4491617Sjake#include "../queue.h" 45100899Sjake#else 46182916Smarius#include <sys/queue.h> 47203833Smarius#endif 48207248Smarius 49203833Smarius#include "aicasm.h" 50203833Smarius#include "aicasm_symbol.h" 51203833Smarius#include "y.tab.h" 52203833Smarius 53182916Smarius#define MAX_STR_CONST 256 54182916Smariuschar string_buf[MAX_STR_CONST]; 55207248Smariuschar *string_buf_ptr; 56182916Smariusint parren_count; 57182916Smarius%} 58182916Smarius 59182916SmariusPATH [-/A-Za-z0-9_.]*[./][-/A-Za-z0-9_.]* 60182916SmariusWORD [A-Za-z_][-A-Za-z_0-9]* 61182916SmariusSPACE [ \t]+ 62182916Smarius 63182916Smarius%x COMMENT 64182916Smarius%x CEXPR 65182916Smarius%x INCLUDE 66182916Smarius 67182916Smarius%% 68182916Smarius\n { ++yylineno; } 69182916Smarius"/*" { BEGIN COMMENT; /* Enter comment eating state */ } 70182916Smarius<COMMENT>"/*" { fprintf(stderr, "Warning! Comment within comment."); } 71182916Smarius<COMMENT>\n { ++yylineno; } 72182916Smarius<COMMENT>[^*/\n]* ; 73203833Smarius<COMMENT>"*"+[^*/\n]* ; 74182916Smarius<COMMENT>"/"+[^*/\n]* ; 75182916Smarius<COMMENT>"*"+"/" { BEGIN INITIAL; } 76182916Smariusif[ \t]*\( { 77182916Smarius string_buf_ptr = string_buf; 78182916Smarius parren_count = 1; 79182916Smarius BEGIN CEXPR; 80182916Smarius return T_IF; 81182916Smarius } 82182916Smarius<CEXPR>\( { *string_buf_ptr++ = '('; parren_count++; } 83182916Smarius<CEXPR>\) { 84182916Smarius parren_count--; 85182916Smarius if (parren_count == 0) { 86182916Smarius /* All done */ 87182916Smarius BEGIN INITIAL; 88182916Smarius *string_buf_ptr = '\0'; 89182916Smarius yylval.sym = symtable_get(string_buf); 90182916Smarius return T_CEXPR; 91182916Smarius } else { 92182916Smarius *string_buf_ptr++ = ')'; 93182916Smarius } 94182916Smarius } 95182916Smarius<CEXPR>\n { ++yylineno; } 96182916Smarius<CEXPR>[^()\n]+ { 97182916Smarius char *yptr = yytext; 98182916Smarius 99203833Smarius while (*yptr != '\0') { 100182916Smarius /* Remove duplicate spaces */ 101182916Smarius if (*yptr == '\t') 102182916Smarius *yptr = ' '; 103182916Smarius if (*yptr == ' ' 104182916Smarius && string_buf_ptr != string_buf 105182916Smarius && string_buf_ptr[-1] == ' ') 106182916Smarius yptr++; 107182916Smarius else 108182916Smarius *string_buf_ptr++ = *yptr++; 109182916Smarius } 110182916Smarius } 111182916Smarius 112182916Smarius{SPACE} ; 113182916Smarius 114182916Smarius /* Register/SCB/SRAM definition keywords */ 115182916Smariusregister { return T_REGISTER; } 116182916Smariusconst { yylval.value = FALSE; return T_CONST; } 11791617Sjakedownload { return T_DOWNLOAD; } 118182916Smariusaddress { return T_ADDRESS; } 119182916Smariusaccess_mode { return T_ACCESS_MODE; } 12091617SjakeRW|RO|WO { 12191617Sjake if (strcmp(yytext, "RW") == 0) 12291617Sjake yylval.value = RW; 123102040Sjake else if (strcmp(yytext, "RO") == 0) 124102040Sjake yylval.value = RO; 12591617Sjake else 12691617Sjake yylval.value = WO; 12791617Sjake return T_MODE; 128182916Smarius } 129182916SmariusBEGIN_CRITICAL { return T_BEGIN_CS; } 130182916SmariusEND_CRITICAL { return T_END_CS; } 131182916Smariusbit { return T_BIT; } 132182916Smariusmask { return T_MASK; } 133182916Smariusalias { return T_ALIAS; } 134182916Smariussize { return T_SIZE; } 135182916Smariusscb { return T_SCB; } 136182916Smariusscratch_ram { return T_SRAM; } 137182916Smariusaccumulator { return T_ACCUM; } 138182916Smariusallones { return T_ALLONES; } 139182916Smariusallzeros { return T_ALLZEROS; } 140182916Smariusnone { return T_NONE; } 141203833Smariussindex { return T_SINDEX; } 142182916SmariusA { return T_A; } 143182916Smarius 144182916Smarius /* Opcodes */ 145182916Smariusshl { return T_SHL; } 146182916Smariusshr { return T_SHR; } 147182916Smariusror { return T_ROR; } 148182916Smariusrol { return T_ROL; } 149182916Smariusmvi { return T_MVI; } 150182916Smariusmov { return T_MOV; } 15191617Sjakeclr { return T_CLR; } 152182916Smariusjmp { return T_JMP; } 153182916Smariusjc { return T_JC; } 154182916Smariusjnc { return T_JNC; } 155182916Smariusje { return T_JE; } 156182916Smariusjne { return T_JNE; } 157182916Smariusjz { return T_JZ; } 158182916Smariusjnz { return T_JNZ; } 15991617Sjakecall { return T_CALL; } 160182916Smariusadd { return T_ADD; } 161182916Smariusadc { return T_ADC; } 16291617Sjakebmov { return T_BMOV; } 163182916Smariusinc { return T_INC; } 16491617Sjakedec { return T_DEC; } 165182916Smariusstc { return T_STC; } 16691617Sjakeclc { return T_CLC; } 16791617Sjakecmp { return T_CMP; } 168100899Sjakenot { return T_NOT; } 169182916Smariusxor { return T_XOR; } 170182916Smariustest { return T_TEST;} 171182916Smariusand { return T_AND; } 17291617Sjakeor { return T_OR; } 17391617Sjakeret { return T_RET; } 17491617Sjakenop { return T_NOP; } 17591617Sjakeelse { return T_ELSE; } 176182916Smarius 17791617Sjake /* Allowed Symbols */ 178182916Smarius[-+,:()~|&."{};<>[\]!] { return yytext[0]; } 17991617Sjake 180182916Smarius /* Number processing */ 18191617Sjake0[0-7]* { 18289051Sjake yylval.value = strtol(yytext, NULL, 8); 18391617Sjake return T_NUMBER; 18489051Sjake } 18591617Sjake 18691617Sjake0[xX][0-9a-fA-F]+ { 18791617Sjake yylval.value = strtoul(yytext + 2, NULL, 16); 188182730Smarius return T_NUMBER; 18989051Sjake } 19091617Sjake 19189051Sjake[1-9][0-9]* { 19291617Sjake yylval.value = strtol(yytext, NULL, 10); 19391617Sjake return T_NUMBER; 19491617Sjake } 19591617Sjake 19691617Sjake /* Include Files */ 197182730Smarius#include { return T_INCLUDE; BEGIN INCLUDE;} 198182730Smarius<INCLUDE>[<>\"] { return yytext[0]; } 19991617Sjake<INCLUDE>{PATH} { yylval.str = strdup(yytext); return T_PATH; } 200182730Smarius<INCLUDE>; { BEGIN INITIAL; return yytext[0]; } 201182730Smarius<INCLUDE>. { stop("Invalid include line", EX_DATAERR); } 202182730Smarius 203207537Smarius /* For parsing C include files with #define foo */ 204207537Smarius#define { yylval.value = TRUE; return T_CONST; } 205207537Smarius /* Throw away macros */ 206207537Smarius#define[^\n]*[()]+[^\n]* ; 207207537Smarius{PATH} { yylval.str = strdup(yytext); return T_PATH; } 208207537Smarius 209182730Smarius{WORD} { yylval.sym = symtable_get(yytext); return T_SYMBOL; } 210209138Smarius 211182730Smarius. { 212207537Smarius char buf[255]; 213182730Smarius 214204152Smarius snprintf(buf, sizeof(buf), "Invalid character " 215182730Smarius "'%c'", yytext[0]); 216207537Smarius stop(buf, EX_DATAERR); 217207537Smarius } 218182730Smarius%% 219204152Smarius 220182730Smariustypedef struct include { 221207537Smarius YY_BUFFER_STATE buffer; 222204152Smarius int lineno; 223182730Smarius char *filename; 22489051Sjake SLIST_ENTRY(include) links; 22591617Sjake}include_t; 22689051Sjake 22791617SjakeSLIST_HEAD(, include) include_stack; 22891617Sjake 22991617Sjakevoid 23091617Sjakeinclude_file(char *file_name, include_type type) 23191617Sjake{ 23291617Sjake FILE *newfile; 23391617Sjake include_t *include; 234207537Smarius 23591617Sjake newfile = NULL; 236207537Smarius /* Try the current directory first */ 23789051Sjake if (includes_search_curdir != 0 || type == SOURCE_FILE) 23889051Sjake newfile = fopen(file_name, "r"); 23991783Sjake 24091783Sjake if (newfile == NULL && type != SOURCE_FILE) { 24191783Sjake path_entry_t include_dir; 24289051Sjake for (include_dir = search_path.slh_first; 243181701Smarius include_dir != NULL; 24489051Sjake include_dir = include_dir->links.sle_next) { 245207537Smarius char fullname[PATH_MAX]; 24691783Sjake 24789051Sjake if ((include_dir->quoted_includes_only == TRUE) 24891783Sjake && (type != QUOTED_INCLUDE)) 24991783Sjake continue; 25091783Sjake 25189051Sjake snprintf(fullname, sizeof(fullname), 252102040Sjake "%s/%s", include_dir->directory, file_name); 253102040Sjake 25491783Sjake if ((newfile = fopen(fullname, "r")) != NULL) 25591783Sjake break; 25689051Sjake } 25789051Sjake } 25891783Sjake 25991783Sjake if (newfile == NULL) { 260207537Smarius perror(file_name); 26191783Sjake stop("Unable to open input file", EX_SOFTWARE); 26291783Sjake /* NOTREACHED */ 26389051Sjake } 264181701Smarius 265181701Smarius if (type != SOURCE_FILE) { 26689051Sjake include = (include_t *)malloc(sizeof(include_t)); 26791783Sjake if (include == NULL) { 26891617Sjake stop("Unable to allocate include stack entry", 26991617Sjake EX_SOFTWARE); 27091617Sjake /* NOTREACHED */ 27189051Sjake } 272222828Smarius include->buffer = YY_CURRENT_BUFFER; 273222828Smarius include->lineno = yylineno; 274222828Smarius include->filename = yyfilename; 275222828Smarius SLIST_INSERT_HEAD(&include_stack, include, links); 27689051Sjake } 27789051Sjake yy_switch_to_buffer(yy_create_buffer(newfile, YY_BUF_SIZE)); 278203838Smarius yylineno = 1; 27989051Sjake yyfilename = strdup(file_name); 280222828Smarius} 28189051Sjake 282222828Smariusint 28389051Sjakeyywrap() 28491783Sjake{ 28589051Sjake include_t *include; 28689051Sjake 28789051Sjake yy_delete_buffer(YY_CURRENT_BUFFER); 28889051Sjake (void)fclose(yyin); 28989051Sjake if (yyfilename != NULL) 29089051Sjake free(yyfilename); 29189051Sjake yyfilename = NULL; 29289051Sjake include = include_stack.slh_first; 29391617Sjake if (include != NULL) { 29489051Sjake yy_switch_to_buffer(include->buffer); 29589051Sjake yylineno = include->lineno; 29691617Sjake yyfilename = include->filename; 297 SLIST_REMOVE_HEAD(&include_stack, links); 298 free(include); 299 return (0); 300 } 301 return (1); 302} 303