1/* $NetBSD: gsp_lex.c,v 1.8 2006/08/26 18:15:37 christos Exp $ */ 2/* 3 * Lexical analyser for GSP assembler 4 * 5 * Copyright (c) 1993 Paul Mackerras. 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 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by Paul Mackerras. 19 * 4. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34#include <sys/cdefs.h> 35#ifndef lint 36__RCSID("$NetBSD: gsp_lex.c,v 1.8 2006/08/26 18:15:37 christos Exp $"); 37#endif 38 39#include <stdio.h> 40#include <ctype.h> 41#include <stdlib.h> 42#include <string.h> 43 44#include "gsp_ass.h" 45#include "gsp_gram.h" 46 47char *lineptr; 48 49char idents[MAXLINE]; 50char *idptr; 51 52extern YYSTYPE yylval; 53 54int str_match(const char *, const char **); 55 56const char *regnames[] = { 57 "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", 58 "A8", "A9", "A10", "A11", "A12", "A13", "A14", "SP", 59 "B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", 60 "B8", "B9", "B10", "B11", "B12", "B13", "B14", "B15", 61 NULL 62}; 63 64short regnumbers[] = { 65 GSPA_A0+0, GSPA_A0+1, GSPA_A0+2, GSPA_A0+3, 66 GSPA_A0+4, GSPA_A0+5, GSPA_A0+6, GSPA_A0+7, 67 GSPA_A0+8, GSPA_A0+9, GSPA_A0+10, GSPA_A0+11, 68 GSPA_A0+12, GSPA_A0+13, GSPA_A0+14, GSPA_SP, 69 GSPA_B0+0, GSPA_B0+1, GSPA_B0+2, GSPA_B0+3, 70 GSPA_B0+4, GSPA_B0+5, GSPA_B0+6, GSPA_B0+7, 71 GSPA_B0+8, GSPA_B0+9, GSPA_B0+10, GSPA_B0+11, 72 GSPA_B0+12, GSPA_B0+13, GSPA_B0+14, GSPA_B0+15, 73}; 74 75void 76lex_init(char *lline) 77{ 78 lineptr = lline; 79 idptr = idents; 80} 81 82int 83yylex() 84{ 85 int c, tok, x, len; 86 char *lp, *ip; 87 char *end; 88 89 lp = lineptr; 90 c = *lp; 91 while( c == ' ' || c == '\t' ) 92 c = *++lp; 93 if( isalpha(c) || c == '_' || c == '.' ){ 94 /* an identifier or register name */ 95 ip = lp; 96 do { 97 c = *++lp; 98 } while( isalnum(c) || c == '_' ); 99 len = lp - ip; 100 if( len == 1 && *ip == '.' ) 101 tok = '.'; 102 else { 103 strncpy(idptr, ip, len); 104 idptr[len] = 0; 105 ucasify(idptr); 106 x = str_match(idptr, regnames); 107 if( x == -1 ){ 108 strncpy(idptr, ip, len); 109 yylval.y_id = idptr; 110 idptr += len + 1; 111 tok = ID; 112 } else { 113 yylval.y_int = regnumbers[x]; 114 tok = REGISTER; 115 } 116 } 117 } else if( c == '$' ){ 118 /* a hex number */ 119 ++lp; 120 yylval.y_int = strtoul(lp, &end, 16); 121 if( end == lp ) 122 perr("Bad number syntax"); 123 else 124 lp = end; 125 tok = NUMBER; 126 } else if( isdigit(c) ){ 127 yylval.y_int = strtoul(lp, &end, 0); 128 ip = lp; 129 lp = end; 130 c = *lp; 131 if( (c == 'f' || c == 'F' || c == 'b' || c == 'B') 132 && !(isalnum((unsigned char)lp[1]) || lp[1] == '_') ){ 133 /* reference to numeric label */ 134 c = toupper(c); 135 sprintf(idptr, "%ld%c", (long)yylval.y_int, c); 136 yylval.y_id = idptr; 137 idptr += strlen(idptr) + 1; 138 ++lp; 139 tok = ID; 140 } else 141 tok = NUMBER; 142 } else if( c == '\n' ){ 143 tok = 0; /* eof */ 144 } else if( c == ';' ){ 145 /* comment - skip to end of line */ 146 while( *++lp != 0 ) 147 ; 148 tok = 0; 149 } else if( c == '"' ){ 150 /* string */ 151 yylval.y_id = idptr; 152 while( (c = *++lp) != '"' && c != '\n' && c != 0 ) 153 *idptr++ = c; 154 *idptr++ = 0; 155 if( c != '"' ) 156 perr("Unterminated string"); 157 else 158 ++lp; 159 tok = STRING; 160 } else if( c == '<' && lp[1] == '<' ){ 161 lp += 2; 162 tok = LEFT_SHIFT; 163 } else if( c == '>' && lp[1] == '>' ){ 164 lp += 2; 165 tok = RIGHT_SHIFT; 166 } else { 167 if( c != 0 ) 168 ++lp; 169 tok = c; 170 } 171 lineptr = lp; 172 return tok; 173} 174 175void 176ucasify(char *p) 177{ 178 int c; 179 180 for( ; (c = *p) != 0; p++ ) 181 if( islower(c) ) 182 *p = toupper(c); 183} 184 185int 186str_match(const char *id, const char **names) 187{ 188 const char **np; 189 190 for( np = names; *np != NULL; ++np ) 191 if( strcmp(id, *np) == 0 ) 192 return np - names; 193 return -1; 194} 195