3 * Lexical Analyzer for the Aic7xxx SCSI Host adapter sequencer assembler.
5 * Copyright (c) 1997-1998 Justin T. Gibbs.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/types.h>
38 #include <sys/queue.h>
41 #include "aicasm_symbol.h"
44 #define MAX_STR_CONST 256
45 char string_buf[MAX_STR_CONST];
50 PATH [-/A-Za-z0-9_.]*[./][-/A-Za-z0-9_.]*
51 WORD [A-Za-z_][-A-Za-z_0-9]*
60 "/*" { BEGIN COMMENT; /* Enter comment eating state */ }
61 <COMMENT>"/*" { fprintf(stderr, "Warning! Comment within comment."); }
62 <COMMENT>\n { ++yylineno; }
64 <COMMENT>"*"+[^*/\n]* ;
65 <COMMENT>"/"+[^*/\n]* ;
66 <COMMENT>"*"+"/" { BEGIN INITIAL; }
68 string_buf_ptr = string_buf;
73 <CEXPR>\( { *string_buf_ptr++ = '('; parren_count++; }
76 if (parren_count == 0) {
79 *string_buf_ptr = '\0';
80 yylval.sym = symtable_get(string_buf);
83 *string_buf_ptr++ = ')';
86 <CEXPR>\n { ++yylineno; }
91 *string_buf_ptr++ = *yptr++;
96 /* Register/SCB/SRAM definition keywords */
97 register { return T_REGISTER; }
98 const { yylval.value = FALSE; return T_CONST; }
99 download { return T_DOWNLOAD; }
100 address { return T_ADDRESS; }
101 access_mode { return T_ACCESS_MODE; }
103 if (strcmp(yytext, "RW") == 0)
105 else if (strcmp(yytext, "RO") == 0)
111 bit { return T_BIT; }
112 mask { return T_MASK; }
113 alias { return T_ALIAS; }
114 size { return T_SIZE; }
115 scb { return T_SCB; }
116 scratch_ram { return T_SRAM; }
117 accumulator { return T_ACCUM; }
118 allones { return T_ALLONES; }
119 allzeros { return T_ALLZEROS; }
120 none { return T_NONE; }
121 sindex { return T_SINDEX; }
125 shl { return T_SHL; }
126 shr { return T_SHR; }
127 ror { return T_ROR; }
128 rol { return T_ROL; }
129 mvi { return T_MVI; }
130 mov { return T_MOV; }
131 clr { return T_CLR; }
132 jmp { return T_JMP; }
134 jnc { return T_JNC; }
136 jne { return T_JNE; }
138 jnz { return T_JNZ; }
139 call { return T_CALL; }
140 add { return T_ADD; }
141 adc { return T_ADC; }
142 bmov { return T_BMOV; }
143 inc { return T_INC; }
144 dec { return T_DEC; }
145 stc { return T_STC; }
146 clc { return T_CLC; }
147 cmp { return T_CMP; }
148 xor { return T_XOR; }
149 test { return T_TEST;}
150 and { return T_AND; }
152 ret { return T_RET; }
153 nop { return T_NOP; }
154 else { return T_ELSE; }
156 /* Allowed Symbols */
157 [-+,:()~|&."{};<>[\]!] { return yytext[0]; }
159 /* Number processing */
161 yylval.value = strtol(yytext, NULL, 8);
166 yylval.value = strtoul(yytext + 2, NULL, 16);
171 yylval.value = strtol(yytext, NULL, 10);
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); }
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; }
188 {WORD} { yylval.sym = symtable_get(yytext); return T_SYMBOL; }
193 snprintf(buf, sizeof(buf), "Invalid character "
195 stop(buf, EX_DATAERR);
199 typedef struct include {
200 YY_BUFFER_STATE buffer;
203 SLIST_ENTRY(include) links;
206 SLIST_HEAD(, include) include_stack;
209 include_file(file_name, type)
217 /* Try the current directory first */
218 if (includes_search_curdir != 0 || type == SOURCE_FILE)
219 newfile = fopen(file_name, "r");
221 if (newfile == NULL && type != SOURCE_FILE) {
222 path_entry_t include_dir;
223 for (include_dir = search_path.slh_first;
225 include_dir = include_dir->links.sle_next) {
226 char fullname[PATH_MAX];
228 if ((include_dir->quoted_includes_only == TRUE)
229 && (type != QUOTED_INCLUDE))
232 snprintf(fullname, sizeof(fullname),
233 "%s/%s", include_dir->directory, file_name);
235 if ((newfile = fopen(fullname, "r")) != NULL)
240 if (newfile == NULL) {
242 stop("Unable to open input file", EX_SOFTWARE);
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",
253 include->buffer = YY_CURRENT_BUFFER;
254 include->lineno = yylineno;
255 include->filename = yyfilename;
256 SLIST_INSERT_HEAD(&include_stack, include, links);
258 yy_switch_to_buffer(yy_create_buffer(newfile, YY_BUF_SIZE));
260 yyfilename = strdup(file_name);
268 yy_delete_buffer(YY_CURRENT_BUFFER);
270 if (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);