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