diff options
Diffstat (limited to 'sys/netiso/xebec/llscan.c')
-rw-r--r-- | sys/netiso/xebec/llscan.c | 430 |
1 files changed, 430 insertions, 0 deletions
diff --git a/sys/netiso/xebec/llscan.c b/sys/netiso/xebec/llscan.c new file mode 100644 index 0000000..ffdb9a9 --- /dev/null +++ b/sys/netiso/xebec/llscan.c @@ -0,0 +1,430 @@ +/* $Header: llscan.c,v 2.2 88/09/19 12:55:06 nhall Exp $ */ +/* $Source: /var/home/tadl/src/argo/xebec/RCS/llscan.c,v $ */ +/* + * ************************* NOTICE ******************************* + * This code is in the public domain. It cannot be copyrighted. + * This scanner was originally written by Keith Thompson for the + * University of Wisconsin Crystal project. + * It was subsequently modified significantly by Nancy Hall at the + * University of Wisconsin for the ARGO project. + * **************************************************************** + */ +#include "xebec.h" +#include "llparse.h" + +#include "main.h" +#include <stdio.h> +#include "procs.h" +#include "debug.h" + +#define EOFILE 0x01 +#define UNUSED 0x02 +#define IGNORE 0x04 +#define OPCHAR 0x8 +#define DIGITS 0x10 +#define LETTER 0x20 + +int chtype[128] = { +/* null, soh ^a, stx ^b etx ^c eot ^d enq ^e ack ^f bel ^g */ + EOFILE, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, +/* bs ^h ht ^i lf ^j vt ^k ff ^l cr ^m so ^n si ^o */ + UNUSED, IGNORE, IGNORE, UNUSED, IGNORE, IGNORE, UNUSED, UNUSED, +/* dle ^p dc1 ^q dc2 ^r dc3 ^s dc4 ^t nak ^u syn ^v etb ^w */ + UNUSED, UNUSED, UNUSED, UNUSED, EOFILE, UNUSED, UNUSED, UNUSED, +/* can ^x em ^y sub ^z esc ^] fs ^\ gs ^} rs ^` us ^/ */ + UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, UNUSED, + +/* ! " # $ % & ' */ + IGNORE, UNUSED, OPCHAR, UNUSED, OPCHAR, UNUSED, OPCHAR, OPCHAR, +/* ( ) * + , - . / */ + OPCHAR, OPCHAR, OPCHAR, OPCHAR, OPCHAR, OPCHAR, OPCHAR, OPCHAR, +/* 0 1 2 3 4 5 6 7 */ + DIGITS, DIGITS, DIGITS, DIGITS, DIGITS, DIGITS, DIGITS, DIGITS, +/* 8 9 : ; < = > ? */ + DIGITS, DIGITS, OPCHAR, OPCHAR, OPCHAR, OPCHAR, OPCHAR, OPCHAR, + +/* @ A B C D E F G */ + UNUSED, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, +/* H I J K L M N O */ + LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, +/* P Q R S T U V W */ + LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, +/* X Y Z [ \ ] ^ _ */ + LETTER, LETTER, LETTER, OPCHAR, UNUSED, OPCHAR, OPCHAR, LETTER, + +/* ` a b c d e f g */ + UNUSED, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, +/* h i j k l m n o */ + LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, +/* p q r s t u v w */ + LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, +/* x y z { | } ~ del */ + LETTER, LETTER, LETTER, OPCHAR, UNUSED, OPCHAR, UNUSED, UNUSED +}; + + +extern FILE *astringfile; +static char *buffptr; +static char buffer[2][LINELEN]; +static int currentbuf = 1; + +#define addbuf(x) *buffptr++ = x + +static int ch = ' '; + +skip() +{ + while((chtype[ch] == IGNORE) ) { + ch = getch(); + } +} + +llaccept(t) +LLtoken *t; +{ + switch(t->llstate) { + case NORMAL: + break; + case INSERT: + fprintf(stderr,"Insert %s\n", llstrings[t->llterm]); + break; + case DELETE: + fprintf(stderr,"Delete %s\n", llstrings[t->llterm]); + break; + } +} + +#define TVAL (t->llattrib) + + +dump_buffer() +{ + register int i; + for(i=0; i<20; i++) + (void) fputc(buffer[currentbuf][i], stderr); + (void) fputc('\n', stderr); + (void) fflush(stderr); +} + +int iskey(c, buf) +char *c; +char **buf; +{ + register int i; + static struct { char *key_word; int term_type; } keys[] = { + { "SAME", T_SAME }, + { "DEFAULT", T_DEFAULT }, + { "NULLACTION", T_NULLACTION }, + { "STRUCT", T_STRUCT }, + { "SYNONYM", T_SYNONYM }, + { "TRANSITIONS", T_TRANSITIONS }, + { "STATES", T_STATES }, + { "EVENTS", T_EVENTS }, + { "PCB", T_PCB }, + { "INCLUDE", T_INCLUDE }, + { "PROTOCOL", T_PROTOCOL }, + { 0, 0}, + }; + + for (i = 0; keys[i].key_word ; i++) { + if( !strcmp(c, (*buf = keys[i].key_word) ) ) { + return ( keys[i].term_type ); + } + } + *buf = (char *)0; + return(0); +} + +getstr(o,c) + /* c is the string delimiter + * allow the delimiter to be escaped + * the messy part: translate $ID to + * e->ev_union.ID + * where ID is an event with a non-zero obj_struc + * need we check for the field??? + */ +char o,c; +{ + register int nested = 1; + register int allow_nesting = (o==c)?-1:1; + + IFDEBUG(S) + fprintf(stdout,"getstr: ch=%c, delimiters %c %c\n", + ch,o, c); + fprintf(stdout,"getstr: buffptr 0x%x, currentbuf 0x%x\n", + buffptr, currentbuf); + ENDDEBUG + + if( ch == c ) nested--; + while(nested) { + if(ch == '\0') { + fprintf(stderr, + "Eof inside of a string, delims= %c,%c, nesting %d",c,o, nested); + Exit(-1); + /* notreached */ + } else if(ch == '$') { + /* might be an attribute */ + IFDEBUG(S) + fprintf(stdout,"getstr: atttribute?\n"); + ENDDEBUG + + /* assume it's an event */ + /* addbuf is a macro so this isn't as bad as + * it looks + * add "e->ev_union." + */ + if( (ch = getch()) == '$' ) { + addbuf('e'); addbuf('-'); addbuf('>'); + addbuf('e'); addbuf('v'); addbuf('_'); + addbuf('u'); addbuf('n'); addbuf('i'); + addbuf('o'); addbuf('n'); + addbuf('.'); + AddCurrentEventName(& buffptr); + } else { + char *obufp = buffptr; + + do { + addbuf(ch); + ch = getch(); + } while(chtype[ch] & LETTER); + addbuf('\0'); + if( !strncmp(obufp, synonyms[PCB_SYN], + strlen(synonyms[PCB_SYN]) )) { + buffptr = obufp; + addbuf('p'); + } else if( !strncmp(obufp, synonyms[EVENT_SYN], + strlen(synonyms[EVENT_SYN]))) { + buffptr = obufp; + addbuf('e'); + } else { + fprintf(stderr, "Unknown synonym %s\n", obufp); + Exit(-1); + } + if(ch == '.') { + addbuf('-'); addbuf('>'); + } else { + /* needs to be checked for nesting */ + goto check; + } + } + /* end of attribute handling */ + goto skip; + } else if(ch == '\\') { + /* possible escape - this is kludgy beyond belief: + * \ is used to escape open and closing delimiters + * and '$' + * otherwise it's passed through to be compiled by C + */ + ch = getch(); + if( (ch != o ) && (ch != c) && (ch != '$') ) { + /* may need to handle case where \ is last char in file... */ + /* don't treat is as escape; not open or close so + * don't have to worry about nesting either + */ + addbuf('\\'); + } + } + addbuf(ch); + skip: + ch = getch(); + check: + if( ch == o ) nested += allow_nesting; + else if( ch == c ) nested--; + if ( (buffptr - buffer[currentbuf]) > LINELEN) { + fprintf(stderr, + "%s too long.\n", (o=='{')?"Action":"Predicate"); /*}*/ + fprintf(stderr, + "buffptr, currentbuf 0x%x, 0x%x\n",buffptr,currentbuf ); + Exit(-1); + } + IFDEBUG(S) + fprintf(stdout,"loop in getstr: ch 0x%x,%c o=%c,c=%c nested=%d\n", + ch,ch,o,c,nested); + ENDDEBUG + } + addbuf(ch); + addbuf('\0'); + + IFDEBUG(S) + fprintf(stdout,"exit getstr: got %s\n", buffer[currentbuf]); + fprintf(stdout,"exit getstr: buffptr 0x%x, currentbuf 0x%x\n", + buffptr, currentbuf); + ENDDEBUG +} + +getch() +{ + char c; + extern FILE *infile; + extern int lineno; + + c = fgetc(infile) ; + if (c == '\n') lineno++; + if ((int)c == EOF) c = (char)0; + if (feof(infile)) c = (char) 0; + IFDEBUG(e) + fprintf(stdout, "getch: 0x%x\n", c); + (void) fputc( c, stdout); + fflush(stdout); + ENDDEBUG + + return c; +} + +llscan(t) +LLtoken *t; +{ + char c; + + t->llstate = NORMAL; + + ++currentbuf; + currentbuf&=1; +again: + buffptr = &buffer[currentbuf][0]; + + skip(); + + switch(chtype[ch]) { + + case EOFILE: + t->llterm = T_ENDMARKER; + break; + + case UNUSED: + fprintf(stderr, "Illegal character in input - 0x%x ignored.", ch); + ch = getch(); + goto again; + + case OPCHAR: + + switch(ch) { + + case '/': + /* possible comment : elide ; kludge */ + IFDEBUG(S) + fprintf(stdout, "Comment ch=%c\n", ch); + ENDDEBUG + c = getch(); + if (c != '*') { + fprintf(stderr,"Syntax error : character(0x%x) ignored", ch); + ch = c; + goto again; + } else { + register int state = 2, whatchar=0; + static int dfa[3][3] = { + /* done seen-star middle */ + /* star */ { 0, 1, 1 }, + /* / */ { 0, 0, 2 }, + /* other */ { 0, 2, 2 } + }; + + while( state ) { + if( (c = getch()) == (char)0) + break; + whatchar = (c=='*')?0:(c=='/'?1:2); + IFDEBUG(S) + fprintf(stdout, + "comment: whatchar = %d, c = 0x%x,%c, oldstate=%d", + whatchar, c,c, state); + ENDDEBUG + state = dfa[whatchar][state]; + IFDEBUG(S) + fprintf(stdout, ", newstate=%d\n", state); + ENDDEBUG + } + if(state) { + fprintf(stderr, + "Syntax error: end of file inside a comment"); + Exit(-1); + } else ch = getch(); + } + IFDEBUG(S) + fprintf(stdout, "end of comment at 0x%x,%c\n",ch,ch); + ENDDEBUG + goto again; + + + case '*': + t->llterm = T_STAR; + break; + + case ',': + t->llterm = T_COMMA; + break; + + case ';': + t->llterm = T_SEMI; + break; + + case '<': + t->llterm = T_LANGLE; + break; + + case '=': + t->llterm = T_EQUAL; + break; + + case '[': + t->llterm = T_LBRACK; + break; + + case ']': + t->llterm = T_RBRACK; + break; + +#ifdef T_FSTRING + case '"': + t->llterm = T_FSTRING; + addbuf(ch); + ch = getch(); + getstr('"', '"'); + TVAL.FSTRING.address = stash(buffer[currentbuf]); + break; +#endif T_FSTRING + + case '(': + t->llterm = T_PREDICATE; + getstr(ch, ')' ); + TVAL.PREDICATE.address = buffer[currentbuf]; + break; + + case '{': + t->llterm = T_ACTION; + getstr(ch, '}'); + TVAL.ACTION.address = buffer[currentbuf]; + break; + + default: + fprintf(stderr,"Syntax error : character(0x%x) ignored", ch); + ch = getch(); + goto again; + + } + ch = getch(); + break; + + case LETTER: + do { + addbuf(ch); + ch = getch(); + } while(chtype[ch] & (LETTER | DIGITS)); + + addbuf('\0'); + + t->llterm = iskey(buffer[currentbuf], &TVAL.ID.address); + if(!t->llterm) { + t->llterm = T_ID; + TVAL.ID.address = buffer[currentbuf]; + } + IFDEBUG(S) + fprintf(stdout, "llscan: id or keyword 0x%x, %s\n", + TVAL.ID.address, TVAL.ID.address); + ENDDEBUG + break; + + default: + fprintf(stderr, "Snark in llscan: chtype=0x%x, ch=0x%x\n", + chtype[ch], ch); + } +} |