summaryrefslogtreecommitdiffstats
path: root/sys/netiso/xebec/llscan.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netiso/xebec/llscan.c')
-rw-r--r--sys/netiso/xebec/llscan.c430
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);
+ }
+}
OpenPOWER on IntegriCloud