home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume2 / basic / part4 / bs2 / lex.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  3.8 KB  |  186 lines

  1. /* lex.c -- tokeniser
  2.  */
  3.  
  4. #include <stdio.h>
  5. #include <ctype.h>
  6. #include "bstokens.h"
  7.  
  8. #define gather(c)    { yytext[yyleng++] = c; }
  9. #define getdig(c)    { for(;isdigit(c);c=input()) gather(c); }
  10.  
  11. #define ERROR (-1) /* yacc won't know what -1 is, gaurantees a syntax error */
  12.  
  13. #define YYTXTSIZ    200
  14. char yytext[YYTXTSIZ];
  15. int yyleng;
  16. extern char *yylval;    /* to return values to Yacc with */
  17. extern FILE *bsin;
  18.  
  19. struct word {
  20.     int val;
  21.     char *name;
  22. } words[] = {
  23.     OR,"or",    AND,"and",    NOT,"not",    RET,"return",
  24.     IF,"if",    THEN,"then",    ELSE,"else",    WHILE,"while",
  25.     GOTO,"goto",    GOSUB,"gosub",    STOP,"stop",    END,"end",
  26.     LET,"let",    PRINT,"print",    INPUT,"input",    FOR,"for",
  27.     TO,"to",    STEP,"step",    READ,"read",    WRITE,"write",
  28.     NEXT,"next",    DATA,"data",    ELIHW,"elihw",    REPEAT,"repeat",
  29.     UNTIL,"until",    DEFINE,"define", LFUN,"longf",    SFUN,"shortf",
  30.     FDEF,"file",    DIM,"dim",    SYMBOL,"symbol", VALUE,"value",
  31.     ITOR,"itor",    ITOA,"itoa",    RTOI,"rtoi",    RTOA,"rtoa",
  32.     CONTINUE,"continue",        LEAVE,"leave",
  33.     LOOP,"loop",    EXITIF,"exitif",    POOL,"pool",
  34.     -1,0
  35. };
  36.  
  37. int yylex()
  38. {
  39.     char c;
  40.     int i,j,typ;
  41.  
  42.     yylval = &yytext[0];
  43. loop:
  44.     c=input();
  45.             /* tab, or space */
  46.     if(c=='\t' || c==' ')
  47.     goto loop;
  48.             /* numbers start with a digit or a dot */
  49.     else if(isdigit(c) || c=='.')
  50.     {
  51.     yyleng=0;
  52.     typ=INTEGER;
  53.     getdig(c);
  54.     if(c == '.')
  55.     {
  56.         typ = REAL;
  57.         gather(c);
  58.         c = input();
  59.         getdig(c);
  60.     }
  61.     /* at this point, SOME digits must have been read, or else error */
  62.     if(yyleng==1 && yytext[0]=='.') goto reterr; /* only "." read */
  63.     if(yyleng == 0) goto reterr;
  64.     j = yyleng;        /* save end of first part */
  65.     if(c=='e' || c=='E')    /* number raised to something */
  66.     {
  67.         typ = REAL;
  68.         gather(c);
  69.         c = input();
  70.         if(c=='-' || c=='+') {gather(c); c=input(); }
  71.         getdig(c);
  72.         /* if no digits read since end of first part,
  73.          * then there is an error
  74.          */
  75.         for(i=yyleng; i>=j; i--)
  76.         if(isdigit(yytext[i]))
  77.             break;
  78.         if(i <= j) goto reterr;
  79.     }
  80.     unput(c);
  81.     gather('\0');
  82.     yylval = malloc(yyleng);
  83.     strcpy(yylval,yytext);
  84.     return(typ);
  85. reterr:
  86.     yyerror("badly formed number\n");
  87.     return(ERROR);
  88.     }
  89.             /* word of some kind */
  90.     else if(isalpha(c))
  91.     {
  92.     yyleng=0;
  93.     gather(c);
  94.     for(c=input(); isalpha(c) || isdigit(c) || c=='$' || c=='%'; c=input())
  95.         gather(c);
  96.     unput(c);
  97.     gather('\0');
  98.  
  99.     fold(yytext);
  100.     for(i=0; words[i].val!=-1; i++)
  101.         if(strcmp(yytext,words[i].name)==0)
  102.             break;
  103.     yylval = malloc(yyleng);
  104.     strcpy(yylval,yytext);
  105.     if(words[i].val != -1)
  106.         return(words[i].val);
  107.     else
  108.         switch(yytext[yyleng-2]) {
  109.         case '$': return(SWORD);
  110.         case '%': return(IWORD);
  111.         default: return(RWORD);
  112.         }
  113.     }
  114.             /* string constant */
  115.     else if(c == '\"')
  116.     {
  117.     yyleng=0;
  118.     for(c=input(); ;c=input())
  119.     {
  120.         if(c == '\"')
  121.         if((c=input()) == '\"')
  122.         {
  123.             gather('\\');
  124.             gather('\"');
  125.         }
  126.         else break;
  127.         else if(c == '\\')
  128.         {
  129.         gather('\\');
  130.         c=input();
  131.         gather(c);
  132.         if(c == '\n') rdlin(bsin);
  133.         }
  134.         else if(c == '\n')
  135.         {
  136.         fprintf(stderr,"unclosed string constant: %s\n",yytext);
  137.         rdlin(bsin);
  138.         return(ERROR);
  139.         }
  140.         else gather(c);
  141.     }
  142.     unput(c);
  143.     gather('\0');
  144.     yylval = malloc(yyleng);
  145.     strcpy(yylval,yytext);
  146.     return(SCONST);
  147.     }
  148.     else if(c == '=')
  149.                 /* EQUAL == '==' */
  150.     if((c=input()) == '=')
  151.         return(EQUAL);
  152.                 /* ASSIGN == '=' */
  153.     else
  154.         { unput(c); return('='); }
  155.     else if(c == '<')
  156.                 /* NEQ == '<>' */
  157.     if((c=input()) == '>')
  158.         return(NEQ);
  159.                 /* LE == '<=' */
  160.     else if(c == '=')
  161.         return(LE);
  162.                 /* LT == '<' */
  163.     else
  164.         { unput(c); return(LT); }
  165.     else if(c == '>')
  166.                 /* GE == '>=' */
  167.     if((c=input()) == '=')
  168.         return(GE);
  169.                 /* GT == '>' */
  170.     else
  171.         { unput(c); return(GT); }
  172.             /* anything else */
  173.     else return(c);
  174. }
  175.  
  176. /* fold(s) -- change string to all lower-case letters.
  177.  */
  178. fold(s) char *s;
  179. {
  180.     int i;
  181.     for(i=0; s[i]!='\0'; i++)
  182.     if(isupper(s[i]))
  183.         s[i] = s[i] + ('a'-'A');
  184.     return(s);
  185. }
  186.