|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T a
Length: 6037 (0x1795) Types: TextFile Names: »advscn.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987 └─⟦this⟧ »EUUGD18/General/Advsys/advscn.c«
/* advscn.c - a lexical scanner for the adventure compiler */ /* Copyright (c) 1986, by David Michael Betz All rights reserved */ #include "advcom.h" /* useful definitions */ #define maplower(ch) (isupper(ch) ? tolower(ch) : ch) /* global variables */ int errcount=0; /* error count */ int t_value; /* numeric value */ char t_token[TKNSIZE+1];/* token string */ char *t_names[] = { 0, "(", ")", "STRING", "IDENTIFIER", "NUMBER", "EOF" }; /* external variables */ extern FILE *ifp; /* input file pointer */ extern int msgoff; /* message section offset */ /* local variables */ static int savetkn = 0; /* look ahead token */ static int savech = 0; /* look ahead character */ static char fname[200]; /* include file name */ static char line[200]; /* current input line */ static char *lptr; /* line pointer */ static int lnum; /* line number */ static int ieof; /* input end of file flag */ static int save_lnum; /* saved lnum */ static FILE *save_ifp; /* saved ifp */ static int scnt; /* count of characters in string */ /* sinit - initialize the scanner */ sinit() { /* setup the line buffer */ lptr = line; *lptr = 0; lnum = 0; /* no include file yet */ save_ifp = NULL; /* no lookahead yet */ savech = 0; savetkn = 0; /* not eof yet */ ieof = FALSE; } /* token - get the next token */ int token() { int tkn; if (tkn = savetkn) savetkn = 0; else tkn = rtoken(); return (tkn); } /* stoken - save a token */ stoken(tkn) int tkn; { savetkn = tkn; } /* rtoken - read the next token */ int rtoken() { int ch; /* check the next character */ for (;;) switch (ch = skipspaces()) { case EOF: return (T_EOF); case '(': strcpy(t_token,"("); return (T_OPEN); case ')': strcpy(t_token,")"); return (T_CLOSE); case '"': return (getstring()); case ';': while (getch() != '\n'); break; default: return (getid(ch)); } } /* getstring - get a string */ int getstring() { int ch,sflag; t_value = msgoff; sflag = FALSE; scnt = 0; while ((ch = getch()) != EOF && ch != '"') if (isspace(ch)) sflag = TRUE; else { if (ch == '\\') switch (ch = getch()) { case 'n': ch = '\n'; break; case 't': ch = '\t'; break; } if (sflag) { wputc(' '); sflag = FALSE; } wputc(ch); } if (sflag) wputc(' '); strdone(); strcpy(t_token,"{string}"); return (T_STRING); } /* getid - get an identifier */ int getid(ch) int ch; { char *p; p = t_token; *p++ = maplower(ch); while ((ch = getch()) != EOF && isidchar(ch)) *p++ = maplower(ch); *p = EOS; savech = ch; return (isnumber(t_token,&t_value) ? T_NUMBER : T_IDENTIFIER); } /* isnumber - check if this string is a number */ int isnumber(str,pval) char *str; int *pval; { int digits; char *p; /* initialize */ p = str; digits = 0; /* check for a sign */ if (*p == '+' || *p == '-') p++; /* check for a string of digits */ while (isdigit(*p)) p++, digits++; /* make sure there was at least one digit and this is the end */ if (digits == 0 || *p) return (FALSE); /* convert the string to an integer and return successfully */ if (*str == '+') ++str; *pval = atoi(str); return (TRUE); } /* wputc - put a character into the output file */ wputc(ch) int ch; { ad_putc(encode(ch)); scnt++; } /* strdone - finish a string */ strdone() { wputc('\0'); while (scnt & 3) wputc('\0'); msgoff += scnt >> 2; } /* skipspaces - skip leading spaces */ skipspaces() { int ch; while ((ch = getch()) && isspace(ch)) ; return (ch); } /* isidchar - is this an identifier character */ int isidchar(ch) int ch; { return (!isspace(ch) && ch != '(' && ch != ')' && ch != '"'); } /* getch - get the next character */ int getch() { FILE *fp; int ch; /* check for a lookahead character */ if (ch = savech) savech = 0; /* check for a buffered character */ else if (ch = *lptr) lptr++; /* check for end of file */ else if (ieof) ch = EOF; /* read another line */ else { /* read the line */ for (lptr = line; (ch = getchr()) != EOF && (*lptr++ = ch) != '\n';) ; *lptr = 0; lnum++; /* check for an included file */ if (line[0] == '@') { /* open the file */ strcpy(fname,&line[1]); fname[strlen(fname)-1] = 0; if ((fp = fopen(fname,"r")) == NULL) { printf("Can't open include file: %s\n",fname); exit(); } printf("[ including %s ]\n",fname); /* setup input from the file */ save_lnum = lnum; save_ifp = ifp; ifp = fp; /* setup for the first line */ lptr = line; *lptr = 0; lnum = 0; } /* otherwise this must be an input line */ else { /* terminate the line with a newline */ *lptr++ = '\n'; *lptr = 0; /* check for end of file */ if (ch == EOF) ieof = TRUE; /* update the line number and setup for the new line */ lptr = line; } /* get a character */ ch = getch(); } /* return the current character */ return (ch); } /* getchr - get a character checking for end of file */ int getchr() { int ch; if ((ch = getc(ifp)) == EOF || ch == '\032') { if (save_ifp) { printf("[ end of %s ]\n",fname); fclose(ifp); lnum = save_lnum; ifp = save_ifp; save_ifp = NULL; ch = getchr(); } else ch = EOF; } else if (ch == '\r') ch = getchr(); return (ch); } /* encode - encode a single character */ int encode(ch) int ch; { return ((ch - 30) & 0xFF); } /* error - report an error in the current line */ error(msg) char *msg; { char *p; printf(">>> %s <<<\n>>> in line %d <<<\n%s",msg,lnum,line); for (p = line; p < lptr; p++) if (*p == '\t') putchar('\t'); else putchar(' '); printf("^\n"); errcount++; #ifdef MAC macpause(); #endif } /* xerror - report an error in the current line */ xerror(msg) char *msg; { printf(">>> %s <<<\n",msg); errcount++; }