home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume21 / coda / part01 / lex.l < prev    next >
Encoding:
Text File  |  1990-04-08  |  4.0 KB  |  230 lines

  1. /*
  2. **  Copyright 1989 BBN Systems and Technologies Corporation.
  3. **  All Rights Reserved.
  4. **  This is free software, and may be distributed under the terms of the
  5. **  GNU Public License; see the file COPYING for more details.
  6. **
  7. **  Lexical analyzer for CODA server.
  8. */
  9. %{
  10. /* SUPPRESS 11 in yylook *//* Pointer subtraction */
  11. /* SUPPRESS 14 on yycrank *//* Storing a bad pointer */
  12. /* SUPPRESS 15 on yyt *//* Copying a bad pointer */
  13. /* SUPPRESS 16 on yycrank *//* Initializing bad pointer */
  14. /* SUPPRESS 18 in yylook *//* Comparing bad pointer */
  15. /* SUPPRESS 287 on ncform_sccsid *//* Unused static variable */
  16. /* SUPPRESS 288 on yyfussy *//* Unused label */
  17. #include "server.h"
  18. #include <ctype.h>
  19. #include "gram.h"
  20. #ifdef    RCSID
  21. static char RCS[] =
  22.     "$Header: lex.l,v 2.0 90/03/23 14:41:33 rsalz Exp $";
  23. #endif    /* RCSID */
  24.  
  25.  
  26. /* Key-value pair. */
  27. typedef struct _PAIR {
  28.     char    *name;
  29.     int        value;
  30. } PAIR;
  31.  
  32. /* List of the keywords. */
  33. STATIC PAIR    Keywords[] = {
  34.     {    "binaries",        BINARIES        },
  35.     {    "class",        CLASS            },
  36.     {    "define",        DEFINE            },
  37.     {    "directory",        DIRECTORY        },
  38.     {    "except",        EXCEPT            },
  39.     {    "host",            HOST            },
  40.     {    "only_explicitly",    ONLY_EXPLICITLY        },
  41.     {    "root",            ROOT            },
  42.     {    "rooted",        ROOTED            },
  43.     {    NULL,            0            }
  44. };
  45.  
  46. STATIC FILE    *F;            /* Input stream for LEX        */
  47.  
  48. #undef input
  49. #undef unput
  50. %}
  51.  
  52. %%
  53.  
  54. [a-z_]+        {
  55.             /* A simple ID or keyword. */
  56.             register PAIR    *p;
  57.  
  58.             for (p = Keywords; p->name; p++)
  59.             if (EQ(p->name, yytext))
  60.                 return p->value;
  61.             yylval.String = COPY(yytext);
  62.             return ID;
  63.             /* NOTREACHED */
  64.         }
  65.  
  66. [a-zA-Z0-9./_]+    {
  67.             /* Most common filenames. */
  68.             yylval.String = COPY(yytext);
  69.             return ID;
  70.             /* NOTREACHED */
  71.         }
  72.  
  73. [{},;:=]    {
  74.             /* Random special character. */
  75.             return *yytext;
  76.             /* NOTREACHED */
  77.         }
  78.  
  79. [ \n\t\f]        {
  80.             /* Tasty whitespace. */
  81. #ifdef    lint
  82.             /* I am compulsive about lint natterings, and probably
  83.              * know too much about the innards of LEX... */
  84.             yyin = yyin;
  85.             yytchar = yytchar;
  86.             yyoutput(yyinput());
  87.             yyunput(yyinput());
  88.             REJECT;
  89. #endif    /* lint */
  90.         }
  91.  
  92. \"[^"]*        {
  93.             /* Quoted string. */
  94.             int        c;
  95.  
  96.             /* See the Lex paper in Volume 2A or PS1:16
  97.              * for details on this code. */
  98.             if (yytext[yyleng - 1] == '\\')
  99.             yymore();
  100.             else {
  101.             if ((c = input()) == '"') {
  102.                 yylval.String = COPY(&yytext[1]);
  103.                 return ID;
  104.             }
  105.             unput(c);
  106.             yyerror("Bad string");
  107.             }
  108.         }
  109.  
  110. #.*        {
  111.             /* Comment. */
  112.         }
  113.  
  114.  
  115. .        {
  116.             yyerror("Bad character");
  117.         }
  118. %%
  119.  
  120.  
  121. /*
  122. **  We found an error while parsing the file, report it.
  123. */
  124. void
  125. yyerror(text)
  126.     char    *text;
  127. {
  128.     char    buff[SIZE];
  129.  
  130.     /* Truncate string to fit. */
  131.     if (strlen(yytext) > SIZE / 2)
  132.     (void)strcpy(&yytext[SIZE / 2], "...");
  133.     (void)sprintf(buff, "ERROR %s near line %d (\"%s\").",
  134.             text, yylineno, yytext);
  135.     Message(buff);
  136.     HaveErrors = TRUE;
  137. }
  138.  
  139.  
  140. /*
  141. **  Turn a string into all uppercase.
  142. */
  143. void
  144. Uppercase(p)
  145.     register char    *p;
  146. {
  147.     for ( ; *p; p++)
  148.     if (isascii(*p) && islower(*p))
  149.         *p = toupper(*p);
  150. }
  151.  
  152.  
  153.  
  154. /*
  155. **  Called by lex at end-of-stream.  Return one if no more input.
  156. */
  157. STATIC int
  158. yywrap()
  159. {
  160.     return 1;
  161. }
  162.  
  163.  
  164. /*
  165. **  Our input routine.
  166. */
  167. STATIC int
  168. input()
  169. {
  170.     int        c;
  171.  
  172.     switch (c = getc(F)) {
  173.     case EOF:
  174.     return 0;
  175.     case '\n':
  176.     yylineno++;
  177.     break;
  178.     }
  179.     return c;
  180. }
  181.  
  182.  
  183. /*
  184. **  Our pushback routine.  If you have an input(), you gotta have an unput().
  185. */
  186. STATIC int
  187. unput(c)
  188.     int        c;
  189. {
  190.     if (c == '\n')
  191.     yylineno--;
  192.     (void)ungetc(c, F);
  193. }
  194.  
  195.  
  196. /*
  197. **  Open file for LEX input.
  198. */
  199. int
  200. yyopen(Checking, name)
  201.     BOOL    Checking;
  202.     char    *name;
  203. {
  204.     /* Open file.  The '-' is only when checking. */
  205.     if (Checking && EQ(name, "-"))
  206.     F = stdin;
  207.     else if ((F = fopen(name, "r")) == NULL)
  208.     return FALSE;
  209.  
  210.     /* Reset our state. */
  211.     yylineno = 1;
  212.     HaveErrors = FALSE;
  213.  
  214.     /* This is black magic to reset LEX, you might need it, might not.
  215.      * Why isn't there a yyreset()?
  216.     yysptr = yysbuf;
  217.      */
  218.  
  219.     return TRUE;
  220. }
  221.  
  222. void
  223. yyclose()
  224. {
  225.     if (F) {
  226.     (void)fclose(F);
  227.     F = NULL;
  228.     }
  229. }
  230.