1 /* $NetBSD: gsp_lex.c,v 1.5 2001/06/13 10:46:06 wiz 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.5 2001/06/13 10:46:06 wiz Exp $"); 37 #endif 38 39 #include <stdio.h> 40 #include "gsp_ass.h" 41 #include "gsp_gram.h" 42 #include <ctype.h> 43 #include <stdlib.h> 44 #include <string.h> 45 46 char *lineptr; 47 48 char idents[MAXLINE]; 49 char *idptr; 50 51 extern YYSTYPE yylval; 52 53 int str_match(char *, char **); 54 55 char *regnames[] = { 56 "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", 57 "A8", "A9", "A10", "A11", "A12", "A13", "A14", "SP", 58 "B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", 59 "B8", "B9", "B10", "B11", "B12", "B13", "B14", "B15", 60 NULL 61 }; 62 63 short regnumbers[] = { 64 A0+0, A0+1, A0+2, A0+3, A0+4, A0+5, A0+6, A0+7, 65 A0+8, A0+9, A0+10, A0+11, A0+12, A0+13, A0+14, SP, 66 B0+0, B0+1, B0+2, B0+3, B0+4, B0+5, B0+6, B0+7, 67 B0+8, B0+9, B0+10, B0+11, B0+12, B0+13, B0+14, B0+15, 68 }; 69 70 void 71 lex_init(char *line) 72 { 73 lineptr = line; 74 idptr = idents; 75 } 76 77 int 78 yylex() 79 { 80 int c, tok, x, len; 81 char *lp, *ip; 82 char *end; 83 84 lp = lineptr; 85 c = *lp; 86 while( c == ' ' || c == '\t' ) 87 c = *++lp; 88 if( isalpha(c) || c == '_' || c == '.' ){ 89 /* an identifier or register name */ 90 ip = lp; 91 do { 92 c = *++lp; 93 } while( isalnum(c) || c == '_' ); 94 len = lp - ip; 95 if( len == 1 && *ip == '.' ) 96 tok = '.'; 97 else { 98 strncpy(idptr, ip, len); 99 idptr[len] = 0; 100 ucasify(idptr); 101 x = str_match(idptr, regnames); 102 if( x == -1 ){ 103 strncpy(idptr, ip, len); 104 yylval.y_id = idptr; 105 idptr += len + 1; 106 tok = ID; 107 } else { 108 yylval.y_int = regnumbers[x]; 109 tok = REGISTER; 110 } 111 } 112 } else if( c == '$' ){ 113 /* a hex number */ 114 ++lp; 115 yylval.y_int = strtoul(lp, &end, 16); 116 if( end == lp ) 117 perr("Bad number syntax"); 118 else 119 lp = end; 120 tok = NUMBER; 121 } else if( isdigit(c) ){ 122 yylval.y_int = strtoul(lp, &end, 0); 123 ip = lp; 124 lp = end; 125 c = *lp; 126 if( (c == 'f' || c == 'F' || c == 'b' || c == 'B') 127 && !(isalnum(lp[1]) || lp[1] == '_') ){ 128 /* reference to numeric label */ 129 c = toupper(c); 130 sprintf(idptr, "%ld%c", (long)yylval.y_int, c); 131 yylval.y_id = idptr; 132 idptr += strlen(idptr) + 1; 133 ++lp; 134 tok = ID; 135 } else 136 tok = NUMBER; 137 } else if( c == '\n' ){ 138 tok = 0; /* eof */ 139 } else if( c == ';' ){ 140 /* comment - skip to end of line */ 141 while( *++lp != 0 ) 142 ; 143 tok = 0; 144 } else if( c == '"' ){ 145 /* string */ 146 yylval.y_id = idptr; 147 while( (c = *++lp) != '"' && c != '\n' && c != 0 ) 148 *idptr++ = c; 149 *idptr++ = 0; 150 if( c != '"' ) 151 perr("Unterminated string"); 152 else 153 ++lp; 154 tok = STRING; 155 } else if( c == '<' && lp[1] == '<' ){ 156 lp += 2; 157 tok = LEFT_SHIFT; 158 } else if( c == '>' && lp[1] == '>' ){ 159 lp += 2; 160 tok = RIGHT_SHIFT; 161 } else { 162 if( c != 0 ) 163 ++lp; 164 tok = c; 165 } 166 lineptr = lp; 167 return tok; 168 } 169 170 void 171 ucasify(char *p) 172 { 173 int c; 174 175 for( ; (c = *p) != 0; p++ ) 176 if( islower(c) ) 177 *p = toupper(c); 178 } 179 180 int 181 str_match(char *id, char **names) 182 { 183 char **np; 184 185 for( np = names; *np != NULL; ++np ) 186 if( strcmp(id, *np) == 0 ) 187 return np - names; 188 return -1; 189 } 190