Back to home page

OSCL-LXR

 
 

    


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 }