home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Guide / c-cplusplus-interactive-guide.iso / c_ref / csource3 / 173_01 / cstock.lxi < prev    next >
Encoding:
Text File  |  1979-12-31  |  5.6 KB  |  217 lines

  1.  
  2. /*
  3.  * Lexical Analyzer for C Library Driver
  4.  *    - evaluates C chars, strings, ints, and floats
  5.  *    - accepts unquoted chars and strings of printing characters
  6.  */
  7.  
  8. ascii    = [\0-\177];          /* Any ASCII character */
  9. white    = [\n\r\t ];          /* The white spaces */
  10. sign     = [-+];               /* Numeric signs */
  11. digit    = [0-9];              /* The digits */
  12. hexdigit = [0-9A-Fa-f];        /* The hexadecimal digits */
  13. hexflag  = [Xx];               /* Inidcator of a hexadecimal constant */
  14. expflag  = [Ee];               /* Inidcator of a floating exponent */
  15.  
  16. t_atom = [!-~];                  /* All the printing characters */
  17. text   = [!#-&(-/:-~](t_atom)*;  /* Text can't start with a digit, " or ' */
  18.  
  19. e_particle   = "\\" ascii;    /* An escaped ascii character */
  20. s_particle   = [^\\"];        /* Anything besides an escape or a quote */
  21. c_particle   = [^\\'];        /* Anything besides an escape or an apostrophe */
  22.  
  23. c_atom = e_particle | c_particle; /* Anything but end of char */
  24. s_atom = e_particle | s_particle; /* Anything but end of string */
  25.  
  26. string = '"' s_atom*  '"';
  27. char   = "'" c_atom*  "'";
  28.  
  29. %{
  30. #include "std.h"
  31. #include "clib.h"
  32.  
  33. TEXT yytext[100];
  34. INTEGER yyival;
  35. FLOAT yyfval, pow();
  36. %}
  37. %%
  38.  
  39. ARG               {return(ARG);}
  40. PRINTF           {return(PTF);}
  41. ISLOWER        {return(ILO);}
  42. EXIT           {return(EXT);}
  43.  
  44. [-]*(digit)(hexflag)*(hexdigit)* { 
  45.        {register TEXT *p = yytext; 
  46.         BOOLEAN minus = FALSE;
  47.         INTEGER base;
  48.  
  49.         gettoken(yytext, sizeof(yytext));
  50.         yyival = 0;
  51.         if(*p == '-') {
  52.             ++p;
  53.             minus = TRUE;
  54.         }
  55.         base = 10;
  56.         if(*p == '0') {
  57.             ++p;
  58.             if(*p == 'X' || *p == 'x') {
  59.                 ++p;
  60.                 base = 16;
  61.             } else
  62.                 base =  8;
  63.         }
  64.         do {
  65.             yyival = base*yyival + hex(*p);
  66.         } while(*++p);
  67.         if(minus) yyival = -yyival;
  68.         printf("\nLEX/ICON: %s is %d (decimal)\n", yytext, yyival);
  69.         return(ICON);
  70.         }}
  71.  
  72. [-]*(digit)*"."*(digit)*expflag*sign*digit* {{
  73.         register TEXT *p = yytext; 
  74.         FLOAT divisor = 10.0, multiplier = 0.0;
  75.         BOOLEAN minus = FALSE, expminus = FALSE;
  76.         BOOLEAN decimal = FALSE, exponent = FALSE;
  77.  
  78.         gettoken(yytext, sizeof(yytext));
  79.         yyfval = 0.0;
  80.         if(*p == '-') {
  81.             ++p;
  82.             minus = TRUE;
  83.         }
  84.  
  85.         do {
  86.             switch(*p) {
  87.             case '.': decimal = TRUE; 
  88.                       break;
  89.  
  90.             case 'e':
  91.             case 'E': exponent = TRUE;
  92.                       if(*(p+1) == '-' || *(p+1) == '+')
  93.                             expminus = (*++p == '-') ? TRUE : FALSE;
  94.                       break;
  95.  
  96.             default : if(!decimal && ! exponent) {
  97.                           yyfval = 10. * (yyfval) + (*p - '0');
  98.                           break;
  99.                        } else if(!exponent) {
  100.                           yyfval = yyfval + (*p - '0')/divisor;
  101.                           divisor *= 10.;
  102.                           break;
  103.                        } else
  104.                           multiplier = 10. * multiplier + (*p - '0');
  105.             }
  106.         } while (*++p);
  107.  
  108.             if(minus) yyfval = -yyfval;
  109.             if(expminus) multiplier = -multiplier;
  110.             if(exponent) yyfval = yyfval * pow(10., multiplier);
  111.             printf("\nLEX/FCON: %s is %f\n", yytext, yyfval);
  112.             return(FCON);
  113.         }}
  114.  
  115. text  {
  116.        gettoken(yytext, sizeof(yytext));
  117.        if(strlen(yytext) == 1) {
  118.            printf("\nLEX/CCON: '%s'\n", yytext);
  119.            return(CCON);
  120.        } else {
  121.           printf("\nLEX/SCON: \"%s\"\n", yytext);
  122.           return(SCON);
  123.        }    
  124.       }
  125.  
  126. string  {
  127.           gettoken(yytext, sizeof(yytext));
  128.           strcpy(yytext, yytext+1);
  129.           yytext[strlen(yytext)-1] = NULL;
  130.           descape(yytext);
  131.           printf("\nLEX/SCON: \"%s\"\n", yytext);
  132.           return(SCON);
  133.         }
  134.  
  135. char  {
  136.        gettoken(yytext, sizeof(yytext));
  137.        strcpy(yytext, yytext+1);
  138.        yytext[strlen(yytext)-1] = NULL;
  139.        descape(yytext);
  140.        printf("\nLEX/CCON: '%s'\n", yytext);
  141.        return(CCON);
  142.       }
  143.  
  144. white(white)*    {return(LEXSKIP);}
  145.  
  146. %%
  147.  
  148. lexgetc(){
  149.     static BOOLEAN newline = TRUE;
  150.     register int c;
  151.  
  152.     if(newline)
  153.         printf("%s>", "C Lib");
  154.  
  155.     if((c = getc(lexin)) == '\n')
  156.         newline = TRUE;
  157.     else
  158.         newline = FALSE;    
  159.  
  160.     return(c);
  161. }
  162.  
  163. /*
  164. ** Translate escape sequences in a character string
  165. */
  166. descape(str)
  167. register STRING str;
  168. {
  169.         register STRING s;
  170.         COUNT i;
  171.  
  172.         for(s = str; *str; s++, str++) {
  173.  
  174.             if(*str != '\\')
  175.                 *s = *str;
  176.             else if (0 <= (i = ndex("'\"bnrtf", *++str)))
  177.                 *s = "'\"\b\n\r\t\f"[i];
  178.             else if (isdigit(*str)) { register BYTE d;
  179.                 *s = *str - '0';
  180.                 for (i=0; (d = *(str+1)) && isdigit(d) && i < 3; i++, str++)
  181.                         *s = (*s << 3) + d - '0';
  182.             }
  183.         }
  184.         *s = '\0';
  185. }
  186.  
  187. /*
  188. ** Find the index of a character in a string
  189. */
  190. INTEGER ndex(str, chr)
  191. register STRING str;
  192. CHARACTER chr;
  193. {
  194.     register COUNT i;
  195.  
  196.     for(i = 0; *str; i++, str++)
  197.         if(*str == chr)    return(i);
  198.     return(-1);
  199. }
  200.  
  201. /*
  202. ** Convert a hex digit (ASCII)
  203. */
  204. INTEGER hex(c)
  205. register CHARACTER c;
  206. {
  207.         if (isdigit(c))
  208.                 return (c - '0');
  209.         else if ('a' <= c && c <= 'f')
  210.                 return (c + 10 - 'a');
  211.         else if ('A' <= c && c <= 'F')
  212.                 return (c + 10 - 'A');
  213.         else
  214.                 return(0);
  215. }
  216.          if (i == T_EOL && !is_eof
  217.                                         && *linep == 0) {
  218.