home *** CD-ROM | disk | FTP | other *** search
- /* lex.c -- tokeniser
- */
-
- #include <stdio.h>
- #include <ctype.h>
- #include "bstokens.h"
-
- #define gather(c) { yytext[yyleng++] = c; }
- #define getdig(c) { for(;isdigit(c);c=input()) gather(c); }
-
- #define ERROR (-1) /* yacc won't know what -1 is, gaurantees a syntax error */
-
- #define YYTXTSIZ 200
- char yytext[YYTXTSIZ];
- int yyleng;
- extern char *yylval; /* to return values to Yacc with */
- extern FILE *bsin;
-
- struct word {
- int val;
- char *name;
- } words[] = {
- OR,"or", AND,"and", NOT,"not", RET,"return",
- IF,"if", THEN,"then", ELSE,"else", WHILE,"while",
- GOTO,"goto", GOSUB,"gosub", STOP,"stop", END,"end",
- LET,"let", PRINT,"print", INPUT,"input", FOR,"for",
- TO,"to", STEP,"step", READ,"read", WRITE,"write",
- NEXT,"next", DATA,"data", ELIHW,"elihw", REPEAT,"repeat",
- UNTIL,"until", DEFINE,"define", LFUN,"longf", SFUN,"shortf",
- FDEF,"file", DIM,"dim", SYMBOL,"symbol", VALUE,"value",
- ITOR,"itor", ITOA,"itoa", RTOI,"rtoi", RTOA,"rtoa",
- CONTINUE,"continue", LEAVE,"leave",
- LOOP,"loop", EXITIF,"exitif", POOL,"pool",
- -1,0
- };
-
- int yylex()
- {
- char c;
- int i,j,typ;
-
- yylval = &yytext[0];
- loop:
- c=input();
- /* tab, or space */
- if(c=='\t' || c==' ')
- goto loop;
- /* numbers start with a digit or a dot */
- else if(isdigit(c) || c=='.')
- {
- yyleng=0;
- typ=INTEGER;
- getdig(c);
- if(c == '.')
- {
- typ = REAL;
- gather(c);
- c = input();
- getdig(c);
- }
- /* at this point, SOME digits must have been read, or else error */
- if(yyleng==1 && yytext[0]=='.') goto reterr; /* only "." read */
- if(yyleng == 0) goto reterr;
- j = yyleng; /* save end of first part */
- if(c=='e' || c=='E') /* number raised to something */
- {
- typ = REAL;
- gather(c);
- c = input();
- if(c=='-' || c=='+') {gather(c); c=input(); }
- getdig(c);
- /* if no digits read since end of first part,
- * then there is an error
- */
- for(i=yyleng; i>=j; i--)
- if(isdigit(yytext[i]))
- break;
- if(i <= j) goto reterr;
- }
- unput(c);
- gather('\0');
- yylval = malloc(yyleng);
- strcpy(yylval,yytext);
- return(typ);
- reterr:
- yyerror("badly formed number\n");
- return(ERROR);
- }
- /* word of some kind */
- else if(isalpha(c))
- {
- yyleng=0;
- gather(c);
- for(c=input(); isalpha(c) || isdigit(c) || c=='$' || c=='%'; c=input())
- gather(c);
- unput(c);
- gather('\0');
-
- fold(yytext);
- for(i=0; words[i].val!=-1; i++)
- if(strcmp(yytext,words[i].name)==0)
- break;
- yylval = malloc(yyleng);
- strcpy(yylval,yytext);
- if(words[i].val != -1)
- return(words[i].val);
- else
- switch(yytext[yyleng-2]) {
- case '$': return(SWORD);
- case '%': return(IWORD);
- default: return(RWORD);
- }
- }
- /* string constant */
- else if(c == '\"')
- {
- yyleng=0;
- for(c=input(); ;c=input())
- {
- if(c == '\"')
- if((c=input()) == '\"')
- {
- gather('\\');
- gather('\"');
- }
- else break;
- else if(c == '\\')
- {
- gather('\\');
- c=input();
- gather(c);
- if(c == '\n') rdlin(bsin);
- }
- else if(c == '\n')
- {
- fprintf(stderr,"unclosed string constant: %s\n",yytext);
- rdlin(bsin);
- return(ERROR);
- }
- else gather(c);
- }
- unput(c);
- gather('\0');
- yylval = malloc(yyleng);
- strcpy(yylval,yytext);
- return(SCONST);
- }
- else if(c == '=')
- /* EQUAL == '==' */
- if((c=input()) == '=')
- return(EQUAL);
- /* ASSIGN == '=' */
- else
- { unput(c); return('='); }
- else if(c == '<')
- /* NEQ == '<>' */
- if((c=input()) == '>')
- return(NEQ);
- /* LE == '<=' */
- else if(c == '=')
- return(LE);
- /* LT == '<' */
- else
- { unput(c); return(LT); }
- else if(c == '>')
- /* GE == '>=' */
- if((c=input()) == '=')
- return(GE);
- /* GT == '>' */
- else
- { unput(c); return(GT); }
- /* anything else */
- else return(c);
- }
-
- /* fold(s) -- change string to all lower-case letters.
- */
- fold(s) char *s;
- {
- int i;
- for(i=0; s[i]!='\0'; i++)
- if(isupper(s[i]))
- s[i] = s[i] + ('a'-'A');
- return(s);
- }
-