1 /*
2  * Copyright (c) 2003
3  *      David Leonard.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of David Leonard nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 /*
32  * Token tables for the lexical analyser.
33  *
34  * The textual form of keywords and punctuators are
35  * kept here.  See lex.c for how the tables are used.
36  */
37 
38 #if HAVE_CONFIG_H
39 # include <config.h>
40 #endif
41 
42 #if STDC_HEADERS
43 # include <stdio.h>
44 #endif
45 
46 #if HAVE_STRING_H
47 # include <string.h>
48 #endif
49 
50 #include <see/type.h>
51 #include <see/value.h>
52 #include <see/string.h>
53 
54 #include "stringdefs.h"
55 #include "lex.h"
56 #include "tokens.h"
57 
58 #define lengthof(a) (sizeof a / sizeof a[0])
59 
60 struct strtoken SEE_tok_keywords[] = {
61 	{ STRi(synchronized), tRESERVED },
62 	{ STRi(eleven_filler), tRESERVED },	/* hack */
63 	{ STRi(implements), tRESERVED },
64 	{ STRi(instanceof), tINSTANCEOF },
65 	{ STRi(transient), tRESERVED },
66 	{ STRi(protected), tRESERVED },
67 	{ STRi(interface), tRESERVED },
68 	{ STRi(volatile), tRESERVED },
69 	{ STRi(debugger), tRESERVED },
70 	{ STRi(function), tFUNCTION },
71 	{ STRi(continue), tCONTINUE },
72 	{ STRi(abstract), tRESERVED },
73 	{ STRi(private), tRESERVED },
74 	{ STRi(package), tRESERVED },
75 	{ STRi(extends), tRESERVED },
76 	{ STRi(boolean), tRESERVED },
77 	{ STRi(finally), tFINALLY },
78 	{ STRi(default), tDEFAULT },
79 	{ STRi(native), tRESERVED },
80 	{ STRi(export), tRESERVED },
81 	{ STRi(typeof), tTYPEOF },
82 	{ STRi(switch), tSWITCH },
83 	{ STRi(return), tRETURN },
84 	{ STRi(throws), tRESERVED },
85 	{ STRi(import), tRESERVED },
86 	{ STRi(static), tRESERVED },
87 	{ STRi(delete), tDELETE },
88 	{ STRi(public), tRESERVED },
89 	{ STRi(double), tRESERVED },
90 	{ STRi(float), tRESERVED },
91 	{ STRi(super), tRESERVED },
92 	{ STRi(short), tRESERVED },
93 	{ STRi(const), tRESERVED },
94 	{ STRi(class), tRESERVED },
95 	{ STRi(while), tWHILE },
96 	{ STRi(final), tRESERVED },
97 	{ STRi(throw), tTHROW },
98 	{ STRi(catch), tCATCH },
99 	{ STRi(break), tBREAK },
100 	{ STRi(false), tFALSE },
101 	{ STRi(with), tWITH },
102 	{ STRi(long), tRESERVED },
103 	{ STRi(null), tNULL },
104 	{ STRi(true), tTRUE },
105 	{ STRi(void), tVOID },
106 	{ STRi(else), tELSE },
107 	{ STRi(goto), tRESERVED },
108 	{ STRi(enum), tRESERVED },
109 	{ STRi(this), tTHIS },
110 	{ STRi(byte), tRESERVED },
111 	{ STRi(case), tCASE },
112 	{ STRi(char), tRESERVED },
113 	{ STRi(new), tNEW },
114 	{ STRi(try), tTRY },
115 	{ STRi(int), tRESERVED },
116 	{ STRi(for), tFOR },
117 	{ STRi(var), tVAR },
118 	{ STRi(in), tIN },
119 	{ STRi(do), tDO },
120 	{ STRi(if), tIF },
121 };
122 int SEE_tok_nkeywords = lengthof(SEE_tok_keywords);
123 
124 static struct token operators1[] = {
125 	{ {'?'}, '?' },
126 	{ {'{'}, '{' },
127 	{ {'}'}, '}' },
128 	{ {'('}, '(' },
129 	{ {')'}, ')' },
130 	{ {'['}, '[' },
131 	{ {']'}, ']' },
132 	{ {'.'}, '.' },
133 	{ {';'}, ';' },
134 	{ {','}, ',' },
135 	{ {'<'}, '<' },
136 	{ {'>'}, '>' },
137 	{ {':'}, ':' },
138 	{ {'='}, '=' },
139 	{ {'|'}, '|' },
140 	{ {'^'}, '^' },
141 	{ {'!'}, '!' },
142 	{ {'~'}, '~' },
143 	{ {'*'}, '*' },
144 	{ {'-'}, '-' },
145 	{ {'+'}, '+' },
146 	{ {'%'}, '%' },
147 	{ {'&'}, '&' },
148 	{ {0}, 0 }
149 }, operators2[] = {
150 	{ {'-','-'}, tMINUSMINUS },
151 	{ {'<','<'}, tLSHIFT },
152 	{ {'>','>'}, tRSHIFT },
153 	{ {'&','&'}, tANDAND },
154 	{ {'|','|'}, tOROR },
155 	{ {'+','='}, tPLUSEQ },
156 	{ {'-','='}, tMINUSEQ },
157 	{ {'*','='}, tSTAREQ },
158 	{ {'%','='}, tMODEQ },
159 	{ {'&','='}, tANDEQ },
160 	{ {'|','='}, tOREQ },
161 	{ {'^','='}, tXOREQ },
162 	{ {'<','='}, tLE },
163 	{ {'>','='}, tGE },
164 	{ {'=','='}, tEQ },
165 	{ {'!','='}, tNE },
166 	{ {'+','+'}, tPLUSPLUS },
167 	{ {0}, 0 }
168 }, operators3[] = {
169 	{ {'>','>','='}, tRSHIFTEQ },
170 	{ {'<','<','='}, tLSHIFTEQ },
171 	{ {'>','>','>'}, tURSHIFT },
172 	{ {'=','=','='}, tSEQ },
173 	{ {'!','=','='}, tSNE },
174 	{ {'-','-','>'}, tSGMLCOMMENTEND },
175 	{ {0}, 0 }
176 }, operators4[] = {
177 	{ {'<','!','-','-'}, tSGMLCOMMENT },
178 	{ {'>','>','>','='}, tURSHIFTEQ },
179 	{ {0}, 0 }
180 };
181 
182 struct token *SEE_tok_operators[] = {
183 	NULL, operators1, operators2, operators3, operators4
184 };
185 int SEE_tok_noperators = lengthof(SEE_tok_operators);
186 
187 
188 static struct {
189 	const char *name;
190 	int token;
191 } tok_names[] = {
192 	{ "end of file",	tEND },
193 	{ "a comment",		tCOMMENT },
194 	{ "a line break",	tLINETERMINATOR },
195 	{ "'/='",		tDIVEQ },
196 	{ "'/'",		tDIV },
197 	{ "a number",		tNUMBER },
198 	{ "a string",		tSTRING },
199 	{ "an identifier",	tIDENT },
200 	{ "a regular expression",tREGEX },
201 	{ "a reserved word",	tRESERVED },
202 	{ "'instanceof'",	tINSTANCEOF },
203 	{ "'function'",		tFUNCTION },
204 	{ "'continue'",		tCONTINUE },
205 	{ "'finally'",		tFINALLY },
206 	{ "'default'",		tDEFAULT },
207 	{ "'typeof'",		tTYPEOF },
208 	{ "'switch'",		tSWITCH },
209 	{ "'return'",		tRETURN },
210 	{ "'delete'",		tDELETE },
211 	{ "'while'",		tWHILE },
212 	{ "'throw'",		tTHROW },
213 	{ "'catch'",		tCATCH },
214 	{ "'break'",		tBREAK },
215 	{ "'with'",		tWITH },
216 	{ "'void'",		tVOID },
217 	{ "'else'",		tELSE },
218 	{ "'this'",		tTHIS },
219 	{ "'case'",		tCASE },
220 	{ "'new'",		tNEW },
221 	{ "'try'",		tTRY },
222 	{ "'for'",		tFOR },
223 	{ "'var'",		tVAR },
224 	{ "'in'",		tIN },
225 	{ "'do'",		tDO },
226 	{ "'if'",		tIF },
227 	{ "'>>>='",		tURSHIFTEQ },
228 	{ "'<!--'",		tSGMLCOMMENT },
229 	{ "'-->'",		tSGMLCOMMENTEND },
230 	{ "'>>='",		tRSHIFTEQ },
231 	{ "'<<='",		tLSHIFTEQ },
232 	{ "'>>>'",		tURSHIFT },
233 	{ "'==='",		tSEQ },
234 	{ "'!=='",		tSNE },
235 	{ "'--'",		tMINUSMINUS },
236 	{ "'<<'",		tLSHIFT },
237 	{ "'>>'",		tRSHIFT },
238 	{ "'&&'",		tANDAND },
239 	{ "'||'",		tOROR },
240 	{ "'+='",		tPLUSEQ },
241 	{ "'-='",		tMINUSEQ },
242 	{ "'*='",		tSTAREQ },
243 	{ "'%='",		tMODEQ },
244 	{ "'&='",		tANDEQ },
245 	{ "'|='",		tOREQ },
246 	{ "'^='",		tXOREQ },
247 	{ "'<='",		tLE },
248 	{ "'>='",		tGE },
249 	{ "'=='",		tEQ },
250 	{ "'!='",		tNE },
251 	{ "'++'",		tPLUSPLUS },
252 	{ "'true'",		tTRUE },
253 	{ "'false'",		tFALSE },
254 	{ "'null'",		tNULL }
255 };
256 
257 const char *
SEE_tokenname(token)258 SEE_tokenname(token)
259 	int token;
260 {
261 	static char buf[30];
262 
263 	SEE_tokenname_buf(token, buf, sizeof buf);
264 	return buf;
265 }
266 
267 void
SEE_tokenname_buf(token,buf,buflen)268 SEE_tokenname_buf(token, buf, buflen)
269 	int token;
270 	char *buf;
271 	int buflen;
272 {
273 	int i;
274 	char tokch[4];
275 	const char *name;
276         int namelen;
277 
278 	for (i = 0; i < lengthof(tok_names); i++)
279 		if (tok_names[i].token == token) {
280 		    name = tok_names[i].name;
281 		    break;
282 		}
283 	else if (token >= ' ' && token <= '~') {
284 		tokch[0] = '\'';
285 		tokch[1] = (unsigned char)token;
286 		tokch[2] = '\'';
287 		tokch[3] = 0;
288 		name = tokch;
289 	} else
290 		name = "<bad token>";
291 	namelen = strlen(name);
292 	if (namelen > buflen - 1)
293 		namelen = buflen - 1;
294         memcpy(buf, name, namelen);
295 	buf[namelen] = 0;
296         return;
297 }
298