home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / awk / awk320sr.zip / AWKLEX.L < prev    next >
Text File  |  1991-04-25  |  7KB  |  281 lines

  1. %{
  2. /*
  3.  * Awk lexical analyser
  4.  *
  5.  * Copyright (C) 1988, 1989, 1990, 1991 by Rob Duff
  6.  * All rights reserved
  7.  */
  8. #include <string.h>
  9. #include <stdlib.h>
  10. #include <math.h>
  11. #include <alloc.h>
  12.  
  13. #include "awk.h"
  14. #include "awklex.h"
  15. #include "awkyacc.h"
  16. #undef input
  17. #pragma warn-rch
  18.  
  19. int input(void);
  20.  
  21. struct  func {
  22.     char    *name;
  23.     char    type, code;
  24. } *funcp, func[] = {
  25.     0,0,0
  26. };
  27.  
  28. static int comment(void);
  29. static void string(int);
  30. static void newline(void);
  31. static void eatspace(void);
  32.  
  33. %}
  34. %%
  35. "\\\n"      ;
  36. [ \t]       eatspace();
  37. '\n'    {
  38.             newline();
  39.             return T_EOL;
  40.         }
  41. '#'     {
  42.             comment();
  43.             newline();
  44.             return T_EOL;
  45.         }
  46. "BEGIN"     return T_BEGIN;
  47. "END"       return T_END;
  48. "if"        return T_IF;
  49. "in"        return T_IN;
  50. "do"        return T_DO;
  51. "for"       return T_FOR;
  52. "else"      return T_ELSE;
  53. "while"     return yydone?T_DONE:T_WHILE;
  54. "break"     return T_BREAK;
  55. "continue"  return T_CONTINUE;
  56. "function"  return T_FUNCTION;
  57. "return"    return T_RETURN;
  58. "next"      return T_NEXT;
  59. "exit"      return T_EXIT;
  60. "close"     return T_CLOSE;
  61. "print"     return T_PRINT;
  62. "printf"    return T_PRINTF;
  63. "getline"   return T_GETLINE;
  64. "delete"    return T_DELETE;
  65. "index"     return T_INDEX;
  66. "match"     return T_MATCH;
  67. "split"     return T_SPLIT;
  68. "substr"    return T_SUBSTR;
  69. "sprintf"   return T_SPRINTF;
  70. "srand"     return T_SRAND;
  71. "sub"       { yylval.ival = P_LSUB; return T_SUB; }
  72. "gsub"      { yylval.ival = P_GSUB; return T_SUB; }
  73. "rand"      { yylval.ival = C_RAND; return T_FUNC0; }
  74. "system"    { yylval.ival = C_SYS; return T_FUNC1; }
  75. "length"    { yylval.ival = C_LEN; return T_FUNC1; }
  76. "toupper"   { yylval.ival = C_UPR; return T_FUNC1; }
  77. "tolower"   { yylval.ival = C_LWR; return T_FUNC1; }
  78. "cos"       { yylval.ival = C_COS; return T_FUNC1; }
  79. "exp"       { yylval.ival = C_EXP; return T_FUNC1; }
  80. "int"       { yylval.ival = C_INT; return T_FUNC1; }
  81. "log"       { yylval.ival = C_LOG; return T_FUNC1; }
  82. "sin"       { yylval.ival = C_SIN; return T_FUNC1; }
  83. "sqrt"      { yylval.ival = C_SQRT; return T_FUNC1; }
  84. "atan2"     { yylval.ival = C_ATAN2; return T_FUNC2; }
  85. [a-zA-Z_][0-9a-zA-Z_]* {
  86.             funcp = func;
  87.             while (funcp->name != 0) {
  88.                 if (strcmp(yytext, funcp->name) == 0) {
  89.                     yylval.ival = funcp->code;
  90.                     return funcp->type;
  91.                 }
  92.                 funcp++;
  93.             }
  94.             yylval.vptr = lookup(yytext);
  95.             if (yypeek() == '(')
  96.                 return T_USER;
  97.             return T_NAME;
  98.         }
  99. [0-9]+ |
  100. [0-9]+\.[0-9]+ |
  101. [0-9]+[Ee][-+]?[0-9]+ |
  102. [0-9]+\.[0-9]+[Ee][-+]?[0-9]+ {
  103.             yylval.dval = atof(yytext);
  104.             return T_DCON;
  105.         }
  106. ">>"        return T_APPEND;
  107. "!~"        return T_NOMATCH;
  108. "&&"        return T_LAND;
  109. "||"        return T_LIOR;
  110. "!="        { yylval.ival = C_NE; return T_RELOP; }
  111. "=="        { yylval.ival = C_EQ; return T_RELOP; }
  112. "<="        { yylval.ival = C_LE; return T_RELOP; }
  113. ">="        { yylval.ival = C_GE; return T_RELOP; }
  114. "++"        { yylval.ival = C_ADD; return T_INCOP; }
  115. "--"        { yylval.ival = C_SUB; return T_INCOP; }
  116. "^="        { yylval.ival = C_POW; return T_STORE; }
  117. "*="        { yylval.ival = C_MUL; return T_STORE; }
  118. "/="        { yylval.ival = C_DIV; return T_STORE; }
  119. "%="        { yylval.ival = C_MOD; return T_STORE; }
  120. "+="        { yylval.ival = C_ADD; return T_STORE; }
  121. "-="        { yylval.ival = C_SUB; return T_STORE; }
  122. "="         { yylval.ival = 0; return T_STORE; }
  123. "}"     {
  124.             yyback('\n');
  125.             return '}';
  126.         }
  127. "-"         return '-';
  128. "]"         return ']';
  129. [{[$!?:;,^~/*%+<>()] {
  130.             return *yytext;
  131.         }
  132. '"'     {
  133.             string('"');
  134.             return T_SCON;
  135.         }
  136. .           return ERROR;
  137. %%
  138.  
  139. static void string(int ec)
  140. {
  141.     register int len;
  142.     register c;
  143.  
  144.     buffer[0] = '\377';
  145.     for (len = 1; len < 79 && (c = yymapc(ec, '\\')) != EOF; len++)
  146.         buffer[len] = c;
  147.     buffer[len] = '\0';
  148.     if (len == 1)
  149.         yylval.sptr = (char near *)nullstr;
  150.     else {
  151.         yylval.sptr = yyalloc(len+1);
  152.         strcpy(yylval.sptr, buffer);
  153.     }
  154. }
  155.  
  156. static int comment()
  157. {
  158.     register int ch;
  159.  
  160.     while ((ch = yynext()) != EOF && ch != '\n')
  161.         ;
  162.     return ch;
  163. }
  164.  
  165. static void newline()
  166. {
  167.     register int ch;
  168.  
  169.     while ((ch = yynext()) != EOF) {
  170.         if (ch == '#')
  171.             ch = comment();
  172.         if (ch != ' ' && ch != '\t' && ch != '\n') {
  173.             yyback(ch);
  174.             break;
  175.         }
  176.     }
  177. }
  178.  
  179. static void eatspace()
  180. {
  181.     register int ch;
  182.  
  183.     while ((ch = yynext()) == ' ' || ch == '\t')
  184.         ;
  185.     yyback(ch);
  186. }
  187.  
  188. int
  189. input()
  190. {
  191.     if (lineptr == NULL) {
  192.         if (awklist != NULL) {
  193.             yyline = 0;
  194.             yyname = awklist->name;
  195.             if (yyname == awkstdin)
  196.                 awkfile = stdin;
  197.             else {
  198.                 awkfile = fopen(yyname ,"r");
  199.                 if (awkfile == NULL)
  200.                     error("Can't open program file %s", yyname);
  201.             }
  202.             awklist = awklist->next;
  203.             lineptr = linebuf;
  204.             *lineptr = '\0';
  205.         }
  206.         else {
  207.             awkeof = 1;
  208.             return(EOF);
  209.         }
  210.     }
  211.     if (*lineptr == '\0') {
  212.         if (awkeof)
  213.             return(EOF);
  214.         lineptr = fgets(linebuf, 128, awkfile);
  215.         if (lineptr != linebuf) {
  216.             lineptr = NULL;
  217.             return('\n');
  218.         }
  219.         yyline++;
  220.         genline();
  221.         if (linebuf[0] == '.' && linebuf[1] == '\n') {
  222.             awkeof = 1;
  223.             lineptr = NULL;
  224.             return(EOF);
  225.         }
  226.     }
  227.     return(*lineptr++);
  228. }
  229.  
  230. IDENT *lookup(char *name)
  231. {
  232.     char    *sp;
  233.     IDENT   *vp;
  234.  
  235.     for (vp = ident; vp != NULL; vp = vp->vnext)
  236.         if (strcmp(name, vp->vname) == 0)
  237.             return vp;
  238.     if (nextvar >= vartab+MAXNAME)
  239.         yyerror("Too many variables");
  240.     
  241.     sp = yyalloc(strlen(name) + 1);
  242.     strcpy(sp, name);
  243.     vp = yyalloc(sizeof(IDENT));
  244.     vp->vitem = NULL;
  245.     vp->vname = sp;
  246.     vp->vfunc = NULL;
  247.     vp->vnext = ident;
  248.     ident = vp;
  249.     return vp;
  250. }
  251.  
  252. void *
  253. yyalloc(size)
  254. unsigned int size;
  255. {
  256.     void    *mp;
  257.  
  258.     mp = malloc(size);
  259.     if (mp == NULL)
  260.         yyerror("out of memory");
  261.     memset(mp, 0, size);
  262.     return(mp);
  263. }
  264.  
  265. void
  266. yyerror(str)
  267. char *str;
  268. {
  269.     char  *lp, *ep;
  270.  
  271.     fprintf(stderr, "%s", linebuf);
  272.     if ((char near *)lineptr != NULL) {
  273.         ep = (char near *)lineptr - 1 - yylook();
  274.         for (lp = linebuf; lp < ep; lp++)
  275.             fputc(*lp=='\t'?'\t':' ', stderr);
  276.         fprintf(stderr, "^\n");
  277.     }
  278.     error(str, NULL);
  279. }
  280.  
  281.