aicasm_scan.l (80169) | aicasm_scan.l (95376) |
---|---|
1%{ 2/* 3 * Lexical Analyzer for the Aic7xxx SCSI Host adapter sequencer assembler. 4 * | 1%{ 2/* 3 * Lexical Analyzer for the Aic7xxx SCSI Host adapter sequencer assembler. 4 * |
5 * Copyright (c) 1997, 1998 Justin T. Gibbs. | 5 * Copyright (c) 1997, 1998, 2000 Justin T. Gibbs. 6 * Copyright (c) 2001 Adaptec Inc. |
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. | 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions, and the following disclaimer, 14 * 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. | 15 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 16 * substantially similar to the "NO WARRANTY" disclaimer below 17 * ("Disclaimer") and any redistribution must be conditioned upon 18 * including a substantially similar Disclaimer requirement for further 19 * binary redistribution. 20 * 3. Neither the names of the above-listed copyright holders nor the names 21 * of any contributors may be used to endorse or promote products derived 22 * from this software without specific prior written permission. |
16 * 17 * Alternatively, this software may be distributed under the terms of the | 23 * 24 * Alternatively, this software may be distributed under the terms of the |
18 * GNU Public License ("GPL"). | 25 * GNU General Public License ("GPL") version 2 as published by the Free 26 * Software Foundation. |
19 * | 27 * |
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 | 28 * NO WARRANTY 29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 33 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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) | 34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 35 * 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. | 36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 38 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 39 * POSSIBILITY OF SUCH DAMAGES. |
31 * | 40 * |
32 * $Id: //depot/src/aic7xxx/aicasm/aicasm_scan.l#5 $ | 41 * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#10 $ |
33 * | 42 * |
34 * $FreeBSD: head/sys/dev/aic7xxx/aicasm/aicasm_scan.l 80169 2001-07-22 23:15:14Z assar $ | 43 * $FreeBSD: head/sys/dev/aic7xxx/aicasm/aicasm_scan.l 95376 2002-04-24 16:24:43Z gibbs $ |
35 */ 36 37#include <sys/types.h> 38 39#include <limits.h> | 44 */ 45 46#include <sys/types.h> 47 48#include <limits.h> |
49#include <regex.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" | 50#include <stdio.h> 51#include <string.h> 52#include <sysexits.h> 53#ifdef __linux__ 54#include "../queue.h" 55#else 56#include <sys/queue.h> 57#endif 58 59#include "aicasm.h" 60#include "aicasm_symbol.h" |
51#include "y.tab.h" | 61#include "aicasm_gram.h" |
52 | 62 |
53#define MAX_STR_CONST 256 54char string_buf[MAX_STR_CONST]; 55char *string_buf_ptr; 56int parren_count; 57int quote_count; | 63/* This is used for macro body capture too, so err on the large size. */ 64#define MAX_STR_CONST 4096 65static char string_buf[MAX_STR_CONST]; 66static char *string_buf_ptr; 67static int parren_count; 68static int quote_count; 69static char buf[255]; |
58%} 59 | 70%} 71 |
60%option nounput 61 62PATH [-/A-Za-z0-9_.]*[./][-/A-Za-z0-9_.]* | 72PATH ([/]*[-A-Za-z0-9_.])+ |
63WORD [A-Za-z_][-A-Za-z_0-9]* 64SPACE [ \t]+ | 73WORD [A-Za-z_][-A-Za-z_0-9]* 74SPACE [ \t]+ |
75MCARG [^(), \t]+ 76MBODY ((\\[^\n])*[^\n\\]*)+ |
|
65 66%x COMMENT 67%x CEXPR 68%x INCLUDE 69%x STRING | 77 78%x COMMENT 79%x CEXPR 80%x INCLUDE 81%x STRING |
82%x MACRODEF 83%x MACROARGLIST 84%x MACROCALLARGS 85%x MACROBODY |
|
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]* ; --- 32 unchanged lines hidden (view full) --- 110 && string_buf_ptr[-1] == ' ') 111 yptr++; 112 else 113 *string_buf_ptr++ = *yptr++; 114 } 115 } 116 117VERSION { return T_VERSION; } | 86 87%% 88\n { ++yylineno; } 89"/*" { BEGIN COMMENT; /* Enter comment eating state */ } 90<COMMENT>"/*" { fprintf(stderr, "Warning! Comment within comment."); } 91<COMMENT>\n { ++yylineno; } 92<COMMENT>[^*/\n]* ; 93<COMMENT>"*"+[^*/\n]* ; --- 32 unchanged lines hidden (view full) --- 126 && string_buf_ptr[-1] == ' ') 127 yptr++; 128 else 129 *string_buf_ptr++ = *yptr++; 130 } 131 } 132 133VERSION { return T_VERSION; } |
134PATCH_ARG_LIST { return T_PATCH_ARG_LIST; } |
|
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 } | 135\" { 136 string_buf_ptr = string_buf; 137 BEGIN STRING; 138 } 139<STRING>[^"]+ { 140 char *yptr; 141 142 yptr = yytext; 143 while (*yptr) 144 *string_buf_ptr++ = *yptr++; 145 } 146<STRING>\" { 147 /* All done */ 148 BEGIN INITIAL; 149 *string_buf_ptr = '\0'; 150 yylval.str = string_buf; 151 return T_STRING; 152 } |
136{SPACE} ; | 153{SPACE} ; |
137 138 /* Register/SCB/SRAM definition keywords */ | 154 155 /* Register/SCB/SRAM definition keywords */ |
156export { return T_EXPORT; } |
|
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; } | 157register { return T_REGISTER; } 158const { yylval.value = FALSE; return T_CONST; } 159download { return T_DOWNLOAD; } 160address { return T_ADDRESS; } 161access_mode { return T_ACCESS_MODE; } |
162modes { return T_MODES; } |
|
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; } | 163RW|RO|WO { 164 if (strcmp(yytext, "RW") == 0) 165 yylval.value = RW; 166 else if (strcmp(yytext, "RO") == 0) 167 yylval.value = RO; 168 else 169 yylval.value = WO; 170 return T_MODE; 171 } 172BEGIN_CRITICAL { return T_BEGIN_CS; } 173END_CRITICAL { return T_END_CS; } |
174SET_SRC_MODE { return T_SET_SRC_MODE; } 175SET_DST_MODE { return T_SET_DST_MODE; } |
|
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; } | 176bit { return T_BIT; } 177mask { return T_MASK; } 178alias { return T_ALIAS; } 179size { return T_SIZE; } 180scb { return T_SCB; } 181scratch_ram { return T_SRAM; } 182accumulator { return T_ACCUM; } |
183mode_pointer { return T_MODE_PTR; } |
|
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; } --- 24 unchanged lines hidden (view full) --- 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 */ | 184allones { return T_ALLONES; } 185allzeros { return T_ALLZEROS; } 186none { return T_NONE; } 187sindex { return T_SINDEX; } 188A { return T_A; } 189 190 /* Opcodes */ 191shl { return T_SHL; } --- 24 unchanged lines hidden (view full) --- 216test { return T_TEST;} 217and { return T_AND; } 218or { return T_OR; } 219ret { return T_RET; } 220nop { return T_NOP; } 221else { return T_ELSE; } 222 223 /* Allowed Symbols */ |
202[-+,:()~|&."{};<>[\]!=] { return yytext[0]; } | 224\<\< { return T_EXPR_LSHIFT; } 225\>\> { return T_EXPR_RSHIFT; } 226[-+,:()~|&."{};<>[\]/*!=] { 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 } | 227 228 /* Number processing */ 2290[0-7]* { 230 yylval.value = strtol(yytext, NULL, 8); 231 return T_NUMBER; 232 } 233 2340[xX][0-9a-fA-F]+ { 235 yylval.value = strtoul(yytext + 2, NULL, 16); 236 return T_NUMBER; 237 } 238 239[1-9][0-9]* { 240 yylval.value = strtol(yytext, NULL, 10); 241 return T_NUMBER; 242 } |
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 } | 243 /* Include Files */ 244#include{SPACE} { 245 BEGIN INCLUDE; 246 quote_count = 0; 247 return T_INCLUDE; 248 } 249<INCLUDE>[<] { return yytext[0]; } 250<INCLUDE>[>] { BEGIN INITIAL; return yytext[0]; } 251<INCLUDE>[\"] { 252 if (quote_count != 0) 253 BEGIN INITIAL; 254 quote_count++; 255 return yytext[0]; 256 } |
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} { | 257<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 } | 258 char *yptr; 259 260 yptr = yytext; 261 string_buf_ptr = string_buf; 262 while (*yptr) 263 *string_buf_ptr++ = *yptr++; 264 yylval.str = string_buf; 265 *string_buf_ptr = '\0'; 266 return T_PATH; 267 } |
268<INCLUDE>. { stop("Invalid include line", EX_DATAERR); } 269#define{SPACE} { 270 BEGIN MACRODEF; 271 return T_DEFINE; 272 } 273<MACRODEF>{WORD}{SPACE} { 274 char *yptr; |
|
251 | 275 |
252{WORD} { yylval.sym = symtable_get(yytext); return T_SYMBOL; } | 276 /* Strip space and return as a normal symbol */ 277 yptr = yytext; 278 while (*yptr != ' ' && *yptr != '\t') 279 yptr++; 280 *yptr = '\0'; 281 yylval.sym = symtable_get(yytext); 282 string_buf_ptr = string_buf; 283 BEGIN MACROBODY; 284 return T_SYMBOL; 285 } 286<MACRODEF>{WORD}\( { 287 /* 288 * We store the symbol with its opening 289 * parren so we can differentiate macros 290 * that take args from macros with the 291 * same name that do not take args as 292 * is allowed in C. 293 */ 294 BEGIN MACROARGLIST; 295 yylval.sym = symtable_get(yytext); 296 unput('('); 297 return T_SYMBOL; 298 } 299<MACROARGLIST>{WORD} { 300 yylval.str = yytext; 301 return T_ARG; 302 } 303<MACROARGLIST>{SPACE} ; 304<MACROARGLIST>[(,] { 305 return yytext[0]; 306 } 307<MACROARGLIST>[)] { 308 string_buf_ptr = string_buf; 309 BEGIN MACROBODY; 310 return ')'; 311 } 312<MACROARGLIST>. { 313 snprintf(buf, sizeof(buf), "Invalid character " 314 "'%c' in macro argument list", 315 yytext[0]); 316 stop(buf, EX_DATAERR); 317 } 318<MACROCALLARGS>{SPACE} ; 319<MACROCALLARGS>\( { 320 parren_count++; 321 if (parren_count == 1) 322 return ('('); 323 *string_buf_ptr++ = '('; 324 } 325<MACROCALLARGS>\) { 326 parren_count--; 327 if (parren_count == 0) { 328 BEGIN INITIAL; 329 return (')'); 330 } 331 *string_buf_ptr++ = ')'; 332 } 333<MACROCALLARGS>{MCARG} { 334 char *yptr; |
253 | 335 |
254. { 255 char buf[255]; | 336 yptr = yytext; 337 while (*yptr) 338 *string_buf_ptr++ = *yptr++; 339 } 340<MACROCALLARGS>\, { 341 if (string_buf_ptr != string_buf) { 342 /* 343 * Return an argument and 344 * rescan this comma so we 345 * can return it as well. 346 */ 347 *string_buf_ptr = '\0'; 348 yylval.str = string_buf; 349 string_buf_ptr = string_buf; 350 unput(','); 351 return T_ARG; 352 } 353 return ','; 354 } 355<MACROBODY>\\\n { 356 /* Eat escaped newlines. */ 357 ++yylineno; 358 } 359<MACROBODY>\n { 360 /* Macros end on the first unescaped newline. */ 361 BEGIN INITIAL; 362 *string_buf_ptr = '\0'; 363 yylval.str = string_buf; 364 ++yylineno; 365 return T_MACROBODY; 366 } 367<MACROBODY>{MBODY} { 368 char *yptr; |
256 | 369 |
370 yptr = yytext; 371 while (*yptr) 372 *string_buf_ptr++ = *yptr++; 373 } 374{WORD}\( { 375 char *yptr; 376 char *ycopy; 377 378 /* May be a symbol or a macro invocation. */ 379 yylval.sym = symtable_get(yytext); 380 if (yylval.sym->type == MACRO) { 381 YY_BUFFER_STATE old_state; 382 YY_BUFFER_STATE temp_state; 383 384 ycopy = strdup(yytext); 385 yptr = ycopy + yyleng; 386 while (yptr > ycopy) 387 unput(*--yptr); 388 old_state = YY_CURRENT_BUFFER; 389 temp_state = 390 yy_create_buffer(stdin, 391 YY_BUF_SIZE); 392 yy_switch_to_buffer(temp_state); 393 mm_switch_to_buffer(old_state); 394 mmparse(); 395 mm_switch_to_buffer(temp_state); 396 yy_switch_to_buffer(old_state); 397 mm_delete_buffer(temp_state); 398 expand_macro(yylval.sym); 399 } else { 400 if (yylval.sym->type == UNINITIALIZED) { 401 /* Try without the '(' */ 402 symbol_delete(yylval.sym); 403 yytext[yyleng-1] = '\0'; 404 yylval.sym = 405 symtable_get(yytext); 406 } 407 unput('('); 408 return T_SYMBOL; 409 } 410 } 411{WORD} { 412 yylval.sym = symtable_get(yytext); 413 if (yylval.sym->type == MACRO) { 414 expand_macro(yylval.sym); 415 } else { 416 return T_SYMBOL; 417 } 418 } 419. { |
|
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; --- 52 unchanged lines hidden (view full) --- 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 | 420 snprintf(buf, sizeof(buf), "Invalid character " 421 "'%c'", yytext[0]); 422 stop(buf, EX_DATAERR); 423 } 424%% 425 426typedef struct include { 427 YY_BUFFER_STATE buffer; --- 52 unchanged lines hidden (view full) --- 480 include->filename = yyfilename; 481 SLIST_INSERT_HEAD(&include_stack, include, links); 482 } 483 yy_switch_to_buffer(yy_create_buffer(newfile, YY_BUF_SIZE)); 484 yylineno = 1; 485 yyfilename = strdup(file_name); 486} 487 |
488static void next_substitution(struct symbol *mac_symbol, const char *body_pos, 489 const char **next_match, 490 struct macro_arg **match_marg, regmatch_t *match); 491 492void 493expand_macro(struct symbol *macro_symbol) 494{ 495 struct macro_arg *marg; 496 struct macro_arg *match_marg; 497 const char *body_head; 498 const char *body_pos; 499 const char *next_match; 500 501 /* 502 * Due to the nature of unput, we must work 503 * backwards through the macro body performing 504 * any expansions. 505 */ 506 body_head = macro_symbol->info.macroinfo->body; 507 body_pos = body_head + strlen(body_head); 508 while (body_pos > body_head) { 509 regmatch_t match; 510 511 next_match = body_head; 512 match_marg = NULL; 513 next_substitution(macro_symbol, body_pos, &next_match, 514 &match_marg, &match); 515 516 /* Put back everything up until the replacement. */ 517 while (body_pos > next_match) 518 unput(*--body_pos); 519 520 /* Perform the replacement. */ 521 if (match_marg != NULL) { 522 const char *strp; 523 524 next_match = match_marg->replacement_text; 525 strp = next_match + strlen(next_match); 526 while (strp > next_match) 527 unput(*--strp); 528 529 /* Skip past the unexpanded macro arg. */ 530 body_pos -= match.rm_eo - match.rm_so; 531 } 532 } 533 534 /* Cleanup replacement text. */ 535 STAILQ_FOREACH(marg, ¯o_symbol->info.macroinfo->args, links) { 536 free(marg->replacement_text); 537 } 538} 539 540/* 541 * Find the next substitution in the macro working backwards from 542 * body_pos until the beginning of the macro buffer. next_match 543 * should be initialized to the beginning of the macro buffer prior 544 * to calling this routine. 545 */ 546static void 547next_substitution(struct symbol *mac_symbol, const char *body_pos, 548 const char **next_match, struct macro_arg **match_marg, 549 regmatch_t *match) 550{ 551 regmatch_t matches[2]; 552 struct macro_arg *marg; 553 const char *search_pos; 554 int retval; 555 556 do { 557 search_pos = *next_match; 558 559 STAILQ_FOREACH(marg, &mac_symbol->info.macroinfo->args, links) { 560 561 retval = regexec(&marg->arg_regex, search_pos, 2, 562 matches, 0); 563 if (retval == 0 564 && (matches[1].rm_eo + search_pos) <= body_pos 565 && (matches[1].rm_eo + search_pos) > *next_match) { 566 *match = matches[1]; 567 *next_match = match->rm_eo + search_pos; 568 *match_marg = marg; 569 } 570 } 571 } while (search_pos != *next_match); 572} 573 |
|
325int 326yywrap() 327{ 328 include_t *include; 329 330 yy_delete_buffer(YY_CURRENT_BUFFER); 331 (void)fclose(yyin); 332 if (yyfilename != NULL) --- 13 unchanged lines hidden --- | 574int 575yywrap() 576{ 577 include_t *include; 578 579 yy_delete_buffer(YY_CURRENT_BUFFER); 580 (void)fclose(yyin); 581 if (yyfilename != NULL) --- 13 unchanged lines hidden --- |