1 /* $NetBSD: llscan.c,v 1.13 2009/03/14 21:04:25 dsl Exp $ */
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 $");
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
,
43 IGNORE
, UNUSED
, OPCHAR
, UNUSED
, OPCHAR
, UNUSED
, OPCHAR
, OPCHAR
,
45 OPCHAR
, OPCHAR
, OPCHAR
, OPCHAR
, OPCHAR
, OPCHAR
, OPCHAR
, OPCHAR
,
47 DIGITS
, DIGITS
, DIGITS
, DIGITS
, DIGITS
, DIGITS
, DIGITS
, DIGITS
,
49 DIGITS
, DIGITS
, OPCHAR
, OPCHAR
, OPCHAR
, OPCHAR
, OPCHAR
, OPCHAR
,
52 UNUSED
, LETTER
, LETTER
, LETTER
, LETTER
, LETTER
, LETTER
, LETTER
,
54 LETTER
, LETTER
, LETTER
, LETTER
, LETTER
, LETTER
, LETTER
, LETTER
,
56 LETTER
, LETTER
, LETTER
, LETTER
, LETTER
, LETTER
, LETTER
, LETTER
,
58 LETTER
, LETTER
, LETTER
, OPCHAR
, UNUSED
, OPCHAR
, OPCHAR
, LETTER
,
61 UNUSED
, LETTER
, LETTER
, LETTER
, LETTER
, LETTER
, LETTER
, LETTER
,
63 LETTER
, LETTER
, LETTER
, LETTER
, LETTER
, LETTER
, LETTER
, LETTER
,
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
;
73 static char buffer
[2][LINELEN
];
74 static int currentbuf
= 1;
76 #define addbuf(x) *buffptr++ = x
81 extern void AddCurrentEventName();
86 while((chtype
[ch
] == IGNORE
) ) {
98 fprintf(stderr
,"Insert %s\n", llstrings
[t
->llterm
]);
101 fprintf(stderr
,"Delete %s\n", llstrings
[t
->llterm
]);
106 #define TVAL (t->llattrib)
113 (void) fputc(buffer
[currentbuf
][i
], stderr
);
114 (void) fputc('\n', stderr
);
115 (void) fflush(stderr
);
123 static struct { char *key_word
; int term_type
; } keys
[] = {
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
},
133 { "INCLUDE", T_INCLUDE
},
134 { "PROTOCOL", T_PROTOCOL
},
138 for (i
= 0; keys
[i
].key_word
; i
++) {
139 if( !strcmp(c
, (*buf
= keys
[i
].key_word
) ) ) {
140 return ( keys
[i
].term_type
);
149 /* c is the string delimiter
150 * allow the delimiter to be escaped
151 * the messy part: translate $ID to
153 * where ID is an event with a non-zero obj_struc
154 * need we check for the field???
158 register int nested
= 1;
159 register int allow_nesting
= (o
==c
)?-1:1;
162 fprintf(stdout
,"getstr: ch=%c, delimiters %c %c\n",
164 fprintf(stdout
,"getstr: buffptr %p, currentbuf 0x%x\n",
165 buffptr
, currentbuf
);
168 if( ch
== c
) nested
--;
172 "Eof inside of a string, delims= %c,%c, nesting %d",c
,o
, nested
);
175 } else if(ch
== '$') {
176 /* might be an attribute */
178 fprintf(stdout
,"getstr: atttribute?\n");
181 /* assume it's an event */
182 /* addbuf is a macro so this isn't as bad as
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');
192 AddCurrentEventName(& buffptr
);
194 char *obufp
= buffptr
;
199 } while(chtype
[ch
] & LETTER
);
201 if( !strncmp(obufp
, synonyms
[PCB_SYN
],
202 strlen(synonyms
[PCB_SYN
]) )) {
205 } else if( !strncmp(obufp
, synonyms
[EVENT_SYN
],
206 strlen(synonyms
[EVENT_SYN
]))) {
210 fprintf(stderr
, "Unknown synonym %s\n", obufp
);
214 addbuf('-'); addbuf('>');
216 /* needs to be checked for nesting */
220 /* end of attribute handling */
222 } else if(ch
== '\\') {
223 /* possible escape - this is kludgy beyond belief:
224 * \ is used to escape open and closing delimiters
226 * otherwise it's passed through to be compiled by C
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
241 if( ch
== o
) nested
+= allow_nesting
;
242 else if( ch
== c
) nested
--;
243 if ( (buffptr
- buffer
[currentbuf
]) > LINELEN
) {
245 "%s too long.\n", (o
=='{')?"Action":"Predicate"); /*}*/
247 "buffptr, currentbuf %p, 0x%x\n",buffptr
,currentbuf
);
251 fprintf(stdout
,"loop in getstr: ch 0x%x,%c o=%c,c=%c nested=%d\n",
259 fprintf(stdout
,"exit getstr: got %s\n", buffer
[currentbuf
]);
260 fprintf(stdout
,"exit getstr: buffptr %p, currentbuf 0x%x\n",
261 buffptr
, currentbuf
);
273 if (c
== '\n') lineno
++;
275 if (c
& ~0x7f) c
= 0;
276 if (feof(infile
)) c
= 0;
278 fprintf(stdout
, "getch: 0x%x\n", c
);
279 (void) fputc(c
, stdout
);
296 buffptr
= &buffer
[currentbuf
][0];
303 t
->llterm
= T_ENDMARKER
;
307 fprintf(stderr
, "Illegal character in input - 0x%x ignored.", ch
);
316 /* possible comment : elide ; kludge */
318 fprintf(stdout
, "Comment ch=%c\n", ch
);
322 fprintf(stderr
,"Syntax error : character(0x%x) ignored", ch
);
326 register int state
= 2, whatchar
=0;
327 static int dfa
[3][3] = {
328 /* done seen-star middle */
329 /* star */ { 0, 1, 1 },
331 /* other */ { 0, 2, 2 }
335 if( (c
= getch()) == (char)0)
337 whatchar
= (c
=='*')?0:(c
=='/'?1:2);
340 "comment: whatchar = %d, c = 0x%x,%c, oldstate=%d",
341 whatchar
, c
,c
, state
);
343 state
= dfa
[whatchar
][state
];
345 fprintf(stdout
, ", newstate=%d\n", state
);
350 "Syntax error: end of file inside a comment");
355 fprintf(stdout
, "end of comment at 0x%x,%c\n",ch
,ch
);
373 t
->llterm
= T_LANGLE
;
381 t
->llterm
= T_LBRACK
;
385 t
->llterm
= T_RBRACK
;
390 t
->llterm
= T_FSTRING
;
394 TVAL
.FSTRING
.address
= stash(buffer
[currentbuf
]);
396 #endif /* T_FSTRING */
399 t
->llterm
= T_PREDICATE
;
401 TVAL
.PREDICATE
.address
= buffer
[currentbuf
];
405 t
->llterm
= T_ACTION
;
407 TVAL
.ACTION
.address
= buffer
[currentbuf
];
411 fprintf(stderr
,"Syntax error : character(0x%x) ignored", ch
);
423 } while(chtype
[ch
] & (LETTER
| DIGITS
));
427 t
->llterm
= iskey(buffer
[currentbuf
], &TVAL
.ID
.address
);
430 TVAL
.ID
.address
= buffer
[currentbuf
];
433 fprintf(stdout
, "llscan: id or keyword %p, %s\n",
434 TVAL
.ID
.address
, TVAL
.ID
.address
);
439 fprintf(stderr
, "Snark in llscan: chtype=0x%x, ch=0x%x\n",