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