Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / netiso / xebec / llscan.c
blob449f60e63e84e13fdb3f8a0697d25b5c6ee44bcc
1 /* $NetBSD: llscan.c,v 1.13 2009/03/14 21:04:25 dsl Exp $ */
3 /*
4 * ************************* NOTICE *******************************
5 * This code is in the public domain. It cannot be copyrighted.
6 * This scanner was originally written by Keith Thompson for the
7 * University of Wisconsin Crystal project.
8 * It was subsequently modified significantly by Nancy Hall at the
9 * University of Wisconsin for the ARGO project.
10 * ****************************************************************
13 #include <sys/cdefs.h>
14 __KERNEL_RCSID(0, "$NetBSD: llscan.c,v 1.13 2009/03/14 21:04:25 dsl Exp $");
16 #include "xebec.h"
17 #include "llparse.h"
19 #include "main.h"
20 #include <stdio.h>
21 #include "procs.h"
22 #include "debug.h"
23 #include <string.h>
25 #define EOFILE 0x01
26 #define UNUSED 0x02
27 #define IGNORE 0x04
28 #define OPCHAR 0x8
29 #define DIGITS 0x10
30 #define LETTER 0x20
32 int chtype[128] = {
33 /* null, soh ^a, stx ^b etx ^c eot ^d enq ^e ack ^f bel ^g */
34 EOFILE, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED,
35 /* bs ^h ht ^i lf ^j vt ^k ff ^l cr ^m so ^n si ^o */
36 UNUSED, IGNORE, IGNORE, UNUSED, IGNORE, IGNORE, UNUSED, UNUSED,
37 /* dle ^p dc1 ^q dc2 ^r dc3 ^s dc4 ^t nak ^u syn ^v etb ^w */
38 UNUSED, UNUSED, UNUSED, UNUSED, EOFILE, UNUSED, UNUSED, UNUSED,
39 /* can ^x em ^y sub ^z esc ^] fs ^\ gs ^} rs ^` us ^/ */
40 UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED,
42 /* ! " # $ % & ' */
43 IGNORE, UNUSED, OPCHAR, UNUSED, OPCHAR, UNUSED, OPCHAR, OPCHAR,
44 /* ( ) * + , - . / */
45 OPCHAR, OPCHAR, OPCHAR, OPCHAR, OPCHAR, OPCHAR, OPCHAR, OPCHAR,
46 /* 0 1 2 3 4 5 6 7 */
47 DIGITS, DIGITS, DIGITS, DIGITS, DIGITS, DIGITS, DIGITS, DIGITS,
48 /* 8 9 : ; < = > ? */
49 DIGITS, DIGITS, OPCHAR, OPCHAR, OPCHAR, OPCHAR, OPCHAR, OPCHAR,
51 /* @ A B C D E F G */
52 UNUSED, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
53 /* H I J K L M N O */
54 LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
55 /* P Q R S T U V W */
56 LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
57 /* X Y Z [ \ ] ^ _ */
58 LETTER, LETTER, LETTER, OPCHAR, UNUSED, OPCHAR, OPCHAR, LETTER,
60 /* ` a b c d e f g */
61 UNUSED, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
62 /* h i j k l m n o */
63 LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
64 /* p q r s t u v w */
65 LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
66 /* x y z { | } ~ del */
67 LETTER, LETTER, LETTER, OPCHAR, UNUSED, OPCHAR, UNUSED, UNUSED
71 extern FILE *astringfile;
72 static char *buffptr;
73 static char buffer[2][LINELEN];
74 static int currentbuf = 1;
76 #define addbuf(x) *buffptr++ = x
78 static int ch = ' ';
80 int getch();
81 extern void AddCurrentEventName();
83 void
84 skip(void)
86 while((chtype[ch] == IGNORE) ) {
87 ch = getch();
91 void
92 llaccept(LLtoken *t)
94 switch(t->llstate) {
95 case NORMAL:
96 break;
97 case INSERT:
98 fprintf(stderr,"Insert %s\n", llstrings[t->llterm]);
99 break;
100 case DELETE:
101 fprintf(stderr,"Delete %s\n", llstrings[t->llterm]);
102 break;
106 #define TVAL (t->llattrib)
108 void
109 dump_buffer(void)
111 register int i;
112 for(i=0; i<20; i++)
113 (void) fputc(buffer[currentbuf][i], stderr);
114 (void) fputc('\n', stderr);
115 (void) fflush(stderr);
118 int iskey(c, buf)
119 char *c;
120 char **buf;
122 register int i;
123 static struct { char *key_word; int term_type; } keys[] = {
124 { "SAME", T_SAME },
125 { "DEFAULT", T_DEFAULT },
126 { "NULLACTION", T_NULLACTION },
127 { "STRUCT", T_STRUCT },
128 { "SYNONYM", T_SYNONYM },
129 { "TRANSITIONS", T_TRANSITIONS },
130 { "STATES", T_STATES },
131 { "EVENTS", T_EVENTS },
132 { "PCB", T_PCB },
133 { "INCLUDE", T_INCLUDE },
134 { "PROTOCOL", T_PROTOCOL },
135 { 0, 0},
138 for (i = 0; keys[i].key_word ; i++) {
139 if( !strcmp(c, (*buf = keys[i].key_word) ) ) {
140 return ( keys[i].term_type );
143 *buf = (char *)0;
144 return(0);
147 void
148 getstr(o,c)
149 /* c is the string delimiter
150 * allow the delimiter to be escaped
151 * the messy part: translate $ID to
152 * e->ev_union.ID
153 * where ID is an event with a non-zero obj_struc
154 * need we check for the field???
156 char o,c;
158 register int nested = 1;
159 register int allow_nesting = (o==c)?-1:1;
161 IFDEBUG(S)
162 fprintf(stdout,"getstr: ch=%c, delimiters %c %c\n",
163 ch,o, c);
164 fprintf(stdout,"getstr: buffptr %p, currentbuf 0x%x\n",
165 buffptr, currentbuf);
166 ENDDEBUG
168 if( ch == c ) nested--;
169 while(nested) {
170 if(ch == '\0') {
171 fprintf(stderr,
172 "Eof inside of a string, delims= %c,%c, nesting %d",c,o, nested);
173 Exit(-1);
174 /* notreached */
175 } else if(ch == '$') {
176 /* might be an attribute */
177 IFDEBUG(S)
178 fprintf(stdout,"getstr: atttribute?\n");
179 ENDDEBUG
181 /* assume it's an event */
182 /* addbuf is a macro so this isn't as bad as
183 * it looks
184 * add "e->ev_union."
186 if( (ch = getch()) == '$' ) {
187 addbuf('e'); addbuf('-'); addbuf('>');
188 addbuf('e'); addbuf('v'); addbuf('_');
189 addbuf('u'); addbuf('n'); addbuf('i');
190 addbuf('o'); addbuf('n');
191 addbuf('.');
192 AddCurrentEventName(& buffptr);
193 } else {
194 char *obufp = buffptr;
196 do {
197 addbuf(ch);
198 ch = getch();
199 } while(chtype[ch] & LETTER);
200 addbuf('\0');
201 if( !strncmp(obufp, synonyms[PCB_SYN],
202 strlen(synonyms[PCB_SYN]) )) {
203 buffptr = obufp;
204 addbuf('p');
205 } else if( !strncmp(obufp, synonyms[EVENT_SYN],
206 strlen(synonyms[EVENT_SYN]))) {
207 buffptr = obufp;
208 addbuf('e');
209 } else {
210 fprintf(stderr, "Unknown synonym %s\n", obufp);
211 Exit(-1);
213 if(ch == '.') {
214 addbuf('-'); addbuf('>');
215 } else {
216 /* needs to be checked for nesting */
217 goto check;
220 /* end of attribute handling */
221 goto skip;
222 } else if(ch == '\\') {
223 /* possible escape - this is kludgy beyond belief:
224 * \ is used to escape open and closing delimiters
225 * and '$'
226 * otherwise it's passed through to be compiled by C
228 ch = getch();
229 if( (ch != o ) && (ch != c) && (ch != '$') ) {
230 /* may need to handle case where \ is last char in file... */
231 /* don't treat is as escape; not open or close so
232 * don't have to worry about nesting either
234 addbuf('\\');
237 addbuf(ch);
238 skip:
239 ch = getch();
240 check:
241 if( ch == o ) nested += allow_nesting;
242 else if( ch == c ) nested--;
243 if ( (buffptr - buffer[currentbuf]) > LINELEN) {
244 fprintf(stderr,
245 "%s too long.\n", (o=='{')?"Action":"Predicate"); /*}*/
246 fprintf(stderr,
247 "buffptr, currentbuf %p, 0x%x\n",buffptr,currentbuf );
248 Exit(-1);
250 IFDEBUG(S)
251 fprintf(stdout,"loop in getstr: ch 0x%x,%c o=%c,c=%c nested=%d\n",
252 ch,ch,o,c,nested);
253 ENDDEBUG
255 addbuf(ch);
256 addbuf('\0');
258 IFDEBUG(S)
259 fprintf(stdout,"exit getstr: got %s\n", buffer[currentbuf]);
260 fprintf(stdout,"exit getstr: buffptr %p, currentbuf 0x%x\n",
261 buffptr, currentbuf);
262 ENDDEBUG
266 getch(void)
268 int c;
269 extern FILE *infile;
270 extern int lineno;
272 c = fgetc(infile);
273 if (c == '\n') lineno++;
274 if (c == EOF) c = 0;
275 if (c & ~0x7f) c = 0;
276 if (feof(infile)) c = 0;
277 IFDEBUG(e)
278 fprintf(stdout, "getch: 0x%x\n", c);
279 (void) fputc(c, stdout);
280 fflush(stdout);
281 ENDDEBUG
283 return c;
286 void
287 llscan(LLtoken *t)
289 char c;
291 t->llstate = NORMAL;
293 ++currentbuf;
294 currentbuf&=1;
295 again:
296 buffptr = &buffer[currentbuf][0];
298 skip();
300 switch(chtype[ch]) {
302 case EOFILE:
303 t->llterm = T_ENDMARKER;
304 break;
306 case UNUSED:
307 fprintf(stderr, "Illegal character in input - 0x%x ignored.", ch);
308 ch = getch();
309 goto again;
311 case OPCHAR:
313 switch(ch) {
315 case '/':
316 /* possible comment : elide ; kludge */
317 IFDEBUG(S)
318 fprintf(stdout, "Comment ch=%c\n", ch);
319 ENDDEBUG
320 c = getch();
321 if (c != '*') {
322 fprintf(stderr,"Syntax error : character(0x%x) ignored", ch);
323 ch = c;
324 goto again;
325 } else {
326 register int state = 2, whatchar=0;
327 static int dfa[3][3] = {
328 /* done seen-star middle */
329 /* star */ { 0, 1, 1 },
330 /* / */ { 0, 0, 2 },
331 /* other */ { 0, 2, 2 }
334 while( state ) {
335 if( (c = getch()) == (char)0)
336 break;
337 whatchar = (c=='*')?0:(c=='/'?1:2);
338 IFDEBUG(S)
339 fprintf(stdout,
340 "comment: whatchar = %d, c = 0x%x,%c, oldstate=%d",
341 whatchar, c,c, state);
342 ENDDEBUG
343 state = dfa[whatchar][state];
344 IFDEBUG(S)
345 fprintf(stdout, ", newstate=%d\n", state);
346 ENDDEBUG
348 if(state) {
349 fprintf(stderr,
350 "Syntax error: end of file inside a comment");
351 Exit(-1);
352 } else ch = getch();
354 IFDEBUG(S)
355 fprintf(stdout, "end of comment at 0x%x,%c\n",ch,ch);
356 ENDDEBUG
357 goto again;
360 case '*':
361 t->llterm = T_STAR;
362 break;
364 case ',':
365 t->llterm = T_COMMA;
366 break;
368 case ';':
369 t->llterm = T_SEMI;
370 break;
372 case '<':
373 t->llterm = T_LANGLE;
374 break;
376 case '=':
377 t->llterm = T_EQUAL;
378 break;
380 case '[':
381 t->llterm = T_LBRACK;
382 break;
384 case ']':
385 t->llterm = T_RBRACK;
386 break;
388 #ifdef T_FSTRING
389 case '"':
390 t->llterm = T_FSTRING;
391 addbuf(ch);
392 ch = getch();
393 getstr('"', '"');
394 TVAL.FSTRING.address = stash(buffer[currentbuf]);
395 break;
396 #endif /* T_FSTRING */
398 case '(':
399 t->llterm = T_PREDICATE;
400 getstr(ch, ')' );
401 TVAL.PREDICATE.address = buffer[currentbuf];
402 break;
404 case '{':
405 t->llterm = T_ACTION;
406 getstr(ch, '}');
407 TVAL.ACTION.address = buffer[currentbuf];
408 break;
410 default:
411 fprintf(stderr,"Syntax error : character(0x%x) ignored", ch);
412 ch = getch();
413 goto again;
416 ch = getch();
417 break;
419 case LETTER:
420 do {
421 addbuf(ch);
422 ch = getch();
423 } while(chtype[ch] & (LETTER | DIGITS));
425 addbuf('\0');
427 t->llterm = iskey(buffer[currentbuf], &TVAL.ID.address);
428 if(!t->llterm) {
429 t->llterm = T_ID;
430 TVAL.ID.address = buffer[currentbuf];
432 IFDEBUG(S)
433 fprintf(stdout, "llscan: id or keyword %p, %s\n",
434 TVAL.ID.address, TVAL.ID.address);
435 ENDDEBUG
436 break;
438 default:
439 fprintf(stderr, "Snark in llscan: chtype=0x%x, ch=0x%x\n",
440 chtype[ch], ch);