0001 %{
0002 /*
0003 * Sub-Lexical Analyzer for macro invokation in
0004 * the Aic7xxx SCSI Host adapter sequencer assembler.
0005 *
0006 * Copyright (c) 2001 Adaptec Inc.
0007 * All rights reserved.
0008 *
0009 * Redistribution and use in source and binary forms, with or without
0010 * modification, are permitted provided that the following conditions
0011 * are met:
0012 * 1. Redistributions of source code must retain the above copyright
0013 * notice, this list of conditions, and the following disclaimer,
0014 * without modification.
0015 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
0016 * substantially similar to the "NO WARRANTY" disclaimer below
0017 * ("Disclaimer") and any redistribution must be conditioned upon
0018 * including a substantially similar Disclaimer requirement for further
0019 * binary redistribution.
0020 * 3. Neither the names of the above-listed copyright holders nor the names
0021 * of any contributors may be used to endorse or promote products derived
0022 * from this software without specific prior written permission.
0023 *
0024 * Alternatively, this software may be distributed under the terms of the
0025 * GNU General Public License ("GPL") version 2 as published by the Free
0026 * Software Foundation.
0027 *
0028 * NO WARRANTY
0029 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0030 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0031 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
0032 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0033 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
0034 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
0035 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
0036 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
0037 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
0038 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0039 * POSSIBILITY OF SUCH DAMAGES.
0040 *
0041 * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_scan.l#8 $
0042 *
0043 * $FreeBSD$
0044 */
0045
0046 #include <sys/types.h>
0047
0048 #include <inttypes.h>
0049 #include <limits.h>
0050 #include <regex.h>
0051 #include <stdio.h>
0052 #include <string.h>
0053 #include <sysexits.h>
0054 #include "../queue.h"
0055
0056 #include "aicasm.h"
0057 #include "aicasm_symbol.h"
0058 #include "aicasm_macro_gram.h"
0059
0060 #define MAX_STR_CONST 4096
0061 static char string_buf[MAX_STR_CONST];
0062 static char *string_buf_ptr;
0063 static int parren_count;
0064 static char buf[255];
0065 int mmlineno;
0066 %}
0067
0068 WORD [A-Za-z_][-A-Za-z_0-9]*
0069 SPACE [ \t]+
0070 MCARG [^(), \t]+
0071
0072 %x ARGLIST
0073
0074 %%
0075 \n {
0076 ++mmlineno;
0077 }
0078 \r ;
0079 <ARGLIST>{SPACE} ;
0080 <ARGLIST>\( {
0081 parren_count++;
0082 if (parren_count == 1) {
0083 string_buf_ptr = string_buf;
0084 return ('(');
0085 }
0086 *string_buf_ptr++ = '(';
0087 }
0088 <ARGLIST>\) {
0089 if (parren_count == 1) {
0090 if (string_buf_ptr != string_buf) {
0091 /*
0092 * Return an argument and
0093 * rescan this parren so we
0094 * can return it as well.
0095 */
0096 *string_buf_ptr = '\0';
0097 mmlval.str = string_buf;
0098 string_buf_ptr = string_buf;
0099 unput(')');
0100 return T_ARG;
0101 }
0102 BEGIN INITIAL;
0103 return (')');
0104 }
0105 parren_count--;
0106 *string_buf_ptr++ = ')';
0107 }
0108 <ARGLIST>{MCARG} {
0109 char *yptr;
0110
0111 yptr = mmtext;
0112 while (*yptr)
0113 *string_buf_ptr++ = *yptr++;
0114 }
0115 <ARGLIST>\, {
0116 if (string_buf_ptr != string_buf) {
0117 /*
0118 * Return an argument and
0119 * rescan this comma so we
0120 * can return it as well.
0121 */
0122 *string_buf_ptr = '\0';
0123 mmlval.str = string_buf;
0124 string_buf_ptr = string_buf;
0125 unput(',');
0126 return T_ARG;
0127 }
0128 return ',';
0129 }
0130 {WORD}[(] {
0131 /* May be a symbol or a macro invocation. */
0132 mmlval.sym = symtable_get(mmtext);
0133 if (mmlval.sym->type != MACRO) {
0134 stop("Expecting Macro Name",
0135 EX_DATAERR);
0136 }
0137 unput('(');
0138 parren_count = 0;
0139 BEGIN ARGLIST;
0140 return T_SYMBOL;
0141 }
0142 . {
0143 snprintf(buf, sizeof(buf), "Invalid character "
0144 "'%c'", mmtext[0]);
0145 stop(buf, EX_DATAERR);
0146 }
0147 %%
0148
0149 int
0150 mmwrap()
0151 {
0152 stop("EOF encountered in macro call", EX_DATAERR);
0153 }